Branch data Line data Source code
1 : : /* linux/drivers/cdrom/cdrom.c
2 : : Copyright (c) 1996, 1997 David A. van Leeuwen.
3 : : Copyright (c) 1997, 1998 Erik Andersen <andersee@debian.org>
4 : : Copyright (c) 1998, 1999 Jens Axboe <axboe@image.dk>
5 : :
6 : : May be copied or modified under the terms of the GNU General Public
7 : : License. See linux/COPYING for more information.
8 : :
9 : : Uniform CD-ROM driver for Linux.
10 : : See Documentation/cdrom/cdrom-standard.rst 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 : :
32 : : 2.00 Dec 2, 1997 -- Erik Andersen <andersee@debian.org>
33 : : -- New maintainer! As David A. van Leeuwen has been too busy to actively
34 : : maintain and improve this driver, I am now carrying on the torch. If
35 : : you have a problem with this driver, please feel free to contact me.
36 : :
37 : : -- Added (rudimentary) sysctl interface. I realize this is really weak
38 : : right now, and is _very_ badly implemented. It will be improved...
39 : :
40 : : -- Modified CDROM_DISC_STATUS so that it is now incorporated into
41 : : the Uniform CD-ROM driver via the cdrom_count_tracks function.
42 : : The cdrom_count_tracks function helps resolve some of the false
43 : : assumptions of the CDROM_DISC_STATUS ioctl, and is also used to check
44 : : for the correct media type when mounting or playing audio from a CD.
45 : :
46 : : -- Remove the calls to verify_area and only use the copy_from_user and
47 : : copy_to_user stuff, since these calls now provide their own memory
48 : : checking with the 2.1.x kernels.
49 : :
50 : : -- Major update to return codes so that errors from low-level drivers
51 : : are passed on through (thanks to Gerd Knorr for pointing out this
52 : : problem).
53 : :
54 : : -- Made it so if a function isn't implemented in a low-level driver,
55 : : ENOSYS is now returned instead of EINVAL.
56 : :
57 : : -- Simplified some complex logic so that the source code is easier to read.
58 : :
59 : : -- Other stuff I probably forgot to mention (lots of changes).
60 : :
61 : : 2.01 to 2.11 Dec 1997-Jan 1998
62 : : -- TO-DO! Write changelogs for 2.01 to 2.12.
63 : :
64 : : 2.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 : :
70 : : 2.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 : :
85 : : 2.50 Oct 19, 1998 - Jens Axboe <axboe@image.dk>
86 : : -- New maintainers! Erik was too busy to continue the work on the driver,
87 : : so now Chris Zwilling <chris@cloudnet.com> and Jens Axboe <axboe@image.dk>
88 : : will do their best to follow in his footsteps
89 : :
90 : : 2.51 Dec 20, 1998 - Jens Axboe <axboe@image.dk>
91 : : -- Check if drive is capable of doing what we ask before blindly changing
92 : : cdi->options in various ioctl.
93 : : -- Added version to proc entry.
94 : :
95 : : 2.52 Jan 16, 1999 - Jens Axboe <axboe@image.dk>
96 : : -- Fixed an error in open_for_data where we would sometimes not return
97 : : the correct error value. Thanks Huba Gaspar <huba@softcell.hu>.
98 : : -- Fixed module usage count - usage was based on /proc/sys/dev
99 : : instead of /proc/sys/dev/cdrom. This could lead to an oops when other
100 : : modules had entries in dev. Feb 02 - real bug was in sysctl.c where
101 : : dev would be removed even though it was used. cdrom.c just illuminated
102 : : that bug.
103 : :
104 : : 2.53 Feb 22, 1999 - Jens Axboe <axboe@image.dk>
105 : : -- Fixup of several ioctl calls, in particular CDROM_SET_OPTIONS has
106 : : been "rewritten" because capabilities and options aren't in sync. They
107 : : should be...
108 : : -- Added CDROM_LOCKDOOR ioctl. Locks the door and keeps it that way.
109 : : -- Added CDROM_RESET ioctl.
110 : : -- Added CDROM_DEBUG ioctl. Enable debug messages on-the-fly.
111 : : -- Added CDROM_GET_CAPABILITY ioctl. This relieves userspace programs
112 : : from parsing /proc/sys/dev/cdrom/info.
113 : :
114 : : 2.54 Mar 15, 1999 - Jens Axboe <axboe@image.dk>
115 : : -- Check capability mask from low level driver when counting tracks as
116 : : per suggestion from Corey J. Scotts <cstotts@blue.weeg.uiowa.edu>.
117 : :
118 : : 2.55 Apr 25, 1999 - Jens Axboe <axboe@image.dk>
119 : : -- autoclose was mistakenly checked against CDC_OPEN_TRAY instead of
120 : : CDC_CLOSE_TRAY.
121 : : -- proc info didn't mask against capabilities mask.
122 : :
123 : : 3.00 Aug 5, 1999 - Jens Axboe <axboe@image.dk>
124 : : -- Unified audio ioctl handling across CD-ROM drivers. A lot of the
125 : : code was duplicated before. Drives that support the generic packet
126 : : interface are now being fed packets from here instead.
127 : : -- First attempt at adding support for MMC2 commands - for DVD and
128 : : CD-R(W) drives. Only the DVD parts are in now - the interface used is
129 : : the same as for the audio ioctls.
130 : : -- ioctl cleanups. if a drive couldn't play audio, it didn't get
131 : : a change to perform device specific ioctls as well.
132 : : -- Defined CDROM_CAN(CDC_XXX) for checking the capabilities.
133 : : -- Put in sysctl files for autoclose, autoeject, check_media, debug,
134 : : and lock.
135 : : -- /proc/sys/dev/cdrom/info has been updated to also contain info about
136 : : CD-Rx and DVD capabilities.
137 : : -- Now default to checking media type.
138 : : -- CDROM_SEND_PACKET ioctl added. The infrastructure was in place for
139 : : doing this anyway, with the generic_packet addition.
140 : :
141 : : 3.01 Aug 6, 1999 - Jens Axboe <axboe@image.dk>
142 : : -- Fix up the sysctl handling so that the option flags get set
143 : : correctly.
144 : : -- Fix up ioctl handling so the device specific ones actually get
145 : : called :).
146 : :
147 : : 3.02 Aug 8, 1999 - Jens Axboe <axboe@image.dk>
148 : : -- Fixed volume control on SCSI drives (or others with longer audio
149 : : page).
150 : : -- Fixed a couple of DVD minors. Thanks to Andrew T. Veliath
151 : : <andrewtv@usa.net> for telling me and for having defined the various
152 : : DVD structures and ioctls in the first place! He designed the original
153 : : DVD patches for ide-cd and while I rearranged and unified them, the
154 : : interface is still the same.
155 : :
156 : : 3.03 Sep 1, 1999 - Jens Axboe <axboe@image.dk>
157 : : -- Moved the rest of the audio ioctls from the CD-ROM drivers here. Only
158 : : CDROMREADTOCENTRY and CDROMREADTOCHDR are left.
159 : : -- Moved the CDROMREADxxx ioctls in here.
160 : : -- Defined the cdrom_get_last_written and cdrom_get_next_block as ioctls
161 : : and exported functions.
162 : : -- Erik Andersen <andersen@xmission.com> modified all SCMD_ commands
163 : : to now read GPCMD_ for the new generic packet interface. All low level
164 : : drivers are updated as well.
165 : : -- Various other cleanups.
166 : :
167 : : 3.04 Sep 12, 1999 - Jens Axboe <axboe@image.dk>
168 : : -- Fixed a couple of possible memory leaks (if an operation failed and
169 : : we didn't free the buffer before returning the error).
170 : : -- Integrated Uniform CD Changer handling from Richard Sharman
171 : : <rsharman@pobox.com>.
172 : : -- Defined CD_DVD and CD_CHANGER log levels.
173 : : -- Fixed the CDROMREADxxx ioctls.
174 : : -- CDROMPLAYTRKIND uses the GPCMD_PLAY_AUDIO_MSF command - too few
175 : : drives supported it. We lose the index part, however.
176 : : -- Small modifications to accommodate opens of /dev/hdc1, required
177 : : for ide-cd to handle multisession discs.
178 : : -- Export cdrom_mode_sense and cdrom_mode_select.
179 : : -- init_cdrom_command() for setting up a cgc command.
180 : :
181 : : 3.05 Oct 24, 1999 - Jens Axboe <axboe@image.dk>
182 : : -- Changed the interface for CDROM_SEND_PACKET. Before it was virtually
183 : : impossible to send the drive data in a sensible way.
184 : : -- Lowered stack usage in mmc_ioctl(), dvd_read_disckey(), and
185 : : dvd_read_manufact.
186 : : -- Added setup of write mode for packet writing.
187 : : -- Fixed CDDA ripping with cdda2wav - accept much larger requests of
188 : : number of frames and split the reads in blocks of 8.
189 : :
190 : : 3.06 Dec 13, 1999 - Jens Axboe <axboe@image.dk>
191 : : -- Added support for changing the region of DVD drives.
192 : : -- Added sense data to generic command.
193 : :
194 : : 3.07 Feb 2, 2000 - Jens Axboe <axboe@suse.de>
195 : : -- Do same "read header length" trick in cdrom_get_disc_info() as
196 : : we do in cdrom_get_track_info() -- some drive don't obey specs and
197 : : fail if they can't supply the full Mt Fuji size table.
198 : : -- Deleted stuff related to setting up write modes. It has a different
199 : : home now.
200 : : -- Clear header length in mode_select unconditionally.
201 : : -- Removed the register_disk() that was added, not needed here.
202 : :
203 : : 3.08 May 1, 2000 - Jens Axboe <axboe@suse.de>
204 : : -- Fix direction flag in setup_send_key and setup_report_key. This
205 : : gave some SCSI adapters problems.
206 : : -- Always return -EROFS for write opens
207 : : -- Convert to module_init/module_exit style init and remove some
208 : : of the #ifdef MODULE stuff
209 : : -- Fix several dvd errors - DVD_LU_SEND_ASF should pass agid,
210 : : DVD_HOST_SEND_RPC_STATE did not set buffer size in cdb, and
211 : : dvd_do_auth passed uninitialized data to drive because init_cdrom_command
212 : : did not clear a 0 sized buffer.
213 : :
214 : : 3.09 May 12, 2000 - Jens Axboe <axboe@suse.de>
215 : : -- Fix Video-CD on SCSI drives that don't support READ_CD command. In
216 : : that case switch block size and issue plain READ_10 again, then switch
217 : : back.
218 : :
219 : : 3.10 Jun 10, 2000 - Jens Axboe <axboe@suse.de>
220 : : -- Fix volume control on CD's - old SCSI-II drives now use their own
221 : : code, as doing MODE6 stuff in here is really not my intention.
222 : : -- Use READ_DISC_INFO for more reliable end-of-disc.
223 : :
224 : : 3.11 Jun 12, 2000 - Jens Axboe <axboe@suse.de>
225 : : -- Fix bug in getting rpc phase 2 region info.
226 : : -- Reinstate "correct" CDROMPLAYTRKIND
227 : :
228 : : 3.12 Oct 18, 2000 - Jens Axboe <axboe@suse.de>
229 : : -- Use quiet bit on packet commands not known to work
230 : :
231 : : 3.20 Dec 17, 2003 - Jens Axboe <axboe@suse.de>
232 : : -- Various fixes and lots of cleanups not listed :-)
233 : : -- Locking fixes
234 : : -- Mt Rainier support
235 : : -- DVD-RAM write open fixes
236 : :
237 : : Nov 5 2001, Aug 8 2002. Modified by Andy Polyakov
238 : : <appro@fy.chalmers.se> to support MMC-3 compliant DVD+RW units.
239 : :
240 : : Modified by Nigel Kukard <nkukard@lbsd.net> - support DVD+RW
241 : : 2.4.x patch by Andy Polyakov <appro@fy.chalmers.se>
242 : :
243 : : -------------------------------------------------------------------------*/
244 : :
245 : : #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
246 : :
247 : : #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 : :
268 : : #include <linux/atomic.h>
269 : : #include <linux/module.h>
270 : : #include <linux/fs.h>
271 : : #include <linux/major.h>
272 : : #include <linux/types.h>
273 : : #include <linux/errno.h>
274 : : #include <linux/kernel.h>
275 : : #include <linux/mm.h>
276 : : #include <linux/slab.h>
277 : : #include <linux/cdrom.h>
278 : : #include <linux/sysctl.h>
279 : : #include <linux/proc_fs.h>
280 : : #include <linux/blkpg.h>
281 : : #include <linux/init.h>
282 : : #include <linux/fcntl.h>
283 : : #include <linux/blkdev.h>
284 : : #include <linux/times.h>
285 : : #include <linux/uaccess.h>
286 : : #include <scsi/scsi_common.h>
287 : : #include <scsi/scsi_request.h>
288 : :
289 : : /* used to tell the module to turn on full debugging messages */
290 : : static bool debug;
291 : : /* default compatibility mode */
292 : : static bool autoclose=1;
293 : : static bool autoeject;
294 : : static bool lockdoor = 1;
295 : : /* will we ever get to use this... sigh. */
296 : : static bool check_media_type;
297 : : /* automatically restart mrw format */
298 : : static bool mrw_format_restart = 1;
299 : : module_param(debug, bool, 0);
300 : : module_param(autoclose, bool, 0);
301 : : module_param(autoeject, bool, 0);
302 : : module_param(lockdoor, bool, 0);
303 : : module_param(check_media_type, bool, 0);
304 : : module_param(mrw_format_restart, bool, 0);
305 : :
306 : : static DEFINE_MUTEX(cdrom_mutex);
307 : :
308 : : static const char *mrw_format_status[] = {
309 : : "not mrw",
310 : : "bgformat inactive",
311 : : "bgformat active",
312 : : "mrw complete",
313 : : };
314 : :
315 : : static const char *mrw_address_space[] = { "DMA", "GAA" };
316 : :
317 : : #if (ERRLOGMASK != CD_NOTHING)
318 : : #define cd_dbg(type, fmt, ...) \
319 : : do { \
320 : : if ((ERRLOGMASK & type) || debug == 1) \
321 : : pr_debug(fmt, ##__VA_ARGS__); \
322 : : } while (0)
323 : : #else
324 : : #define cd_dbg(type, fmt, ...) \
325 : : do { \
326 : : if (0 && (ERRLOGMASK & type) || debug == 1) \
327 : : pr_debug(fmt, ##__VA_ARGS__); \
328 : : } while (0)
329 : : #endif
330 : :
331 : : /* The (cdo->capability & ~cdi->mask & CDC_XXX) construct was used in
332 : : a lot of places. This macro makes the code more clear. */
333 : : #define CDROM_CAN(type) (cdi->ops->capability & ~cdi->mask & (type))
334 : :
335 : : /*
336 : : * Another popular OS uses 7 seconds as the hard timeout for default
337 : : * commands, so it is a good choice for us as well.
338 : : */
339 : : #define CDROM_DEF_TIMEOUT (7 * HZ)
340 : :
341 : : /* Not-exported routines. */
342 : :
343 : : static void cdrom_sysctl_register(void);
344 : :
345 : : static LIST_HEAD(cdrom_list);
346 : :
347 : 0 : int cdrom_dummy_generic_packet(struct cdrom_device_info *cdi,
348 : : struct packet_command *cgc)
349 : : {
350 [ # # ]: 0 : if (cgc->sshdr) {
351 : 0 : cgc->sshdr->sense_key = 0x05;
352 : 0 : cgc->sshdr->asc = 0x20;
353 : 0 : cgc->sshdr->ascq = 0x00;
354 : : }
355 : :
356 : 0 : cgc->stat = -EIO;
357 : 0 : return -EIO;
358 : : }
359 : : EXPORT_SYMBOL(cdrom_dummy_generic_packet);
360 : :
361 : 0 : static int cdrom_flush_cache(struct cdrom_device_info *cdi)
362 : : {
363 : 0 : struct packet_command cgc;
364 : :
365 : 0 : init_cdrom_command(&cgc, NULL, 0, CGC_DATA_NONE);
366 : 0 : cgc.cmd[0] = GPCMD_FLUSH_CACHE;
367 : :
368 : 0 : cgc.timeout = 5 * 60 * HZ;
369 : :
370 : 0 : return cdi->ops->generic_packet(cdi, &cgc);
371 : : }
372 : :
373 : : /* requires CD R/RW */
374 : 0 : static int cdrom_get_disc_info(struct cdrom_device_info *cdi,
375 : : disc_information *di)
376 : : {
377 : 0 : const struct cdrom_device_ops *cdo = cdi->ops;
378 : 0 : struct packet_command cgc;
379 : 0 : int ret, buflen;
380 : :
381 : : /* set up command and get the disc info */
382 : 0 : init_cdrom_command(&cgc, di, sizeof(*di), CGC_DATA_READ);
383 : 0 : cgc.cmd[0] = GPCMD_READ_DISC_INFO;
384 : 0 : cgc.cmd[8] = cgc.buflen = 2;
385 : 0 : cgc.quiet = 1;
386 : :
387 : 0 : ret = cdo->generic_packet(cdi, &cgc);
388 [ # # ]: 0 : if (ret)
389 : : return ret;
390 : :
391 : : /* not all drives have the same disc_info length, so requeue
392 : : * packet with the length the drive tells us it can supply
393 : : */
394 : 0 : buflen = be16_to_cpu(di->disc_information_length) +
395 : : sizeof(di->disc_information_length);
396 : :
397 : 0 : if (buflen > sizeof(disc_information))
398 : : buflen = sizeof(disc_information);
399 : :
400 : 0 : cgc.cmd[8] = cgc.buflen = buflen;
401 : 0 : ret = cdo->generic_packet(cdi, &cgc);
402 [ # # ]: 0 : if (ret)
403 : 0 : return ret;
404 : :
405 : : /* return actual fill size */
406 : : return buflen;
407 : : }
408 : :
409 : : /* This macro makes sure we don't have to check on cdrom_device_ops
410 : : * existence in the run-time routines below. Change_capability is a
411 : : * hack to have the capability flags defined const, while we can still
412 : : * change it here without gcc complaining at every line.
413 : : */
414 : : #define ENSURE(cdo, call, bits) \
415 : : do { \
416 : : if (cdo->call == NULL) \
417 : : WARN_ON_ONCE((cdo)->capability & (bits)); \
418 : : } while (0)
419 : :
420 : : /*
421 : : * the first prototypes used 0x2c as the page code for the mrw mode page,
422 : : * subsequently this was changed to 0x03. probe the one used by this drive
423 : : */
424 : 0 : static int cdrom_mrw_probe_pc(struct cdrom_device_info *cdi)
425 : : {
426 : 0 : struct packet_command cgc;
427 : 0 : char buffer[16];
428 : :
429 : 0 : init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ);
430 : :
431 : 0 : cgc.timeout = HZ;
432 : 0 : cgc.quiet = 1;
433 : :
434 [ # # ]: 0 : if (!cdrom_mode_sense(cdi, &cgc, MRW_MODE_PC, 0)) {
435 : 0 : cdi->mrw_mode_page = MRW_MODE_PC;
436 : 0 : return 0;
437 [ # # ]: 0 : } else if (!cdrom_mode_sense(cdi, &cgc, MRW_MODE_PC_PRE1, 0)) {
438 : 0 : cdi->mrw_mode_page = MRW_MODE_PC_PRE1;
439 : 0 : return 0;
440 : : }
441 : :
442 : : return 1;
443 : : }
444 : :
445 : 0 : static int cdrom_is_mrw(struct cdrom_device_info *cdi, int *write)
446 : : {
447 : 0 : struct packet_command cgc;
448 : 0 : struct mrw_feature_desc *mfd;
449 : 0 : unsigned char buffer[16];
450 : 0 : int ret;
451 : :
452 : 0 : *write = 0;
453 : :
454 : 0 : init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ);
455 : :
456 : 0 : cgc.cmd[0] = GPCMD_GET_CONFIGURATION;
457 : 0 : cgc.cmd[3] = CDF_MRW;
458 : 0 : cgc.cmd[8] = sizeof(buffer);
459 : 0 : cgc.quiet = 1;
460 : :
461 [ # # ]: 0 : if ((ret = cdi->ops->generic_packet(cdi, &cgc)))
462 : : return ret;
463 : :
464 : 0 : mfd = (struct mrw_feature_desc *)&buffer[sizeof(struct feature_header)];
465 [ # # ]: 0 : if (be16_to_cpu(mfd->feature_code) != CDF_MRW)
466 : : return 1;
467 : 0 : *write = mfd->write;
468 : :
469 [ # # ]: 0 : if ((ret = cdrom_mrw_probe_pc(cdi))) {
470 : 0 : *write = 0;
471 : 0 : return ret;
472 : : }
473 : :
474 : : return 0;
475 : : }
476 : :
477 : 0 : static int cdrom_mrw_bgformat(struct cdrom_device_info *cdi, int cont)
478 : : {
479 : 0 : struct packet_command cgc;
480 : 0 : unsigned char buffer[12];
481 : 0 : int ret;
482 : :
483 [ # # ]: 0 : pr_info("%sstarting format\n", cont ? "Re" : "");
484 : :
485 : : /*
486 : : * FmtData bit set (bit 4), format type is 1
487 : : */
488 : 0 : init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_WRITE);
489 : 0 : cgc.cmd[0] = GPCMD_FORMAT_UNIT;
490 : 0 : cgc.cmd[1] = (1 << 4) | 1;
491 : :
492 : 0 : cgc.timeout = 5 * 60 * HZ;
493 : :
494 : : /*
495 : : * 4 byte format list header, 8 byte format list descriptor
496 : : */
497 : 0 : buffer[1] = 1 << 1;
498 : 0 : buffer[3] = 8;
499 : :
500 : : /*
501 : : * nr_blocks field
502 : : */
503 : 0 : buffer[4] = 0xff;
504 : 0 : buffer[5] = 0xff;
505 : 0 : buffer[6] = 0xff;
506 : 0 : buffer[7] = 0xff;
507 : :
508 : 0 : buffer[8] = 0x24 << 2;
509 : 0 : buffer[11] = cont;
510 : :
511 : 0 : ret = cdi->ops->generic_packet(cdi, &cgc);
512 [ # # ]: 0 : if (ret)
513 : 0 : pr_info("bgformat failed\n");
514 : :
515 : 0 : return ret;
516 : : }
517 : :
518 : 0 : static int cdrom_mrw_bgformat_susp(struct cdrom_device_info *cdi, int immed)
519 : : {
520 : 0 : struct packet_command cgc;
521 : :
522 : 0 : init_cdrom_command(&cgc, NULL, 0, CGC_DATA_NONE);
523 : 0 : cgc.cmd[0] = GPCMD_CLOSE_TRACK;
524 : :
525 : : /*
526 : : * Session = 1, Track = 0
527 : : */
528 : 0 : cgc.cmd[1] = !!immed;
529 : 0 : cgc.cmd[2] = 1 << 1;
530 : :
531 : 0 : cgc.timeout = 5 * 60 * HZ;
532 : :
533 : 0 : return cdi->ops->generic_packet(cdi, &cgc);
534 : : }
535 : :
536 : 0 : static int cdrom_mrw_exit(struct cdrom_device_info *cdi)
537 : : {
538 : 0 : disc_information di;
539 : 0 : int ret;
540 : :
541 : 0 : ret = cdrom_get_disc_info(cdi, &di);
542 [ # # ]: 0 : if (ret < 0 || ret < (int)offsetof(typeof(di),disc_type))
543 : : return 1;
544 : :
545 : 0 : ret = 0;
546 [ # # ]: 0 : if (di.mrw_status == CDM_MRW_BGFORMAT_ACTIVE) {
547 : 0 : pr_info("issuing MRW background format suspend\n");
548 : 0 : ret = cdrom_mrw_bgformat_susp(cdi, 0);
549 : : }
550 : :
551 [ # # # # ]: 0 : if (!ret && cdi->media_written)
552 : 0 : ret = cdrom_flush_cache(cdi);
553 : :
554 : : return ret;
555 : : }
556 : :
557 : 0 : static int cdrom_mrw_set_lba_space(struct cdrom_device_info *cdi, int space)
558 : : {
559 : 0 : struct packet_command cgc;
560 : 0 : struct mode_page_header *mph;
561 : 0 : char buffer[16];
562 : 0 : int ret, offset, size;
563 : :
564 : 0 : init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ);
565 : :
566 : 0 : cgc.buffer = buffer;
567 : 0 : cgc.buflen = sizeof(buffer);
568 : :
569 : 0 : ret = cdrom_mode_sense(cdi, &cgc, cdi->mrw_mode_page, 0);
570 [ # # ]: 0 : if (ret)
571 : : return ret;
572 : :
573 : 0 : mph = (struct mode_page_header *)buffer;
574 : 0 : offset = be16_to_cpu(mph->desc_length);
575 : 0 : size = be16_to_cpu(mph->mode_data_length) + 2;
576 : :
577 : 0 : buffer[offset + 3] = space;
578 : 0 : cgc.buflen = size;
579 : :
580 : 0 : ret = cdrom_mode_select(cdi, &cgc);
581 [ # # ]: 0 : if (ret)
582 : : return ret;
583 : :
584 : 0 : pr_info("%s: mrw address space %s selected\n",
585 : : cdi->name, mrw_address_space[space]);
586 : 0 : return 0;
587 : : }
588 : :
589 : 13 : int register_cdrom(struct cdrom_device_info *cdi)
590 : : {
591 : 13 : static char banner_printed;
592 : 13 : const struct cdrom_device_ops *cdo = cdi->ops;
593 : :
594 : 13 : cd_dbg(CD_OPEN, "entering register_cdrom\n");
595 : :
596 [ + - + - ]: 13 : if (cdo->open == NULL || cdo->release == NULL)
597 : : return -EINVAL;
598 [ + - ]: 13 : if (!banner_printed) {
599 : 13 : pr_info("Uniform CD-ROM driver " REVISION "\n");
600 : 13 : banner_printed = 1;
601 : 13 : cdrom_sysctl_register();
602 : : }
603 : :
604 [ - + - - ]: 13 : ENSURE(cdo, drive_status, CDC_DRIVE_STATUS);
605 [ - + - - ]: 13 : if (cdo->check_events == NULL && cdo->media_changed == NULL)
606 [ # # ]: 0 : WARN_ON_ONCE(cdo->capability & (CDC_MEDIA_CHANGED | CDC_SELECT_DISC));
607 [ - + - - ]: 13 : ENSURE(cdo, tray_move, CDC_CLOSE_TRAY | CDC_OPEN_TRAY);
608 [ - + - - ]: 13 : ENSURE(cdo, lock_door, CDC_LOCK);
609 [ - + - - ]: 13 : ENSURE(cdo, select_speed, CDC_SELECT_SPEED);
610 [ - + - - ]: 13 : ENSURE(cdo, get_last_session, CDC_MULTI_SESSION);
611 [ - + - - ]: 13 : ENSURE(cdo, get_mcn, CDC_MCN);
612 [ - + - - ]: 13 : ENSURE(cdo, reset, CDC_RESET);
613 [ - + - - ]: 13 : ENSURE(cdo, generic_packet, CDC_GENERIC_PACKET);
614 : 13 : cdi->mc_flags = 0;
615 : 13 : cdi->options = CDO_USE_FFLAGS;
616 : :
617 [ + - + - ]: 13 : if (autoclose == 1 && CDROM_CAN(CDC_CLOSE_TRAY))
618 : 13 : cdi->options |= (int) CDO_AUTO_CLOSE;
619 [ - + - - ]: 13 : if (autoeject == 1 && CDROM_CAN(CDC_OPEN_TRAY))
620 : 0 : cdi->options |= (int) CDO_AUTO_EJECT;
621 [ + - ]: 13 : if (lockdoor == 1)
622 : 13 : cdi->options |= (int) CDO_LOCK;
623 [ - + ]: 13 : if (check_media_type == 1)
624 : 0 : cdi->options |= (int) CDO_CHECK_TYPE;
625 : :
626 [ + - ]: 13 : if (CDROM_CAN(CDC_MRW_W))
627 : 13 : cdi->exit = cdrom_mrw_exit;
628 : :
629 [ + - ]: 13 : if (cdi->disk)
630 : 13 : cdi->cdda_method = CDDA_BPC_FULL;
631 : : else
632 : 0 : cdi->cdda_method = CDDA_OLD;
633 : :
634 [ - + ]: 13 : WARN_ON(!cdo->generic_packet);
635 : :
636 : 13 : cd_dbg(CD_REG_UNREG, "drive \"/dev/%s\" registered\n", cdi->name);
637 : 13 : mutex_lock(&cdrom_mutex);
638 : 13 : list_add(&cdi->list, &cdrom_list);
639 : 13 : mutex_unlock(&cdrom_mutex);
640 : 13 : return 0;
641 : : }
642 : : #undef ENSURE
643 : :
644 : 0 : void unregister_cdrom(struct cdrom_device_info *cdi)
645 : : {
646 : 0 : cd_dbg(CD_OPEN, "entering unregister_cdrom\n");
647 : :
648 : 0 : mutex_lock(&cdrom_mutex);
649 : 0 : list_del(&cdi->list);
650 : 0 : mutex_unlock(&cdrom_mutex);
651 : :
652 [ # # ]: 0 : if (cdi->exit)
653 : 0 : cdi->exit(cdi);
654 : :
655 : 0 : cd_dbg(CD_REG_UNREG, "drive \"/dev/%s\" unregistered\n", cdi->name);
656 : 0 : }
657 : :
658 : 13 : int cdrom_get_media_event(struct cdrom_device_info *cdi,
659 : : struct media_event_desc *med)
660 : : {
661 : 13 : struct packet_command cgc;
662 : 13 : unsigned char buffer[8];
663 : 13 : struct event_header *eh = (struct event_header *)buffer;
664 : :
665 : 13 : init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ);
666 : 13 : cgc.cmd[0] = GPCMD_GET_EVENT_STATUS_NOTIFICATION;
667 : 13 : cgc.cmd[1] = 1; /* IMMED */
668 : 13 : cgc.cmd[4] = 1 << 4; /* media event */
669 : 13 : cgc.cmd[8] = sizeof(buffer);
670 : 13 : cgc.quiet = 1;
671 : :
672 [ + - ]: 13 : if (cdi->ops->generic_packet(cdi, &cgc))
673 : : return 1;
674 : :
675 [ + - ]: 13 : if (be16_to_cpu(eh->data_len) < sizeof(*med))
676 : : return 1;
677 : :
678 [ + - ]: 13 : if (eh->nea || eh->notification_class != 0x4)
679 : : return 1;
680 : :
681 : 13 : memcpy(med, &buffer[sizeof(*eh)], sizeof(*med));
682 : 13 : return 0;
683 : : }
684 : :
685 : 0 : static int cdrom_get_random_writable(struct cdrom_device_info *cdi,
686 : : struct rwrt_feature_desc *rfd)
687 : : {
688 : 0 : struct packet_command cgc;
689 : 0 : char buffer[24];
690 : 0 : int ret;
691 : :
692 : 0 : init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ);
693 : :
694 : 0 : cgc.cmd[0] = GPCMD_GET_CONFIGURATION; /* often 0x46 */
695 : 0 : cgc.cmd[3] = CDF_RWRT; /* often 0x0020 */
696 : 0 : cgc.cmd[8] = sizeof(buffer); /* often 0x18 */
697 : 0 : cgc.quiet = 1;
698 : :
699 [ # # ]: 0 : if ((ret = cdi->ops->generic_packet(cdi, &cgc)))
700 : : return ret;
701 : :
702 : 0 : memcpy(rfd, &buffer[sizeof(struct feature_header)], sizeof (*rfd));
703 : 0 : return 0;
704 : : }
705 : :
706 : 0 : static int cdrom_has_defect_mgt(struct cdrom_device_info *cdi)
707 : : {
708 : 0 : struct packet_command cgc;
709 : 0 : char buffer[16];
710 : 0 : __be16 *feature_code;
711 : 0 : int ret;
712 : :
713 : 0 : init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ);
714 : :
715 : 0 : cgc.cmd[0] = GPCMD_GET_CONFIGURATION;
716 : 0 : cgc.cmd[3] = CDF_HWDM;
717 : 0 : cgc.cmd[8] = sizeof(buffer);
718 : 0 : cgc.quiet = 1;
719 : :
720 [ # # ]: 0 : if ((ret = cdi->ops->generic_packet(cdi, &cgc)))
721 : : return ret;
722 : :
723 : 0 : feature_code = (__be16 *) &buffer[sizeof(struct feature_header)];
724 [ # # ]: 0 : if (be16_to_cpu(*feature_code) == CDF_HWDM)
725 : 0 : return 0;
726 : :
727 : : return 1;
728 : : }
729 : :
730 : :
731 : 0 : static int cdrom_is_random_writable(struct cdrom_device_info *cdi, int *write)
732 : : {
733 : 0 : struct rwrt_feature_desc rfd;
734 : 0 : int ret;
735 : :
736 : 0 : *write = 0;
737 : :
738 [ # # ]: 0 : if ((ret = cdrom_get_random_writable(cdi, &rfd)))
739 : : return ret;
740 : :
741 [ # # ]: 0 : if (CDF_RWRT == be16_to_cpu(rfd.feature_code))
742 : 0 : *write = 1;
743 : :
744 : : return 0;
745 : : }
746 : :
747 : 0 : static int cdrom_media_erasable(struct cdrom_device_info *cdi)
748 : : {
749 : 0 : disc_information di;
750 : 0 : int ret;
751 : :
752 : 0 : ret = cdrom_get_disc_info(cdi, &di);
753 [ # # ]: 0 : if (ret < 0 || ret < offsetof(typeof(di), n_first_track))
754 : : return -1;
755 : :
756 : 0 : return di.erasable;
757 : : }
758 : :
759 : : /*
760 : : * FIXME: check RO bit
761 : : */
762 : 0 : static int cdrom_dvdram_open_write(struct cdrom_device_info *cdi)
763 : : {
764 : 0 : int ret = cdrom_media_erasable(cdi);
765 : :
766 : : /*
767 : : * allow writable open if media info read worked and media is
768 : : * erasable, _or_ if it fails since not all drives support it
769 : : */
770 [ # # ]: 0 : if (!ret)
771 : 0 : return 1;
772 : :
773 : : return 0;
774 : : }
775 : :
776 : 0 : static int cdrom_mrw_open_write(struct cdrom_device_info *cdi)
777 : : {
778 : 0 : disc_information di;
779 : 0 : int ret;
780 : :
781 : : /*
782 : : * always reset to DMA lba space on open
783 : : */
784 [ # # ]: 0 : if (cdrom_mrw_set_lba_space(cdi, MRW_LBA_DMA)) {
785 : 0 : pr_err("failed setting lba address space\n");
786 : 0 : return 1;
787 : : }
788 : :
789 : 0 : ret = cdrom_get_disc_info(cdi, &di);
790 [ # # ]: 0 : if (ret < 0 || ret < offsetof(typeof(di),disc_type))
791 : : return 1;
792 : :
793 [ # # ]: 0 : if (!di.erasable)
794 : : return 1;
795 : :
796 : : /*
797 : : * mrw_status
798 : : * 0 - not MRW formatted
799 : : * 1 - MRW bgformat started, but not running or complete
800 : : * 2 - MRW bgformat in progress
801 : : * 3 - MRW formatting complete
802 : : */
803 : 0 : ret = 0;
804 : 0 : pr_info("open: mrw_status '%s'\n", mrw_format_status[di.mrw_status]);
805 [ # # ]: 0 : if (!di.mrw_status)
806 : : ret = 1;
807 [ # # # # ]: 0 : else if (di.mrw_status == CDM_MRW_BGFORMAT_INACTIVE &&
808 : : mrw_format_restart)
809 : 0 : ret = cdrom_mrw_bgformat(cdi, 1);
810 : :
811 : : return ret;
812 : : }
813 : :
814 : 0 : static int mo_open_write(struct cdrom_device_info *cdi)
815 : : {
816 : 0 : struct packet_command cgc;
817 : 0 : char buffer[255];
818 : 0 : int ret;
819 : :
820 : 0 : init_cdrom_command(&cgc, &buffer, 4, CGC_DATA_READ);
821 : 0 : cgc.quiet = 1;
822 : :
823 : : /*
824 : : * obtain write protect information as per
825 : : * drivers/scsi/sd.c:sd_read_write_protect_flag
826 : : */
827 : :
828 : 0 : ret = cdrom_mode_sense(cdi, &cgc, GPMODE_ALL_PAGES, 0);
829 [ # # ]: 0 : if (ret)
830 : 0 : ret = cdrom_mode_sense(cdi, &cgc, GPMODE_VENDOR_PAGE, 0);
831 [ # # ]: 0 : if (ret) {
832 : 0 : cgc.buflen = 255;
833 : 0 : ret = cdrom_mode_sense(cdi, &cgc, GPMODE_ALL_PAGES, 0);
834 : : }
835 : :
836 : : /* drive gave us no info, let the user go ahead */
837 [ # # ]: 0 : if (ret)
838 : : return 0;
839 : :
840 : 0 : return buffer[3] & 0x80;
841 : : }
842 : :
843 : 0 : static int cdrom_ram_open_write(struct cdrom_device_info *cdi)
844 : : {
845 : 0 : struct rwrt_feature_desc rfd;
846 : 0 : int ret;
847 : :
848 [ # # ]: 0 : if ((ret = cdrom_has_defect_mgt(cdi)))
849 : : return ret;
850 : :
851 [ # # ]: 0 : if ((ret = cdrom_get_random_writable(cdi, &rfd)))
852 : : return ret;
853 [ # # ]: 0 : else if (CDF_RWRT == be16_to_cpu(rfd.feature_code))
854 : 0 : ret = !rfd.curr;
855 : :
856 : 0 : cd_dbg(CD_OPEN, "can open for random write\n");
857 : : return ret;
858 : : }
859 : :
860 : 0 : static void cdrom_mmc3_profile(struct cdrom_device_info *cdi)
861 : : {
862 : 0 : struct packet_command cgc;
863 : 0 : char buffer[32];
864 : 0 : int ret, mmc3_profile;
865 : :
866 : 0 : init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ);
867 : :
868 : 0 : cgc.cmd[0] = GPCMD_GET_CONFIGURATION;
869 : 0 : cgc.cmd[1] = 0;
870 : 0 : cgc.cmd[2] = cgc.cmd[3] = 0; /* Starting Feature Number */
871 : 0 : cgc.cmd[8] = sizeof(buffer); /* Allocation Length */
872 : 0 : cgc.quiet = 1;
873 : :
874 [ # # ]: 0 : if ((ret = cdi->ops->generic_packet(cdi, &cgc)))
875 : : mmc3_profile = 0xffff;
876 : : else
877 : 0 : mmc3_profile = (buffer[6] << 8) | buffer[7];
878 : :
879 : 0 : cdi->mmc3_profile = mmc3_profile;
880 : 0 : }
881 : :
882 : 0 : static int cdrom_is_dvd_rw(struct cdrom_device_info *cdi)
883 : : {
884 : 0 : switch (cdi->mmc3_profile) {
885 : : case 0x12: /* DVD-RAM */
886 : : case 0x1A: /* DVD+RW */
887 : : case 0x43: /* BD-RE */
888 : : return 0;
889 : : default:
890 : 0 : return 1;
891 : : }
892 : : }
893 : :
894 : : /*
895 : : * returns 0 for ok to open write, non-0 to disallow
896 : : */
897 : 0 : static int cdrom_open_write(struct cdrom_device_info *cdi)
898 : : {
899 : 0 : int mrw, mrw_write, ram_write;
900 : 0 : int ret = 1;
901 : :
902 : 0 : mrw = 0;
903 [ # # ]: 0 : if (!cdrom_is_mrw(cdi, &mrw_write))
904 : 0 : mrw = 1;
905 : :
906 [ # # ]: 0 : if (CDROM_CAN(CDC_MO_DRIVE))
907 : 0 : ram_write = 1;
908 : : else
909 : 0 : (void) cdrom_is_random_writable(cdi, &ram_write);
910 : :
911 [ # # ]: 0 : if (mrw)
912 : 0 : cdi->mask &= ~CDC_MRW;
913 : : else
914 : 0 : cdi->mask |= CDC_MRW;
915 : :
916 [ # # ]: 0 : if (mrw_write)
917 : 0 : cdi->mask &= ~CDC_MRW_W;
918 : : else
919 : 0 : cdi->mask |= CDC_MRW_W;
920 : :
921 [ # # ]: 0 : if (ram_write)
922 : 0 : cdi->mask &= ~CDC_RAM;
923 : : else
924 : 0 : cdi->mask |= CDC_RAM;
925 : :
926 [ # # ]: 0 : if (CDROM_CAN(CDC_MRW_W))
927 : 0 : ret = cdrom_mrw_open_write(cdi);
928 [ # # ]: 0 : else if (CDROM_CAN(CDC_DVD_RAM))
929 : 0 : ret = cdrom_dvdram_open_write(cdi);
930 [ # # ]: 0 : else if (CDROM_CAN(CDC_RAM) &&
931 : : !CDROM_CAN(CDC_CD_R|CDC_CD_RW|CDC_DVD|CDC_DVD_R|CDC_MRW|CDC_MO_DRIVE))
932 : 0 : ret = cdrom_ram_open_write(cdi);
933 [ # # ]: 0 : else if (CDROM_CAN(CDC_MO_DRIVE))
934 : 0 : ret = mo_open_write(cdi);
935 [ # # ]: 0 : else if (!cdrom_is_dvd_rw(cdi))
936 : : ret = 0;
937 : :
938 : 0 : return ret;
939 : : }
940 : :
941 : 13 : static void cdrom_dvd_rw_close_write(struct cdrom_device_info *cdi)
942 : : {
943 : 13 : struct packet_command cgc;
944 : :
945 [ - + ]: 13 : if (cdi->mmc3_profile != 0x1a) {
946 : : cd_dbg(CD_CLOSE, "%s: No DVD+RW\n", cdi->name);
947 : 13 : return;
948 : : }
949 : :
950 [ # # ]: 0 : if (!cdi->media_written) {
951 : : cd_dbg(CD_CLOSE, "%s: DVD+RW media clean\n", cdi->name);
952 : : return;
953 : : }
954 : :
955 : 0 : pr_info("%s: dirty DVD+RW media, \"finalizing\"\n", cdi->name);
956 : :
957 : 0 : init_cdrom_command(&cgc, NULL, 0, CGC_DATA_NONE);
958 : 0 : cgc.cmd[0] = GPCMD_FLUSH_CACHE;
959 : 0 : cgc.timeout = 30*HZ;
960 : 0 : cdi->ops->generic_packet(cdi, &cgc);
961 : :
962 : 0 : init_cdrom_command(&cgc, NULL, 0, CGC_DATA_NONE);
963 : 0 : cgc.cmd[0] = GPCMD_CLOSE_TRACK;
964 : 0 : cgc.timeout = 3000*HZ;
965 : 0 : cgc.quiet = 1;
966 : 0 : cdi->ops->generic_packet(cdi, &cgc);
967 : :
968 : 0 : init_cdrom_command(&cgc, NULL, 0, CGC_DATA_NONE);
969 : 0 : cgc.cmd[0] = GPCMD_CLOSE_TRACK;
970 : 0 : cgc.cmd[2] = 2; /* Close session */
971 : 0 : cgc.quiet = 1;
972 : 0 : cgc.timeout = 3000*HZ;
973 : 0 : cdi->ops->generic_packet(cdi, &cgc);
974 : :
975 : 0 : cdi->media_written = 0;
976 : : }
977 : :
978 : : static int cdrom_close_write(struct cdrom_device_info *cdi)
979 : : {
980 : : #if 0
981 : : return cdrom_flush_cache(cdi);
982 : : #else
983 : : return 0;
984 : : #endif
985 : : }
986 : :
987 : : /* badly broken, I know. Is due for a fixup anytime. */
988 : 0 : static void cdrom_count_tracks(struct cdrom_device_info *cdi, tracktype *tracks)
989 : : {
990 : 0 : struct cdrom_tochdr header;
991 : 0 : struct cdrom_tocentry entry;
992 : 0 : int ret, i;
993 : 0 : tracks->data = 0;
994 : 0 : tracks->audio = 0;
995 : 0 : tracks->cdi = 0;
996 : 0 : tracks->xa = 0;
997 : 0 : tracks->error = 0;
998 : 0 : cd_dbg(CD_COUNT_TRACKS, "entering cdrom_count_tracks\n");
999 : :
1000 [ # # ]: 0 : if (!CDROM_CAN(CDC_PLAY_AUDIO)) {
1001 : : tracks->error = CDS_NO_INFO;
1002 : 0 : return;
1003 : : }
1004 : :
1005 : : /* Grab the TOC header so we can see how many tracks there are */
1006 : 0 : ret = cdi->ops->audio_ioctl(cdi, CDROMREADTOCHDR, &header);
1007 [ # # ]: 0 : if (ret) {
1008 [ # # ]: 0 : if (ret == -ENOMEDIUM)
1009 : 0 : tracks->error = CDS_NO_DISC;
1010 : : else
1011 : 0 : tracks->error = CDS_NO_INFO;
1012 : 0 : return;
1013 : : }
1014 : : /* check what type of tracks are on this disc */
1015 : 0 : entry.cdte_format = CDROM_MSF;
1016 [ # # ]: 0 : for (i = header.cdth_trk0; i <= header.cdth_trk1; i++) {
1017 : 0 : entry.cdte_track = i;
1018 [ # # ]: 0 : if (cdi->ops->audio_ioctl(cdi, CDROMREADTOCENTRY, &entry)) {
1019 : 0 : tracks->error = CDS_NO_INFO;
1020 : 0 : return;
1021 : : }
1022 [ # # ]: 0 : if (entry.cdte_ctrl & CDROM_DATA_TRACK) {
1023 [ # # ]: 0 : if (entry.cdte_format == 0x10)
1024 : 0 : tracks->cdi++;
1025 [ # # ]: 0 : else if (entry.cdte_format == 0x20)
1026 : 0 : tracks->xa++;
1027 : : else
1028 : 0 : tracks->data++;
1029 : : } else {
1030 : 0 : tracks->audio++;
1031 : : }
1032 : 0 : cd_dbg(CD_COUNT_TRACKS, "track %d: format=%d, ctrl=%d\n",
1033 : : i, entry.cdte_format, entry.cdte_ctrl);
1034 : : }
1035 : 0 : cd_dbg(CD_COUNT_TRACKS, "disc has %d tracks: %d=audio %d=data %d=Cd-I %d=XA\n",
1036 : : header.cdth_trk1, tracks->audio, tracks->data,
1037 : : tracks->cdi, tracks->xa);
1038 : : }
1039 : :
1040 : : static
1041 : 0 : int open_for_data(struct cdrom_device_info *cdi)
1042 : : {
1043 : 0 : int ret;
1044 : 0 : const struct cdrom_device_ops *cdo = cdi->ops;
1045 : 0 : tracktype tracks;
1046 : 0 : cd_dbg(CD_OPEN, "entering open_for_data\n");
1047 : : /* Check if the driver can report drive status. If it can, we
1048 : : can do clever things. If it can't, well, we at least tried! */
1049 [ # # ]: 0 : if (cdo->drive_status != NULL) {
1050 : 0 : ret = cdo->drive_status(cdi, CDSL_CURRENT);
1051 : 0 : cd_dbg(CD_OPEN, "drive_status=%d\n", ret);
1052 [ # # ]: 0 : if (ret == CDS_TRAY_OPEN) {
1053 : 0 : cd_dbg(CD_OPEN, "the tray is open...\n");
1054 : : /* can/may i close it? */
1055 [ # # ]: 0 : if (CDROM_CAN(CDC_CLOSE_TRAY) &&
1056 [ # # ]: 0 : cdi->options & CDO_AUTO_CLOSE) {
1057 : 0 : cd_dbg(CD_OPEN, "trying to close the tray\n");
1058 : 0 : ret=cdo->tray_move(cdi,0);
1059 [ # # ]: 0 : if (ret) {
1060 : 0 : cd_dbg(CD_OPEN, "bummer. tried to close the tray but failed.\n");
1061 : : /* Ignore the error from the low
1062 : : level driver. We don't care why it
1063 : : couldn't close the tray. We only care
1064 : : that there is no disc in the drive,
1065 : : since that is the _REAL_ problem here.*/
1066 : 0 : ret=-ENOMEDIUM;
1067 : 0 : goto clean_up_and_return;
1068 : : }
1069 : : } else {
1070 : 0 : cd_dbg(CD_OPEN, "bummer. this drive can't close the tray.\n");
1071 : 0 : ret=-ENOMEDIUM;
1072 : 0 : goto clean_up_and_return;
1073 : : }
1074 : : /* Ok, the door should be closed now.. Check again */
1075 : 0 : ret = cdo->drive_status(cdi, CDSL_CURRENT);
1076 [ # # ]: 0 : if ((ret == CDS_NO_DISC) || (ret==CDS_TRAY_OPEN)) {
1077 : 0 : cd_dbg(CD_OPEN, "bummer. the tray is still not closed.\n");
1078 : 0 : cd_dbg(CD_OPEN, "tray might not contain a medium\n");
1079 : 0 : ret=-ENOMEDIUM;
1080 : 0 : goto clean_up_and_return;
1081 : : }
1082 : 0 : cd_dbg(CD_OPEN, "the tray is now closed\n");
1083 : : }
1084 : : /* the door should be closed now, check for the disc */
1085 : 0 : ret = cdo->drive_status(cdi, CDSL_CURRENT);
1086 [ # # ]: 0 : if (ret!=CDS_DISC_OK) {
1087 : 0 : ret = -ENOMEDIUM;
1088 : 0 : goto clean_up_and_return;
1089 : : }
1090 : : }
1091 : 0 : cdrom_count_tracks(cdi, &tracks);
1092 [ # # ]: 0 : if (tracks.error == CDS_NO_DISC) {
1093 : 0 : cd_dbg(CD_OPEN, "bummer. no disc.\n");
1094 : 0 : ret=-ENOMEDIUM;
1095 : 0 : goto clean_up_and_return;
1096 : : }
1097 : : /* CD-Players which don't use O_NONBLOCK, workman
1098 : : * for example, need bit CDO_CHECK_TYPE cleared! */
1099 [ # # ]: 0 : if (tracks.data==0) {
1100 [ # # ]: 0 : if (cdi->options & CDO_CHECK_TYPE) {
1101 : : /* give people a warning shot, now that CDO_CHECK_TYPE
1102 : : is the default case! */
1103 : 0 : cd_dbg(CD_OPEN, "bummer. wrong media type.\n");
1104 : 0 : cd_dbg(CD_WARNING, "pid %d must open device O_NONBLOCK!\n",
1105 : : (unsigned int)task_pid_nr(current));
1106 : 0 : ret=-EMEDIUMTYPE;
1107 : 0 : goto clean_up_and_return;
1108 : : }
1109 : : else {
1110 : 0 : cd_dbg(CD_OPEN, "wrong media type, but CDO_CHECK_TYPE not set\n");
1111 : : }
1112 : : }
1113 : :
1114 : 0 : cd_dbg(CD_OPEN, "all seems well, opening the devicen");
1115 : :
1116 : : /* all seems well, we can open the device */
1117 : 0 : ret = cdo->open(cdi, 0); /* open for data */
1118 : 0 : cd_dbg(CD_OPEN, "opening the device gave me %d\n", ret);
1119 : : /* After all this careful checking, we shouldn't have problems
1120 : : opening the device, but we don't want the device locked if
1121 : : this somehow fails... */
1122 [ # # ]: 0 : if (ret) {
1123 : 0 : cd_dbg(CD_OPEN, "open device failed\n");
1124 : 0 : goto clean_up_and_return;
1125 : : }
1126 [ # # # # ]: 0 : if (CDROM_CAN(CDC_LOCK) && (cdi->options & CDO_LOCK)) {
1127 : 0 : cdo->lock_door(cdi, 1);
1128 : 0 : cd_dbg(CD_OPEN, "door locked\n");
1129 : : }
1130 : 0 : cd_dbg(CD_OPEN, "device opened successfully\n");
1131 : : return ret;
1132 : :
1133 : : /* Something failed. Try to unlock the drive, because some drivers
1134 : : (notably ide-cd) lock the drive after every command. This produced
1135 : : a nasty bug where after mount failed, the drive would remain locked!
1136 : : This ensures that the drive gets unlocked after a mount fails. This
1137 : : is a goto to avoid bloating the driver with redundant code. */
1138 : 0 : clean_up_and_return:
1139 : 0 : cd_dbg(CD_OPEN, "open failed\n");
1140 [ # # # # ]: 0 : if (CDROM_CAN(CDC_LOCK) && cdi->options & CDO_LOCK) {
1141 : 0 : cdo->lock_door(cdi, 0);
1142 : 0 : cd_dbg(CD_OPEN, "door unlocked\n");
1143 : : }
1144 : : return ret;
1145 : : }
1146 : :
1147 : : /* We use the open-option O_NONBLOCK to indicate that the
1148 : : * purpose of opening is only for subsequent ioctl() calls; no device
1149 : : * integrity checks are performed.
1150 : : *
1151 : : * We hope that all cd-player programs will adopt this convention. It
1152 : : * is in their own interest: device control becomes a lot easier
1153 : : * this way.
1154 : : */
1155 : 39 : int cdrom_open(struct cdrom_device_info *cdi, struct block_device *bdev,
1156 : : fmode_t mode)
1157 : : {
1158 : 39 : int ret;
1159 : :
1160 : 39 : cd_dbg(CD_OPEN, "entering cdrom_open\n");
1161 : :
1162 : : /* if this was a O_NONBLOCK open and we should honor the flags,
1163 : : * do a quick open without drive/disc integrity checks. */
1164 : 39 : cdi->use_count++;
1165 [ + - + - ]: 39 : if ((mode & FMODE_NDELAY) && (cdi->options & CDO_USE_FFLAGS)) {
1166 : 39 : ret = cdi->ops->open(cdi, 1);
1167 : : } else {
1168 : 0 : ret = open_for_data(cdi);
1169 [ # # ]: 0 : if (ret)
1170 : 0 : goto err;
1171 [ # # ]: 0 : if (CDROM_CAN(CDC_GENERIC_PACKET))
1172 : 0 : cdrom_mmc3_profile(cdi);
1173 [ # # ]: 0 : if (mode & FMODE_WRITE) {
1174 : 0 : ret = -EROFS;
1175 [ # # ]: 0 : if (cdrom_open_write(cdi))
1176 : 0 : goto err_release;
1177 [ # # ]: 0 : if (!CDROM_CAN(CDC_RAM))
1178 : 0 : goto err_release;
1179 : 0 : ret = 0;
1180 : 0 : cdi->media_written = 0;
1181 : : }
1182 : : }
1183 : :
1184 [ - + ]: 39 : if (ret)
1185 : 0 : goto err;
1186 : :
1187 : 39 : cd_dbg(CD_OPEN, "Use count for \"/dev/%s\" now %d\n",
1188 : : cdi->name, cdi->use_count);
1189 : : return 0;
1190 : 0 : err_release:
1191 [ # # # # ]: 0 : if (CDROM_CAN(CDC_LOCK) && cdi->options & CDO_LOCK) {
1192 : 0 : cdi->ops->lock_door(cdi, 0);
1193 : 0 : cd_dbg(CD_OPEN, "door unlocked\n");
1194 : : }
1195 : 0 : cdi->ops->release(cdi);
1196 : 0 : err:
1197 : 0 : cdi->use_count--;
1198 : 0 : return ret;
1199 : : }
1200 : :
1201 : : /* This code is similar to that in open_for_data. The routine is called
1202 : : whenever an audio play operation is requested.
1203 : : */
1204 : : static int check_for_audio_disc(struct cdrom_device_info *cdi,
1205 : : const struct cdrom_device_ops *cdo)
1206 : : {
1207 : : int ret;
1208 : : tracktype tracks;
1209 : : cd_dbg(CD_OPEN, "entering check_for_audio_disc\n");
1210 : : if (!(cdi->options & CDO_CHECK_TYPE))
1211 : : return 0;
1212 : : if (cdo->drive_status != NULL) {
1213 : : ret = cdo->drive_status(cdi, CDSL_CURRENT);
1214 : : cd_dbg(CD_OPEN, "drive_status=%d\n", ret);
1215 : : if (ret == CDS_TRAY_OPEN) {
1216 : : cd_dbg(CD_OPEN, "the tray is open...\n");
1217 : : /* can/may i close it? */
1218 : : if (CDROM_CAN(CDC_CLOSE_TRAY) &&
1219 : : cdi->options & CDO_AUTO_CLOSE) {
1220 : : cd_dbg(CD_OPEN, "trying to close the tray\n");
1221 : : ret=cdo->tray_move(cdi,0);
1222 : : if (ret) {
1223 : : cd_dbg(CD_OPEN, "bummer. tried to close tray but failed.\n");
1224 : : /* Ignore the error from the low
1225 : : level driver. We don't care why it
1226 : : couldn't close the tray. We only care
1227 : : that there is no disc in the drive,
1228 : : since that is the _REAL_ problem here.*/
1229 : : return -ENOMEDIUM;
1230 : : }
1231 : : } else {
1232 : : cd_dbg(CD_OPEN, "bummer. this driver can't close the tray.\n");
1233 : : return -ENOMEDIUM;
1234 : : }
1235 : : /* Ok, the door should be closed now.. Check again */
1236 : : ret = cdo->drive_status(cdi, CDSL_CURRENT);
1237 : : if ((ret == CDS_NO_DISC) || (ret==CDS_TRAY_OPEN)) {
1238 : : cd_dbg(CD_OPEN, "bummer. the tray is still not closed.\n");
1239 : : return -ENOMEDIUM;
1240 : : }
1241 : : if (ret!=CDS_DISC_OK) {
1242 : : cd_dbg(CD_OPEN, "bummer. disc isn't ready.\n");
1243 : : return -EIO;
1244 : : }
1245 : : cd_dbg(CD_OPEN, "the tray is now closed\n");
1246 : : }
1247 : : }
1248 : : cdrom_count_tracks(cdi, &tracks);
1249 : : if (tracks.error)
1250 : : return(tracks.error);
1251 : :
1252 : : if (tracks.audio==0)
1253 : : return -EMEDIUMTYPE;
1254 : :
1255 : : return 0;
1256 : : }
1257 : :
1258 : 39 : void cdrom_release(struct cdrom_device_info *cdi, fmode_t mode)
1259 : : {
1260 : 39 : const struct cdrom_device_ops *cdo = cdi->ops;
1261 : 39 : int opened_for_data;
1262 : :
1263 : 39 : cd_dbg(CD_CLOSE, "entering cdrom_release\n");
1264 : :
1265 [ + - ]: 39 : if (cdi->use_count > 0)
1266 : 39 : cdi->use_count--;
1267 : :
1268 [ + + ]: 39 : if (cdi->use_count == 0) {
1269 : 13 : cd_dbg(CD_CLOSE, "Use count for \"/dev/%s\" now zero\n",
1270 : : cdi->name);
1271 : 13 : cdrom_dvd_rw_close_write(cdi);
1272 : :
1273 [ + - + - ]: 13 : if ((cdo->capability & CDC_LOCK) && !cdi->keeplocked) {
1274 : 13 : cd_dbg(CD_CLOSE, "Unlocking door!\n");
1275 : 13 : cdo->lock_door(cdi, 0);
1276 : : }
1277 : : }
1278 : :
1279 [ + - ]: 39 : opened_for_data = !(cdi->options & CDO_USE_FFLAGS) ||
1280 [ + - ]: 39 : !(mode & FMODE_NDELAY);
1281 : :
1282 : : /*
1283 : : * flush cache on last write release
1284 : : */
1285 : 39 : if (CDROM_CAN(CDC_RAM) && !cdi->use_count && cdi->for_data)
1286 : : cdrom_close_write(cdi);
1287 : :
1288 : 39 : cdo->release(cdi);
1289 [ + + ]: 39 : if (cdi->use_count == 0) { /* last process that closes dev*/
1290 [ - + ]: 13 : if (opened_for_data &&
1291 [ # # # # ]: 0 : cdi->options & CDO_AUTO_EJECT && CDROM_CAN(CDC_OPEN_TRAY))
1292 : 0 : cdo->tray_move(cdi, 1);
1293 : : }
1294 : 39 : }
1295 : :
1296 : 0 : static int cdrom_read_mech_status(struct cdrom_device_info *cdi,
1297 : : struct cdrom_changer_info *buf)
1298 : : {
1299 : 0 : struct packet_command cgc;
1300 : 0 : const struct cdrom_device_ops *cdo = cdi->ops;
1301 : 0 : int length;
1302 : :
1303 : : /*
1304 : : * Sanyo changer isn't spec compliant (doesn't use regular change
1305 : : * LOAD_UNLOAD command, and it doesn't implement the mech status
1306 : : * command below
1307 : : */
1308 [ # # ]: 0 : if (cdi->sanyo_slot) {
1309 : 0 : buf->hdr.nslots = 3;
1310 [ # # ]: 0 : buf->hdr.curslot = cdi->sanyo_slot == 3 ? 0 : cdi->sanyo_slot;
1311 [ # # ]: 0 : for (length = 0; length < 3; length++) {
1312 : 0 : buf->slots[length].disc_present = 1;
1313 : 0 : buf->slots[length].change = 0;
1314 : : }
1315 : : return 0;
1316 : : }
1317 : :
1318 : 0 : length = sizeof(struct cdrom_mechstat_header) +
1319 : 0 : cdi->capacity * sizeof(struct cdrom_slot);
1320 : :
1321 : 0 : init_cdrom_command(&cgc, buf, length, CGC_DATA_READ);
1322 : 0 : cgc.cmd[0] = GPCMD_MECHANISM_STATUS;
1323 : 0 : cgc.cmd[8] = (length >> 8) & 0xff;
1324 : 0 : cgc.cmd[9] = length & 0xff;
1325 : 0 : return cdo->generic_packet(cdi, &cgc);
1326 : : }
1327 : :
1328 : 0 : static int cdrom_slot_status(struct cdrom_device_info *cdi, int slot)
1329 : : {
1330 : 0 : struct cdrom_changer_info *info;
1331 : 0 : int ret;
1332 : :
1333 : 0 : cd_dbg(CD_CHANGER, "entering cdrom_slot_status()\n");
1334 [ # # ]: 0 : if (cdi->sanyo_slot)
1335 : : return CDS_NO_INFO;
1336 : :
1337 : 0 : info = kmalloc(sizeof(*info), GFP_KERNEL);
1338 [ # # ]: 0 : if (!info)
1339 : : return -ENOMEM;
1340 : :
1341 [ # # ]: 0 : if ((ret = cdrom_read_mech_status(cdi, info)))
1342 : 0 : goto out_free;
1343 : :
1344 [ # # ]: 0 : if (info->slots[slot].disc_present)
1345 : : ret = CDS_DISC_OK;
1346 : : else
1347 : 0 : ret = CDS_NO_DISC;
1348 : :
1349 : 0 : out_free:
1350 : 0 : kfree(info);
1351 : 0 : return ret;
1352 : : }
1353 : :
1354 : : /* Return the number of slots for an ATAPI/SCSI cdrom,
1355 : : * return 1 if not a changer.
1356 : : */
1357 : 0 : int cdrom_number_of_slots(struct cdrom_device_info *cdi)
1358 : : {
1359 : 0 : int status;
1360 : 0 : int nslots = 1;
1361 : 0 : struct cdrom_changer_info *info;
1362 : :
1363 : 0 : cd_dbg(CD_CHANGER, "entering cdrom_number_of_slots()\n");
1364 : : /* cdrom_read_mech_status requires a valid value for capacity: */
1365 : 0 : cdi->capacity = 0;
1366 : :
1367 : 0 : info = kmalloc(sizeof(*info), GFP_KERNEL);
1368 [ # # ]: 0 : if (!info)
1369 : : return -ENOMEM;
1370 : :
1371 [ # # ]: 0 : if ((status = cdrom_read_mech_status(cdi, info)) == 0)
1372 : 0 : nslots = info->hdr.nslots;
1373 : :
1374 : 0 : kfree(info);
1375 : 0 : return nslots;
1376 : : }
1377 : :
1378 : :
1379 : : /* If SLOT < 0, unload the current slot. Otherwise, try to load SLOT. */
1380 : 0 : static int cdrom_load_unload(struct cdrom_device_info *cdi, int slot)
1381 : : {
1382 : 0 : struct packet_command cgc;
1383 : :
1384 : 0 : cd_dbg(CD_CHANGER, "entering cdrom_load_unload()\n");
1385 [ # # # # ]: 0 : if (cdi->sanyo_slot && slot < 0)
1386 : : return 0;
1387 : :
1388 : 0 : init_cdrom_command(&cgc, NULL, 0, CGC_DATA_NONE);
1389 : 0 : cgc.cmd[0] = GPCMD_LOAD_UNLOAD;
1390 : 0 : cgc.cmd[4] = 2 + (slot >= 0);
1391 : 0 : cgc.cmd[8] = slot;
1392 : 0 : cgc.timeout = 60 * HZ;
1393 : :
1394 : : /* The Sanyo 3 CD changer uses byte 7 of the
1395 : : GPCMD_TEST_UNIT_READY to command to switch CDs instead of
1396 : : using the GPCMD_LOAD_UNLOAD opcode. */
1397 [ # # # # ]: 0 : if (cdi->sanyo_slot && -1 < slot) {
1398 : 0 : cgc.cmd[0] = GPCMD_TEST_UNIT_READY;
1399 : 0 : cgc.cmd[7] = slot;
1400 : 0 : cgc.cmd[4] = cgc.cmd[8] = 0;
1401 [ # # ]: 0 : cdi->sanyo_slot = slot ? slot : 3;
1402 : : }
1403 : :
1404 : 0 : return cdi->ops->generic_packet(cdi, &cgc);
1405 : : }
1406 : :
1407 : 0 : static int cdrom_select_disc(struct cdrom_device_info *cdi, int slot)
1408 : : {
1409 : 0 : struct cdrom_changer_info *info;
1410 : 0 : int curslot;
1411 : 0 : int ret;
1412 : :
1413 : 0 : cd_dbg(CD_CHANGER, "entering cdrom_select_disc()\n");
1414 [ # # ]: 0 : if (!CDROM_CAN(CDC_SELECT_DISC))
1415 : : return -EDRIVE_CANT_DO_THIS;
1416 : :
1417 [ # # ]: 0 : if (cdi->ops->check_events)
1418 : 0 : cdi->ops->check_events(cdi, 0, slot);
1419 : : else
1420 : 0 : cdi->ops->media_changed(cdi, slot);
1421 : :
1422 [ # # ]: 0 : if (slot == CDSL_NONE) {
1423 : : /* set media changed bits, on both queues */
1424 : 0 : cdi->mc_flags = 0x3;
1425 : 0 : return cdrom_load_unload(cdi, -1);
1426 : : }
1427 : :
1428 : 0 : info = kmalloc(sizeof(*info), GFP_KERNEL);
1429 [ # # ]: 0 : if (!info)
1430 : : return -ENOMEM;
1431 : :
1432 [ # # ]: 0 : if ((ret = cdrom_read_mech_status(cdi, info))) {
1433 : 0 : kfree(info);
1434 : 0 : return ret;
1435 : : }
1436 : :
1437 : 0 : curslot = info->hdr.curslot;
1438 : 0 : kfree(info);
1439 : :
1440 [ # # # # ]: 0 : if (cdi->use_count > 1 || cdi->keeplocked) {
1441 [ # # ]: 0 : if (slot == CDSL_CURRENT) {
1442 : : return curslot;
1443 : : } else {
1444 : 0 : return -EBUSY;
1445 : : }
1446 : : }
1447 : :
1448 : : /* Specifying CDSL_CURRENT will attempt to load the currnet slot,
1449 : : which is useful if it had been previously unloaded.
1450 : : Whether it can or not, it returns the current slot.
1451 : : Similarly, if slot happens to be the current one, we still
1452 : : try and load it. */
1453 [ # # ]: 0 : if (slot == CDSL_CURRENT)
1454 : 0 : slot = curslot;
1455 : :
1456 : : /* set media changed bits on both queues */
1457 : 0 : cdi->mc_flags = 0x3;
1458 [ # # ]: 0 : if ((ret = cdrom_load_unload(cdi, slot)))
1459 : 0 : return ret;
1460 : :
1461 : : return slot;
1462 : : }
1463 : :
1464 : : /*
1465 : : * As cdrom implements an extra ioctl consumer for media changed
1466 : : * event, it needs to buffer ->check_events() output, such that event
1467 : : * is not lost for both the usual VFS and ioctl paths.
1468 : : * cdi->{vfs|ioctl}_events are used to buffer pending events for each
1469 : : * path.
1470 : : *
1471 : : * XXX: Locking is non-existent. cdi->ops->check_events() can be
1472 : : * called in parallel and buffering fields are accessed without any
1473 : : * exclusion. The original media_changed code had the same problem.
1474 : : * It might be better to simply deprecate CDROM_MEDIA_CHANGED ioctl
1475 : : * and remove this cruft altogether. It doesn't have much usefulness
1476 : : * at this point.
1477 : : */
1478 : 123 : static void cdrom_update_events(struct cdrom_device_info *cdi,
1479 : : unsigned int clearing)
1480 : : {
1481 : 123 : unsigned int events;
1482 : :
1483 : 123 : events = cdi->ops->check_events(cdi, clearing, CDSL_CURRENT);
1484 : 123 : cdi->vfs_events |= events;
1485 : 123 : cdi->ioctl_events |= events;
1486 : : }
1487 : :
1488 : 123 : unsigned int cdrom_check_events(struct cdrom_device_info *cdi,
1489 : : unsigned int clearing)
1490 : : {
1491 : 123 : unsigned int events;
1492 : :
1493 : 123 : cdrom_update_events(cdi, clearing);
1494 : 123 : events = cdi->vfs_events;
1495 : 123 : cdi->vfs_events = 0;
1496 : 123 : return events;
1497 : : }
1498 : : EXPORT_SYMBOL(cdrom_check_events);
1499 : :
1500 : : /* We want to make media_changed accessible to the user through an
1501 : : * ioctl. The main problem now is that we must double-buffer the
1502 : : * low-level implementation, to assure that the VFS and the user both
1503 : : * see a medium change once.
1504 : : */
1505 : :
1506 : : static
1507 : 0 : int media_changed(struct cdrom_device_info *cdi, int queue)
1508 : : {
1509 : 0 : unsigned int mask = (1 << (queue & 1));
1510 : 0 : int ret = !!(cdi->mc_flags & mask);
1511 : 0 : bool changed;
1512 : :
1513 [ # # ]: 0 : if (!CDROM_CAN(CDC_MEDIA_CHANGED))
1514 : : return ret;
1515 : :
1516 : : /* changed since last call? */
1517 [ # # ]: 0 : if (cdi->ops->check_events) {
1518 [ # # ]: 0 : BUG_ON(!queue); /* shouldn't be called from VFS path */
1519 : 0 : cdrom_update_events(cdi, DISK_EVENT_MEDIA_CHANGE);
1520 : 0 : changed = cdi->ioctl_events & DISK_EVENT_MEDIA_CHANGE;
1521 : 0 : cdi->ioctl_events = 0;
1522 : : } else
1523 : 0 : changed = cdi->ops->media_changed(cdi, CDSL_CURRENT);
1524 : :
1525 [ # # ]: 0 : if (changed) {
1526 : 0 : cdi->mc_flags = 0x3; /* set bit on both queues */
1527 : 0 : ret |= 1;
1528 : 0 : cdi->media_written = 0;
1529 : : }
1530 : :
1531 : 0 : cdi->mc_flags &= ~mask; /* clear bit */
1532 : 0 : return ret;
1533 : : }
1534 : :
1535 : 0 : int cdrom_media_changed(struct cdrom_device_info *cdi)
1536 : : {
1537 : : /* This talks to the VFS, which doesn't like errors - just 1 or 0.
1538 : : * Returning "0" is always safe (media hasn't been changed). Do that
1539 : : * if the low-level cdrom driver dosn't support media changed. */
1540 [ # # # # ]: 0 : if (cdi == NULL || cdi->ops->media_changed == NULL)
1541 : : return 0;
1542 [ # # ]: 0 : if (!CDROM_CAN(CDC_MEDIA_CHANGED))
1543 : : return 0;
1544 : 0 : return media_changed(cdi, 0);
1545 : : }
1546 : :
1547 : : /* Requests to the low-level drivers will /always/ be done in the
1548 : : following format convention:
1549 : :
1550 : : CDROM_LBA: all data-related requests.
1551 : : CDROM_MSF: all audio-related requests.
1552 : :
1553 : : However, a low-level implementation is allowed to refuse this
1554 : : request, and return information in its own favorite format.
1555 : :
1556 : : It doesn't make sense /at all/ to ask for a play_audio in LBA
1557 : : format, or ask for multi-session info in MSF format. However, for
1558 : : backward compatibility these format requests will be satisfied, but
1559 : : the requests to the low-level drivers will be sanitized in the more
1560 : : meaningful format indicated above.
1561 : : */
1562 : :
1563 : : static
1564 : 0 : void sanitize_format(union cdrom_addr *addr,
1565 : : u_char * curr, u_char requested)
1566 : : {
1567 [ # # ]: 0 : if (*curr == requested)
1568 : : return; /* nothing to be done! */
1569 [ # # ]: 0 : if (requested == CDROM_LBA) {
1570 : 0 : addr->lba = (int) addr->msf.frame +
1571 : 0 : 75 * (addr->msf.second - 2 + 60 * addr->msf.minute);
1572 : : } else { /* CDROM_MSF */
1573 : 0 : int lba = addr->lba;
1574 : 0 : addr->msf.frame = lba % 75;
1575 : 0 : lba /= 75;
1576 : 0 : lba += 2;
1577 : 0 : addr->msf.second = lba % 60;
1578 : 0 : addr->msf.minute = lba / 60;
1579 : : }
1580 : 0 : *curr = requested;
1581 : : }
1582 : :
1583 : 13 : void init_cdrom_command(struct packet_command *cgc, void *buf, int len,
1584 : : int type)
1585 : : {
1586 : 13 : memset(cgc, 0, sizeof(struct packet_command));
1587 [ + - ]: 13 : if (buf)
1588 : 13 : memset(buf, 0, len);
1589 : 13 : cgc->buffer = (char *) buf;
1590 : 13 : cgc->buflen = len;
1591 : 13 : cgc->data_direction = type;
1592 [ # # ]: 0 : cgc->timeout = CDROM_DEF_TIMEOUT;
1593 : 13 : }
1594 : :
1595 : : /* DVD handling */
1596 : :
1597 : : #define copy_key(dest,src) memcpy((dest), (src), sizeof(dvd_key))
1598 : : #define copy_chal(dest,src) memcpy((dest), (src), sizeof(dvd_challenge))
1599 : :
1600 : 0 : static void setup_report_key(struct packet_command *cgc, unsigned agid, unsigned type)
1601 : : {
1602 : 0 : cgc->cmd[0] = GPCMD_REPORT_KEY;
1603 : 0 : cgc->cmd[10] = type | (agid << 6);
1604 : 0 : switch (type) {
1605 : : case 0: case 8: case 5: {
1606 : 0 : cgc->buflen = 8;
1607 : 0 : break;
1608 : : }
1609 : : case 1: {
1610 : 0 : cgc->buflen = 16;
1611 : 0 : break;
1612 : : }
1613 : : case 2: case 4: {
1614 : 0 : cgc->buflen = 12;
1615 : 0 : break;
1616 : : }
1617 : : }
1618 : 0 : cgc->cmd[9] = cgc->buflen;
1619 : 0 : cgc->data_direction = CGC_DATA_READ;
1620 : : }
1621 : :
1622 : 0 : static void setup_send_key(struct packet_command *cgc, unsigned agid, unsigned type)
1623 : : {
1624 : 0 : cgc->cmd[0] = GPCMD_SEND_KEY;
1625 : 0 : cgc->cmd[10] = type | (agid << 6);
1626 : 0 : switch (type) {
1627 : : case 1: {
1628 : 0 : cgc->buflen = 16;
1629 : 0 : break;
1630 : : }
1631 : : case 3: {
1632 : 0 : cgc->buflen = 12;
1633 : 0 : break;
1634 : : }
1635 : : case 6: {
1636 : 0 : cgc->buflen = 8;
1637 : 0 : break;
1638 : : }
1639 : : }
1640 : 0 : cgc->cmd[9] = cgc->buflen;
1641 : 0 : cgc->data_direction = CGC_DATA_WRITE;
1642 : : }
1643 : :
1644 : 0 : static int dvd_do_auth(struct cdrom_device_info *cdi, dvd_authinfo *ai)
1645 : : {
1646 : 0 : int ret;
1647 : 0 : u_char buf[20];
1648 : 0 : struct packet_command cgc;
1649 : 0 : const struct cdrom_device_ops *cdo = cdi->ops;
1650 : 0 : rpc_state_t rpc_state;
1651 : :
1652 : 0 : memset(buf, 0, sizeof(buf));
1653 : 0 : init_cdrom_command(&cgc, buf, 0, CGC_DATA_READ);
1654 : :
1655 [ # # # # : 0 : switch (ai->type) {
# # # # #
# # ]
1656 : : /* LU data send */
1657 : 0 : case DVD_LU_SEND_AGID:
1658 : 0 : cd_dbg(CD_DVD, "entering DVD_LU_SEND_AGID\n");
1659 : 0 : cgc.quiet = 1;
1660 : 0 : setup_report_key(&cgc, ai->lsa.agid, 0);
1661 : :
1662 [ # # ]: 0 : if ((ret = cdo->generic_packet(cdi, &cgc)))
1663 : : return ret;
1664 : :
1665 : 0 : ai->lsa.agid = buf[7] >> 6;
1666 : : /* Returning data, let host change state */
1667 : 0 : break;
1668 : :
1669 : 0 : case DVD_LU_SEND_KEY1:
1670 : 0 : cd_dbg(CD_DVD, "entering DVD_LU_SEND_KEY1\n");
1671 : 0 : setup_report_key(&cgc, ai->lsk.agid, 2);
1672 : :
1673 [ # # ]: 0 : if ((ret = cdo->generic_packet(cdi, &cgc)))
1674 : : return ret;
1675 : :
1676 : 0 : copy_key(ai->lsk.key, &buf[4]);
1677 : : /* Returning data, let host change state */
1678 : 0 : break;
1679 : :
1680 : 0 : case DVD_LU_SEND_CHALLENGE:
1681 : 0 : cd_dbg(CD_DVD, "entering DVD_LU_SEND_CHALLENGE\n");
1682 : 0 : setup_report_key(&cgc, ai->lsc.agid, 1);
1683 : :
1684 [ # # ]: 0 : if ((ret = cdo->generic_packet(cdi, &cgc)))
1685 : : return ret;
1686 : :
1687 : 0 : copy_chal(ai->lsc.chal, &buf[4]);
1688 : : /* Returning data, let host change state */
1689 : 0 : break;
1690 : :
1691 : : /* Post-auth key */
1692 : 0 : case DVD_LU_SEND_TITLE_KEY:
1693 : 0 : cd_dbg(CD_DVD, "entering DVD_LU_SEND_TITLE_KEY\n");
1694 : 0 : cgc.quiet = 1;
1695 : 0 : setup_report_key(&cgc, ai->lstk.agid, 4);
1696 : 0 : cgc.cmd[5] = ai->lstk.lba;
1697 : 0 : cgc.cmd[4] = ai->lstk.lba >> 8;
1698 : 0 : cgc.cmd[3] = ai->lstk.lba >> 16;
1699 : 0 : cgc.cmd[2] = ai->lstk.lba >> 24;
1700 : :
1701 [ # # ]: 0 : if ((ret = cdo->generic_packet(cdi, &cgc)))
1702 : : return ret;
1703 : :
1704 : 0 : ai->lstk.cpm = (buf[4] >> 7) & 1;
1705 : 0 : ai->lstk.cp_sec = (buf[4] >> 6) & 1;
1706 : 0 : ai->lstk.cgms = (buf[4] >> 4) & 3;
1707 : 0 : copy_key(ai->lstk.title_key, &buf[5]);
1708 : : /* Returning data, let host change state */
1709 : 0 : break;
1710 : :
1711 : 0 : case DVD_LU_SEND_ASF:
1712 : 0 : cd_dbg(CD_DVD, "entering DVD_LU_SEND_ASF\n");
1713 : 0 : setup_report_key(&cgc, ai->lsasf.agid, 5);
1714 : :
1715 [ # # ]: 0 : if ((ret = cdo->generic_packet(cdi, &cgc)))
1716 : : return ret;
1717 : :
1718 : 0 : ai->lsasf.asf = buf[7] & 1;
1719 : 0 : break;
1720 : :
1721 : : /* LU data receive (LU changes state) */
1722 : 0 : case DVD_HOST_SEND_CHALLENGE:
1723 : 0 : cd_dbg(CD_DVD, "entering DVD_HOST_SEND_CHALLENGE\n");
1724 : 0 : setup_send_key(&cgc, ai->hsc.agid, 1);
1725 : 0 : buf[1] = 0xe;
1726 : 0 : copy_chal(&buf[4], ai->hsc.chal);
1727 : :
1728 [ # # ]: 0 : if ((ret = cdo->generic_packet(cdi, &cgc)))
1729 : : return ret;
1730 : :
1731 : 0 : ai->type = DVD_LU_SEND_KEY1;
1732 : 0 : break;
1733 : :
1734 : 0 : case DVD_HOST_SEND_KEY2:
1735 : 0 : cd_dbg(CD_DVD, "entering DVD_HOST_SEND_KEY2\n");
1736 : 0 : setup_send_key(&cgc, ai->hsk.agid, 3);
1737 : 0 : buf[1] = 0xa;
1738 : 0 : copy_key(&buf[4], ai->hsk.key);
1739 : :
1740 [ # # ]: 0 : if ((ret = cdo->generic_packet(cdi, &cgc))) {
1741 : 0 : ai->type = DVD_AUTH_FAILURE;
1742 : 0 : return ret;
1743 : : }
1744 : 0 : ai->type = DVD_AUTH_ESTABLISHED;
1745 : 0 : break;
1746 : :
1747 : : /* Misc */
1748 : 0 : case DVD_INVALIDATE_AGID:
1749 : 0 : cgc.quiet = 1;
1750 : 0 : cd_dbg(CD_DVD, "entering DVD_INVALIDATE_AGID\n");
1751 : 0 : setup_report_key(&cgc, ai->lsa.agid, 0x3f);
1752 [ # # ]: 0 : if ((ret = cdo->generic_packet(cdi, &cgc)))
1753 : 0 : return ret;
1754 : : break;
1755 : :
1756 : : /* Get region settings */
1757 : 0 : case DVD_LU_SEND_RPC_STATE:
1758 : 0 : cd_dbg(CD_DVD, "entering DVD_LU_SEND_RPC_STATE\n");
1759 : 0 : setup_report_key(&cgc, 0, 8);
1760 : 0 : memset(&rpc_state, 0, sizeof(rpc_state_t));
1761 : 0 : cgc.buffer = (char *) &rpc_state;
1762 : :
1763 [ # # ]: 0 : if ((ret = cdo->generic_packet(cdi, &cgc)))
1764 : : return ret;
1765 : :
1766 : 0 : ai->lrpcs.type = rpc_state.type_code;
1767 : 0 : ai->lrpcs.vra = rpc_state.vra;
1768 : 0 : ai->lrpcs.ucca = rpc_state.ucca;
1769 : 0 : ai->lrpcs.region_mask = rpc_state.region_mask;
1770 : 0 : ai->lrpcs.rpc_scheme = rpc_state.rpc_scheme;
1771 : 0 : break;
1772 : :
1773 : : /* Set region settings */
1774 : 0 : case DVD_HOST_SEND_RPC_STATE:
1775 : 0 : cd_dbg(CD_DVD, "entering DVD_HOST_SEND_RPC_STATE\n");
1776 : 0 : setup_send_key(&cgc, 0, 6);
1777 : 0 : buf[1] = 6;
1778 : 0 : buf[4] = ai->hrpcs.pdrc;
1779 : :
1780 [ # # ]: 0 : if ((ret = cdo->generic_packet(cdi, &cgc)))
1781 : 0 : return ret;
1782 : : break;
1783 : :
1784 : : default:
1785 : : cd_dbg(CD_WARNING, "Invalid DVD key ioctl (%d)\n", ai->type);
1786 : : return -ENOTTY;
1787 : : }
1788 : :
1789 : : return 0;
1790 : : }
1791 : :
1792 : 0 : static int dvd_read_physical(struct cdrom_device_info *cdi, dvd_struct *s,
1793 : : struct packet_command *cgc)
1794 : : {
1795 : 0 : unsigned char buf[21], *base;
1796 : 0 : struct dvd_layer *layer;
1797 : 0 : const struct cdrom_device_ops *cdo = cdi->ops;
1798 : 0 : int ret, layer_num = s->physical.layer_num;
1799 : :
1800 [ # # ]: 0 : if (layer_num >= DVD_LAYERS)
1801 : : return -EINVAL;
1802 : :
1803 : 0 : init_cdrom_command(cgc, buf, sizeof(buf), CGC_DATA_READ);
1804 : 0 : cgc->cmd[0] = GPCMD_READ_DVD_STRUCTURE;
1805 : 0 : cgc->cmd[6] = layer_num;
1806 : 0 : cgc->cmd[7] = s->type;
1807 : 0 : cgc->cmd[9] = cgc->buflen & 0xff;
1808 : :
1809 : : /*
1810 : : * refrain from reporting errors on non-existing layers (mainly)
1811 : : */
1812 : 0 : cgc->quiet = 1;
1813 : :
1814 : 0 : ret = cdo->generic_packet(cdi, cgc);
1815 [ # # ]: 0 : if (ret)
1816 : : return ret;
1817 : :
1818 : 0 : base = &buf[4];
1819 : 0 : layer = &s->physical.layer[layer_num];
1820 : :
1821 : : /*
1822 : : * place the data... really ugly, but at least we won't have to
1823 : : * worry about endianess in userspace.
1824 : : */
1825 : 0 : memset(layer, 0, sizeof(*layer));
1826 : 0 : layer->book_version = base[0] & 0xf;
1827 : 0 : layer->book_type = base[0] >> 4;
1828 : 0 : layer->min_rate = base[1] & 0xf;
1829 : 0 : layer->disc_size = base[1] >> 4;
1830 : 0 : layer->layer_type = base[2] & 0xf;
1831 : 0 : layer->track_path = (base[2] >> 4) & 1;
1832 : 0 : layer->nlayers = (base[2] >> 5) & 3;
1833 : 0 : layer->track_density = base[3] & 0xf;
1834 : 0 : layer->linear_density = base[3] >> 4;
1835 : 0 : layer->start_sector = base[5] << 16 | base[6] << 8 | base[7];
1836 : 0 : layer->end_sector = base[9] << 16 | base[10] << 8 | base[11];
1837 : 0 : layer->end_sector_l0 = base[13] << 16 | base[14] << 8 | base[15];
1838 : 0 : layer->bca = base[16] >> 7;
1839 : :
1840 : 0 : return 0;
1841 : : }
1842 : :
1843 : 0 : static int dvd_read_copyright(struct cdrom_device_info *cdi, dvd_struct *s,
1844 : : struct packet_command *cgc)
1845 : : {
1846 : 0 : int ret;
1847 : 0 : u_char buf[8];
1848 : 0 : const struct cdrom_device_ops *cdo = cdi->ops;
1849 : :
1850 : 0 : init_cdrom_command(cgc, buf, sizeof(buf), CGC_DATA_READ);
1851 : 0 : cgc->cmd[0] = GPCMD_READ_DVD_STRUCTURE;
1852 : 0 : cgc->cmd[6] = s->copyright.layer_num;
1853 : 0 : cgc->cmd[7] = s->type;
1854 : 0 : cgc->cmd[8] = cgc->buflen >> 8;
1855 : 0 : cgc->cmd[9] = cgc->buflen & 0xff;
1856 : :
1857 : 0 : ret = cdo->generic_packet(cdi, cgc);
1858 [ # # ]: 0 : if (ret)
1859 : : return ret;
1860 : :
1861 : 0 : s->copyright.cpst = buf[4];
1862 : 0 : s->copyright.rmi = buf[5];
1863 : :
1864 : 0 : return 0;
1865 : : }
1866 : :
1867 : 0 : static int dvd_read_disckey(struct cdrom_device_info *cdi, dvd_struct *s,
1868 : : struct packet_command *cgc)
1869 : : {
1870 : 0 : int ret, size;
1871 : 0 : u_char *buf;
1872 : 0 : const struct cdrom_device_ops *cdo = cdi->ops;
1873 : :
1874 : 0 : size = sizeof(s->disckey.value) + 4;
1875 : :
1876 : 0 : buf = kmalloc(size, GFP_KERNEL);
1877 [ # # ]: 0 : if (!buf)
1878 : : return -ENOMEM;
1879 : :
1880 : 0 : init_cdrom_command(cgc, buf, size, CGC_DATA_READ);
1881 : 0 : cgc->cmd[0] = GPCMD_READ_DVD_STRUCTURE;
1882 : 0 : cgc->cmd[7] = s->type;
1883 : 0 : cgc->cmd[8] = size >> 8;
1884 : 0 : cgc->cmd[9] = size & 0xff;
1885 : 0 : cgc->cmd[10] = s->disckey.agid << 6;
1886 : :
1887 : 0 : ret = cdo->generic_packet(cdi, cgc);
1888 [ # # ]: 0 : if (!ret)
1889 : 0 : memcpy(s->disckey.value, &buf[4], sizeof(s->disckey.value));
1890 : :
1891 : 0 : kfree(buf);
1892 : 0 : return ret;
1893 : : }
1894 : :
1895 : 0 : static int dvd_read_bca(struct cdrom_device_info *cdi, dvd_struct *s,
1896 : : struct packet_command *cgc)
1897 : : {
1898 : 0 : int ret, size = 4 + 188;
1899 : 0 : u_char *buf;
1900 : 0 : const struct cdrom_device_ops *cdo = cdi->ops;
1901 : :
1902 : 0 : buf = kmalloc(size, GFP_KERNEL);
1903 [ # # ]: 0 : if (!buf)
1904 : : return -ENOMEM;
1905 : :
1906 : 0 : init_cdrom_command(cgc, buf, size, CGC_DATA_READ);
1907 : 0 : cgc->cmd[0] = GPCMD_READ_DVD_STRUCTURE;
1908 : 0 : cgc->cmd[7] = s->type;
1909 : 0 : cgc->cmd[9] = cgc->buflen & 0xff;
1910 : :
1911 : 0 : ret = cdo->generic_packet(cdi, cgc);
1912 [ # # ]: 0 : if (ret)
1913 : 0 : goto out;
1914 : :
1915 : 0 : s->bca.len = buf[0] << 8 | buf[1];
1916 [ # # ]: 0 : if (s->bca.len < 12 || s->bca.len > 188) {
1917 : 0 : cd_dbg(CD_WARNING, "Received invalid BCA length (%d)\n",
1918 : : s->bca.len);
1919 : 0 : ret = -EIO;
1920 : 0 : goto out;
1921 : : }
1922 : 0 : memcpy(s->bca.value, &buf[4], s->bca.len);
1923 : 0 : ret = 0;
1924 : 0 : out:
1925 : 0 : kfree(buf);
1926 : 0 : return ret;
1927 : : }
1928 : :
1929 : 0 : static int dvd_read_manufact(struct cdrom_device_info *cdi, dvd_struct *s,
1930 : : struct packet_command *cgc)
1931 : : {
1932 : 0 : int ret = 0, size;
1933 : 0 : u_char *buf;
1934 : 0 : const struct cdrom_device_ops *cdo = cdi->ops;
1935 : :
1936 : 0 : size = sizeof(s->manufact.value) + 4;
1937 : :
1938 : 0 : buf = kmalloc(size, GFP_KERNEL);
1939 [ # # ]: 0 : if (!buf)
1940 : : return -ENOMEM;
1941 : :
1942 : 0 : init_cdrom_command(cgc, buf, size, CGC_DATA_READ);
1943 : 0 : cgc->cmd[0] = GPCMD_READ_DVD_STRUCTURE;
1944 : 0 : cgc->cmd[7] = s->type;
1945 : 0 : cgc->cmd[8] = size >> 8;
1946 : 0 : cgc->cmd[9] = size & 0xff;
1947 : :
1948 : 0 : ret = cdo->generic_packet(cdi, cgc);
1949 [ # # ]: 0 : if (ret)
1950 : 0 : goto out;
1951 : :
1952 : 0 : s->manufact.len = buf[0] << 8 | buf[1];
1953 : 0 : if (s->manufact.len < 0) {
1954 : : cd_dbg(CD_WARNING, "Received invalid manufacture info length (%d)\n",
1955 : : s->manufact.len);
1956 : : ret = -EIO;
1957 : : } else {
1958 [ # # ]: 0 : if (s->manufact.len > 2048) {
1959 : 0 : cd_dbg(CD_WARNING, "Received invalid manufacture info length (%d): truncating to 2048\n",
1960 : : s->manufact.len);
1961 : 0 : s->manufact.len = 2048;
1962 : : }
1963 : 0 : memcpy(s->manufact.value, &buf[4], s->manufact.len);
1964 : : }
1965 : :
1966 : 0 : out:
1967 : 0 : kfree(buf);
1968 : 0 : return ret;
1969 : : }
1970 : :
1971 : 0 : static int dvd_read_struct(struct cdrom_device_info *cdi, dvd_struct *s,
1972 : : struct packet_command *cgc)
1973 : : {
1974 [ # # # # : 0 : switch (s->type) {
# # ]
1975 : 0 : case DVD_STRUCT_PHYSICAL:
1976 : 0 : return dvd_read_physical(cdi, s, cgc);
1977 : :
1978 : 0 : case DVD_STRUCT_COPYRIGHT:
1979 : 0 : return dvd_read_copyright(cdi, s, cgc);
1980 : :
1981 : 0 : case DVD_STRUCT_DISCKEY:
1982 : 0 : return dvd_read_disckey(cdi, s, cgc);
1983 : :
1984 : 0 : case DVD_STRUCT_BCA:
1985 : 0 : return dvd_read_bca(cdi, s, cgc);
1986 : :
1987 : 0 : case DVD_STRUCT_MANUFACT:
1988 : 0 : return dvd_read_manufact(cdi, s, cgc);
1989 : :
1990 : : default:
1991 : : cd_dbg(CD_WARNING, ": Invalid DVD structure read requested (%d)\n",
1992 : : s->type);
1993 : : return -EINVAL;
1994 : : }
1995 : : }
1996 : :
1997 : 0 : int cdrom_mode_sense(struct cdrom_device_info *cdi,
1998 : : struct packet_command *cgc,
1999 : : int page_code, int page_control)
2000 : : {
2001 : 0 : const struct cdrom_device_ops *cdo = cdi->ops;
2002 : :
2003 : 0 : memset(cgc->cmd, 0, sizeof(cgc->cmd));
2004 : :
2005 : 0 : cgc->cmd[0] = GPCMD_MODE_SENSE_10;
2006 : 0 : cgc->cmd[2] = page_code | (page_control << 6);
2007 : 0 : cgc->cmd[7] = cgc->buflen >> 8;
2008 : 0 : cgc->cmd[8] = cgc->buflen & 0xff;
2009 : 0 : cgc->data_direction = CGC_DATA_READ;
2010 : 0 : return cdo->generic_packet(cdi, cgc);
2011 : : }
2012 : :
2013 : 0 : int cdrom_mode_select(struct cdrom_device_info *cdi,
2014 : : struct packet_command *cgc)
2015 : : {
2016 : 0 : const struct cdrom_device_ops *cdo = cdi->ops;
2017 : :
2018 : 0 : memset(cgc->cmd, 0, sizeof(cgc->cmd));
2019 : 0 : memset(cgc->buffer, 0, 2);
2020 : 0 : cgc->cmd[0] = GPCMD_MODE_SELECT_10;
2021 : 0 : cgc->cmd[1] = 0x10; /* PF */
2022 : 0 : cgc->cmd[7] = cgc->buflen >> 8;
2023 : 0 : cgc->cmd[8] = cgc->buflen & 0xff;
2024 : 0 : cgc->data_direction = CGC_DATA_WRITE;
2025 : 0 : return cdo->generic_packet(cdi, cgc);
2026 : : }
2027 : :
2028 : 0 : static int cdrom_read_subchannel(struct cdrom_device_info *cdi,
2029 : : struct cdrom_subchnl *subchnl, int mcn)
2030 : : {
2031 : 0 : const struct cdrom_device_ops *cdo = cdi->ops;
2032 : 0 : struct packet_command cgc;
2033 : 0 : char buffer[32];
2034 : 0 : int ret;
2035 : :
2036 : 0 : init_cdrom_command(&cgc, buffer, 16, CGC_DATA_READ);
2037 : 0 : cgc.cmd[0] = GPCMD_READ_SUBCHANNEL;
2038 : 0 : cgc.cmd[1] = subchnl->cdsc_format;/* MSF or LBA addressing */
2039 : 0 : cgc.cmd[2] = 0x40; /* request subQ data */
2040 [ # # ]: 0 : cgc.cmd[3] = mcn ? 2 : 1;
2041 : 0 : cgc.cmd[8] = 16;
2042 : :
2043 [ # # ]: 0 : if ((ret = cdo->generic_packet(cdi, &cgc)))
2044 : : return ret;
2045 : :
2046 : 0 : subchnl->cdsc_audiostatus = cgc.buffer[1];
2047 : 0 : subchnl->cdsc_ctrl = cgc.buffer[5] & 0xf;
2048 : 0 : subchnl->cdsc_trk = cgc.buffer[6];
2049 : 0 : subchnl->cdsc_ind = cgc.buffer[7];
2050 : :
2051 [ # # ]: 0 : if (subchnl->cdsc_format == CDROM_LBA) {
2052 : 0 : subchnl->cdsc_absaddr.lba = ((cgc.buffer[8] << 24) |
2053 : 0 : (cgc.buffer[9] << 16) |
2054 : 0 : (cgc.buffer[10] << 8) |
2055 : 0 : (cgc.buffer[11]));
2056 : 0 : subchnl->cdsc_reladdr.lba = ((cgc.buffer[12] << 24) |
2057 : 0 : (cgc.buffer[13] << 16) |
2058 : 0 : (cgc.buffer[14] << 8) |
2059 : 0 : (cgc.buffer[15]));
2060 : : } else {
2061 : 0 : subchnl->cdsc_reladdr.msf.minute = cgc.buffer[13];
2062 : 0 : subchnl->cdsc_reladdr.msf.second = cgc.buffer[14];
2063 : 0 : subchnl->cdsc_reladdr.msf.frame = cgc.buffer[15];
2064 : 0 : subchnl->cdsc_absaddr.msf.minute = cgc.buffer[9];
2065 : 0 : subchnl->cdsc_absaddr.msf.second = cgc.buffer[10];
2066 : 0 : subchnl->cdsc_absaddr.msf.frame = cgc.buffer[11];
2067 : : }
2068 : :
2069 : : return 0;
2070 : : }
2071 : :
2072 : : /*
2073 : : * Specific READ_10 interface
2074 : : */
2075 : 0 : static int cdrom_read_cd(struct cdrom_device_info *cdi,
2076 : : struct packet_command *cgc, int lba,
2077 : : int blocksize, int nblocks)
2078 : : {
2079 : 0 : const struct cdrom_device_ops *cdo = cdi->ops;
2080 : :
2081 : 0 : memset(&cgc->cmd, 0, sizeof(cgc->cmd));
2082 : 0 : cgc->cmd[0] = GPCMD_READ_10;
2083 : 0 : cgc->cmd[2] = (lba >> 24) & 0xff;
2084 : 0 : cgc->cmd[3] = (lba >> 16) & 0xff;
2085 : 0 : cgc->cmd[4] = (lba >> 8) & 0xff;
2086 : 0 : cgc->cmd[5] = lba & 0xff;
2087 : 0 : cgc->cmd[6] = (nblocks >> 16) & 0xff;
2088 : 0 : cgc->cmd[7] = (nblocks >> 8) & 0xff;
2089 : 0 : cgc->cmd[8] = nblocks & 0xff;
2090 : 0 : cgc->buflen = blocksize * nblocks;
2091 : 0 : return cdo->generic_packet(cdi, cgc);
2092 : : }
2093 : :
2094 : : /* very generic interface for reading the various types of blocks */
2095 : 0 : static int cdrom_read_block(struct cdrom_device_info *cdi,
2096 : : struct packet_command *cgc,
2097 : : int lba, int nblocks, int format, int blksize)
2098 : : {
2099 : 0 : const struct cdrom_device_ops *cdo = cdi->ops;
2100 : :
2101 : 0 : memset(&cgc->cmd, 0, sizeof(cgc->cmd));
2102 : 0 : cgc->cmd[0] = GPCMD_READ_CD;
2103 : : /* expected sector size - cdda,mode1,etc. */
2104 : 0 : cgc->cmd[1] = format << 2;
2105 : : /* starting address */
2106 : 0 : cgc->cmd[2] = (lba >> 24) & 0xff;
2107 : 0 : cgc->cmd[3] = (lba >> 16) & 0xff;
2108 : 0 : cgc->cmd[4] = (lba >> 8) & 0xff;
2109 : 0 : cgc->cmd[5] = lba & 0xff;
2110 : : /* number of blocks */
2111 : 0 : cgc->cmd[6] = (nblocks >> 16) & 0xff;
2112 : 0 : cgc->cmd[7] = (nblocks >> 8) & 0xff;
2113 : 0 : cgc->cmd[8] = nblocks & 0xff;
2114 : 0 : cgc->buflen = blksize * nblocks;
2115 : :
2116 : : /* set the header info returned */
2117 [ # # # # ]: 0 : switch (blksize) {
2118 : 0 : case CD_FRAMESIZE_RAW0 : cgc->cmd[9] = 0x58; break;
2119 : 0 : case CD_FRAMESIZE_RAW1 : cgc->cmd[9] = 0x78; break;
2120 : 0 : case CD_FRAMESIZE_RAW : cgc->cmd[9] = 0xf8; break;
2121 : 0 : default : cgc->cmd[9] = 0x10;
2122 : : }
2123 : :
2124 : 0 : return cdo->generic_packet(cdi, cgc);
2125 : : }
2126 : :
2127 : 0 : static int cdrom_read_cdda_old(struct cdrom_device_info *cdi, __u8 __user *ubuf,
2128 : : int lba, int nframes)
2129 : : {
2130 : 0 : struct packet_command cgc;
2131 : 0 : int ret = 0;
2132 : 0 : int nr;
2133 : :
2134 : 0 : cdi->last_sense = 0;
2135 : :
2136 : 0 : memset(&cgc, 0, sizeof(cgc));
2137 : :
2138 : : /*
2139 : : * start with will ra.nframes size, back down if alloc fails
2140 : : */
2141 : 0 : nr = nframes;
2142 : 0 : do {
2143 : 0 : cgc.buffer = kmalloc_array(nr, CD_FRAMESIZE_RAW, GFP_KERNEL);
2144 [ # # ]: 0 : if (cgc.buffer)
2145 : : break;
2146 : :
2147 : 0 : nr >>= 1;
2148 [ # # ]: 0 : } while (nr);
2149 : :
2150 [ # # ]: 0 : if (!nr)
2151 : : return -ENOMEM;
2152 : :
2153 : 0 : cgc.data_direction = CGC_DATA_READ;
2154 [ # # ]: 0 : while (nframes > 0) {
2155 : 0 : if (nr > nframes)
2156 : : nr = nframes;
2157 : :
2158 : 0 : ret = cdrom_read_block(cdi, &cgc, lba, nr, 1, CD_FRAMESIZE_RAW);
2159 [ # # ]: 0 : if (ret)
2160 : : break;
2161 [ # # # # ]: 0 : if (copy_to_user(ubuf, cgc.buffer, CD_FRAMESIZE_RAW * nr)) {
2162 : : ret = -EFAULT;
2163 : : break;
2164 : : }
2165 : 0 : ubuf += CD_FRAMESIZE_RAW * nr;
2166 : 0 : nframes -= nr;
2167 : 0 : lba += nr;
2168 : : }
2169 : 0 : kfree(cgc.buffer);
2170 : 0 : return ret;
2171 : : }
2172 : :
2173 : 0 : static int cdrom_read_cdda_bpc(struct cdrom_device_info *cdi, __u8 __user *ubuf,
2174 : : int lba, int nframes)
2175 : : {
2176 : 0 : struct request_queue *q = cdi->disk->queue;
2177 : 0 : struct request *rq;
2178 : 0 : struct scsi_request *req;
2179 : 0 : struct bio *bio;
2180 : 0 : unsigned int len;
2181 : 0 : int nr, ret = 0;
2182 : :
2183 [ # # ]: 0 : if (!q)
2184 : : return -ENXIO;
2185 : :
2186 [ # # ]: 0 : if (!blk_queue_scsi_passthrough(q)) {
2187 [ # # ]: 0 : WARN_ONCE(true,
2188 : : "Attempt read CDDA info through a non-SCSI queue\n");
2189 : 0 : return -EINVAL;
2190 : : }
2191 : :
2192 : 0 : cdi->last_sense = 0;
2193 : :
2194 [ # # ]: 0 : while (nframes) {
2195 : 0 : nr = nframes;
2196 [ # # ]: 0 : if (cdi->cdda_method == CDDA_BPC_SINGLE)
2197 : 0 : nr = 1;
2198 [ # # ]: 0 : if (nr * CD_FRAMESIZE_RAW > (queue_max_sectors(q) << 9))
2199 : 0 : nr = (queue_max_sectors(q) << 9) / CD_FRAMESIZE_RAW;
2200 : :
2201 : 0 : len = nr * CD_FRAMESIZE_RAW;
2202 : :
2203 : 0 : rq = blk_get_request(q, REQ_OP_SCSI_IN, 0);
2204 [ # # ]: 0 : if (IS_ERR(rq)) {
2205 : 0 : ret = PTR_ERR(rq);
2206 : 0 : break;
2207 : : }
2208 : 0 : req = scsi_req(rq);
2209 : :
2210 : 0 : ret = blk_rq_map_user(q, rq, NULL, ubuf, len, GFP_KERNEL);
2211 [ # # ]: 0 : if (ret) {
2212 : 0 : blk_put_request(rq);
2213 : 0 : break;
2214 : : }
2215 : :
2216 : 0 : req->cmd[0] = GPCMD_READ_CD;
2217 : 0 : req->cmd[1] = 1 << 2;
2218 : 0 : req->cmd[2] = (lba >> 24) & 0xff;
2219 : 0 : req->cmd[3] = (lba >> 16) & 0xff;
2220 : 0 : req->cmd[4] = (lba >> 8) & 0xff;
2221 : 0 : req->cmd[5] = lba & 0xff;
2222 : 0 : req->cmd[6] = (nr >> 16) & 0xff;
2223 : 0 : req->cmd[7] = (nr >> 8) & 0xff;
2224 : 0 : req->cmd[8] = nr & 0xff;
2225 : 0 : req->cmd[9] = 0xf8;
2226 : :
2227 : 0 : req->cmd_len = 12;
2228 : 0 : rq->timeout = 60 * HZ;
2229 : 0 : bio = rq->bio;
2230 : :
2231 : 0 : blk_execute_rq(q, cdi->disk, rq, 0);
2232 [ # # ]: 0 : if (scsi_req(rq)->result) {
2233 : 0 : struct scsi_sense_hdr sshdr;
2234 : :
2235 : 0 : ret = -EIO;
2236 : 0 : scsi_normalize_sense(req->sense, req->sense_len,
2237 : : &sshdr);
2238 : 0 : cdi->last_sense = sshdr.sense_key;
2239 : : }
2240 : :
2241 [ # # ]: 0 : if (blk_rq_unmap_user(bio))
2242 : 0 : ret = -EFAULT;
2243 : 0 : blk_put_request(rq);
2244 : :
2245 [ # # ]: 0 : if (ret)
2246 : : break;
2247 : :
2248 : 0 : nframes -= nr;
2249 : 0 : lba += nr;
2250 : 0 : ubuf += len;
2251 : : }
2252 : :
2253 : : return ret;
2254 : : }
2255 : :
2256 : 0 : static int cdrom_read_cdda(struct cdrom_device_info *cdi, __u8 __user *ubuf,
2257 : : int lba, int nframes)
2258 : : {
2259 : 0 : int ret;
2260 : :
2261 [ # # ]: 0 : if (cdi->cdda_method == CDDA_OLD)
2262 : 0 : return cdrom_read_cdda_old(cdi, ubuf, lba, nframes);
2263 : :
2264 : 0 : retry:
2265 : : /*
2266 : : * for anything else than success and io error, we need to retry
2267 : : */
2268 : 0 : ret = cdrom_read_cdda_bpc(cdi, ubuf, lba, nframes);
2269 [ # # ]: 0 : if (!ret || ret != -EIO)
2270 : 0 : return ret;
2271 : :
2272 : : /*
2273 : : * I've seen drives get sense 4/8/3 udma crc errors on multi
2274 : : * frame dma, so drop to single frame dma if we need to
2275 : : */
2276 [ # # # # ]: 0 : if (cdi->cdda_method == CDDA_BPC_FULL && nframes > 1) {
2277 : 0 : pr_info("dropping to single frame dma\n");
2278 : 0 : cdi->cdda_method = CDDA_BPC_SINGLE;
2279 : 0 : goto retry;
2280 : : }
2281 : :
2282 : : /*
2283 : : * so we have an io error of some sort with multi frame dma. if the
2284 : : * condition wasn't a hardware error
2285 : : * problems, not for any error
2286 : : */
2287 [ # # ]: 0 : if (cdi->last_sense != 0x04 && cdi->last_sense != 0x0b)
2288 : : return ret;
2289 : :
2290 : 0 : pr_info("dropping to old style cdda (sense=%x)\n", cdi->last_sense);
2291 : 0 : cdi->cdda_method = CDDA_OLD;
2292 : 0 : return cdrom_read_cdda_old(cdi, ubuf, lba, nframes);
2293 : : }
2294 : :
2295 : 0 : static int cdrom_ioctl_multisession(struct cdrom_device_info *cdi,
2296 : : void __user *argp)
2297 : : {
2298 : 0 : struct cdrom_multisession ms_info;
2299 : 0 : u8 requested_format;
2300 : 0 : int ret;
2301 : :
2302 : 0 : cd_dbg(CD_DO_IOCTL, "entering CDROMMULTISESSION\n");
2303 : :
2304 [ # # ]: 0 : if (!(cdi->ops->capability & CDC_MULTI_SESSION))
2305 : : return -ENOSYS;
2306 : :
2307 [ # # ]: 0 : if (copy_from_user(&ms_info, argp, sizeof(ms_info)))
2308 : : return -EFAULT;
2309 : :
2310 : 0 : requested_format = ms_info.addr_format;
2311 [ # # ]: 0 : if (requested_format != CDROM_MSF && requested_format != CDROM_LBA)
2312 : : return -EINVAL;
2313 : 0 : ms_info.addr_format = CDROM_LBA;
2314 : :
2315 : 0 : ret = cdi->ops->get_last_session(cdi, &ms_info);
2316 [ # # ]: 0 : if (ret)
2317 : : return ret;
2318 : :
2319 : 0 : sanitize_format(&ms_info.addr, &ms_info.addr_format, requested_format);
2320 : :
2321 [ # # ]: 0 : if (copy_to_user(argp, &ms_info, sizeof(ms_info)))
2322 : 0 : return -EFAULT;
2323 : :
2324 : : cd_dbg(CD_DO_IOCTL, "CDROMMULTISESSION successful\n");
2325 : : return 0;
2326 : : }
2327 : :
2328 : 0 : static int cdrom_ioctl_eject(struct cdrom_device_info *cdi)
2329 : : {
2330 : 0 : cd_dbg(CD_DO_IOCTL, "entering CDROMEJECT\n");
2331 : :
2332 [ # # ]: 0 : if (!CDROM_CAN(CDC_OPEN_TRAY))
2333 : : return -ENOSYS;
2334 [ # # # # ]: 0 : if (cdi->use_count != 1 || cdi->keeplocked)
2335 : : return -EBUSY;
2336 [ # # ]: 0 : if (CDROM_CAN(CDC_LOCK)) {
2337 : 0 : int ret = cdi->ops->lock_door(cdi, 0);
2338 [ # # ]: 0 : if (ret)
2339 : : return ret;
2340 : : }
2341 : :
2342 : 0 : return cdi->ops->tray_move(cdi, 1);
2343 : : }
2344 : :
2345 : 0 : static int cdrom_ioctl_closetray(struct cdrom_device_info *cdi)
2346 : : {
2347 : 0 : cd_dbg(CD_DO_IOCTL, "entering CDROMCLOSETRAY\n");
2348 : :
2349 : 0 : if (!CDROM_CAN(CDC_CLOSE_TRAY))
2350 : : return -ENOSYS;
2351 : 0 : return cdi->ops->tray_move(cdi, 0);
2352 : : }
2353 : :
2354 : 0 : static int cdrom_ioctl_eject_sw(struct cdrom_device_info *cdi,
2355 : : unsigned long arg)
2356 : : {
2357 : 0 : cd_dbg(CD_DO_IOCTL, "entering CDROMEJECT_SW\n");
2358 : :
2359 : 0 : if (!CDROM_CAN(CDC_OPEN_TRAY))
2360 : : return -ENOSYS;
2361 [ # # ]: 0 : if (cdi->keeplocked)
2362 : : return -EBUSY;
2363 : :
2364 : 0 : cdi->options &= ~(CDO_AUTO_CLOSE | CDO_AUTO_EJECT);
2365 [ # # ]: 0 : if (arg)
2366 : 0 : cdi->options |= CDO_AUTO_CLOSE | CDO_AUTO_EJECT;
2367 : : return 0;
2368 : : }
2369 : :
2370 : 0 : static int cdrom_ioctl_media_changed(struct cdrom_device_info *cdi,
2371 : : unsigned long arg)
2372 : : {
2373 : 0 : struct cdrom_changer_info *info;
2374 : 0 : int ret;
2375 : :
2376 : 0 : cd_dbg(CD_DO_IOCTL, "entering CDROM_MEDIA_CHANGED\n");
2377 : :
2378 [ # # ]: 0 : if (!CDROM_CAN(CDC_MEDIA_CHANGED))
2379 : : return -ENOSYS;
2380 : :
2381 : : /* cannot select disc or select current disc */
2382 [ # # # # ]: 0 : if (!CDROM_CAN(CDC_SELECT_DISC) || arg == CDSL_CURRENT)
2383 : 0 : return media_changed(cdi, 1);
2384 : :
2385 [ # # ]: 0 : if (arg >= cdi->capacity)
2386 : : return -EINVAL;
2387 : :
2388 : 0 : info = kmalloc(sizeof(*info), GFP_KERNEL);
2389 [ # # ]: 0 : if (!info)
2390 : : return -ENOMEM;
2391 : :
2392 : 0 : ret = cdrom_read_mech_status(cdi, info);
2393 [ # # ]: 0 : if (!ret)
2394 : 0 : ret = info->slots[arg].change;
2395 : 0 : kfree(info);
2396 : 0 : return ret;
2397 : : }
2398 : :
2399 : 0 : static int cdrom_ioctl_set_options(struct cdrom_device_info *cdi,
2400 : : unsigned long arg)
2401 : : {
2402 : 0 : cd_dbg(CD_DO_IOCTL, "entering CDROM_SET_OPTIONS\n");
2403 : :
2404 : : /*
2405 : : * Options need to be in sync with capability.
2406 : : * Too late for that, so we have to check each one separately.
2407 : : */
2408 [ # # # # ]: 0 : switch (arg) {
2409 : : case CDO_USE_FFLAGS:
2410 : : case CDO_CHECK_TYPE:
2411 : : break;
2412 : 0 : case CDO_LOCK:
2413 [ # # ]: 0 : if (!CDROM_CAN(CDC_LOCK))
2414 : : return -ENOSYS;
2415 : : break;
2416 : 0 : case 0:
2417 : 0 : return cdi->options;
2418 : : /* default is basically CDO_[AUTO_CLOSE|AUTO_EJECT] */
2419 : 0 : default:
2420 [ # # ]: 0 : if (!CDROM_CAN(arg))
2421 : : return -ENOSYS;
2422 : : }
2423 : 0 : cdi->options |= (int) arg;
2424 : 0 : return cdi->options;
2425 : : }
2426 : :
2427 : 0 : static int cdrom_ioctl_clear_options(struct cdrom_device_info *cdi,
2428 : : unsigned long arg)
2429 : : {
2430 : 0 : cd_dbg(CD_DO_IOCTL, "entering CDROM_CLEAR_OPTIONS\n");
2431 : :
2432 : 0 : cdi->options &= ~(int) arg;
2433 : 0 : return cdi->options;
2434 : : }
2435 : :
2436 : 0 : static int cdrom_ioctl_select_speed(struct cdrom_device_info *cdi,
2437 : : unsigned long arg)
2438 : : {
2439 : 0 : cd_dbg(CD_DO_IOCTL, "entering CDROM_SELECT_SPEED\n");
2440 : :
2441 : 0 : if (!CDROM_CAN(CDC_SELECT_SPEED))
2442 : : return -ENOSYS;
2443 : 0 : return cdi->ops->select_speed(cdi, arg);
2444 : : }
2445 : :
2446 : 0 : static int cdrom_ioctl_select_disc(struct cdrom_device_info *cdi,
2447 : : unsigned long arg)
2448 : : {
2449 : 0 : cd_dbg(CD_DO_IOCTL, "entering CDROM_SELECT_DISC\n");
2450 : :
2451 [ # # ]: 0 : if (!CDROM_CAN(CDC_SELECT_DISC))
2452 : : return -ENOSYS;
2453 : :
2454 [ # # ]: 0 : if (arg != CDSL_CURRENT && arg != CDSL_NONE) {
2455 [ # # ]: 0 : if (arg >= cdi->capacity)
2456 : : return -EINVAL;
2457 : : }
2458 : :
2459 : : /*
2460 : : * ->select_disc is a hook to allow a driver-specific way of
2461 : : * seleting disc. However, since there is no equivalent hook for
2462 : : * cdrom_slot_status this may not actually be useful...
2463 : : */
2464 [ # # ]: 0 : if (cdi->ops->select_disc)
2465 : 0 : return cdi->ops->select_disc(cdi, arg);
2466 : :
2467 : 0 : cd_dbg(CD_CHANGER, "Using generic cdrom_select_disc()\n");
2468 : 0 : return cdrom_select_disc(cdi, arg);
2469 : : }
2470 : :
2471 : 0 : static int cdrom_ioctl_reset(struct cdrom_device_info *cdi,
2472 : : struct block_device *bdev)
2473 : : {
2474 : 0 : cd_dbg(CD_DO_IOCTL, "entering CDROM_RESET\n");
2475 : :
2476 [ # # ]: 0 : if (!capable(CAP_SYS_ADMIN))
2477 : : return -EACCES;
2478 [ # # ]: 0 : if (!CDROM_CAN(CDC_RESET))
2479 : : return -ENOSYS;
2480 : 0 : invalidate_bdev(bdev);
2481 : 0 : return cdi->ops->reset(cdi);
2482 : : }
2483 : :
2484 : 0 : static int cdrom_ioctl_lock_door(struct cdrom_device_info *cdi,
2485 : : unsigned long arg)
2486 : : {
2487 : 0 : cd_dbg(CD_DO_IOCTL, "%socking door\n", arg ? "L" : "Unl");
2488 : :
2489 [ # # ]: 0 : if (!CDROM_CAN(CDC_LOCK))
2490 : : return -EDRIVE_CANT_DO_THIS;
2491 : :
2492 : 0 : cdi->keeplocked = arg ? 1 : 0;
2493 : :
2494 : : /*
2495 : : * Don't unlock the door on multiple opens by default, but allow
2496 : : * root to do so.
2497 : : */
2498 [ # # # # : 0 : if (cdi->use_count != 1 && !arg && !capable(CAP_SYS_ADMIN))
# # ]
2499 : : return -EBUSY;
2500 : 0 : return cdi->ops->lock_door(cdi, arg);
2501 : : }
2502 : :
2503 : 0 : static int cdrom_ioctl_debug(struct cdrom_device_info *cdi,
2504 : : unsigned long arg)
2505 : : {
2506 : 0 : cd_dbg(CD_DO_IOCTL, "%sabling debug\n", arg ? "En" : "Dis");
2507 : :
2508 [ # # ]: 0 : if (!capable(CAP_SYS_ADMIN))
2509 : : return -EACCES;
2510 : 0 : debug = arg ? 1 : 0;
2511 : 0 : return debug;
2512 : : }
2513 : :
2514 : 13 : static int cdrom_ioctl_get_capability(struct cdrom_device_info *cdi)
2515 : : {
2516 : 13 : cd_dbg(CD_DO_IOCTL, "entering CDROM_GET_CAPABILITY\n");
2517 : 13 : return (cdi->ops->capability & ~cdi->mask);
2518 : : }
2519 : :
2520 : : /*
2521 : : * The following function is implemented, although very few audio
2522 : : * discs give Universal Product Code information, which should just be
2523 : : * the Medium Catalog Number on the box. Note, that the way the code
2524 : : * is written on the CD is /not/ uniform across all discs!
2525 : : */
2526 : 0 : static int cdrom_ioctl_get_mcn(struct cdrom_device_info *cdi,
2527 : : void __user *argp)
2528 : : {
2529 : 0 : struct cdrom_mcn mcn;
2530 : 0 : int ret;
2531 : :
2532 : 0 : cd_dbg(CD_DO_IOCTL, "entering CDROM_GET_MCN\n");
2533 : :
2534 [ # # ]: 0 : if (!(cdi->ops->capability & CDC_MCN))
2535 : : return -ENOSYS;
2536 : 0 : ret = cdi->ops->get_mcn(cdi, &mcn);
2537 [ # # ]: 0 : if (ret)
2538 : : return ret;
2539 : :
2540 [ # # ]: 0 : if (copy_to_user(argp, &mcn, sizeof(mcn)))
2541 : 0 : return -EFAULT;
2542 : : cd_dbg(CD_DO_IOCTL, "CDROM_GET_MCN successful\n");
2543 : : return 0;
2544 : : }
2545 : :
2546 : 13 : static int cdrom_ioctl_drive_status(struct cdrom_device_info *cdi,
2547 : : unsigned long arg)
2548 : : {
2549 : 13 : cd_dbg(CD_DO_IOCTL, "entering CDROM_DRIVE_STATUS\n");
2550 : :
2551 [ + - ]: 13 : if (!(cdi->ops->capability & CDC_DRIVE_STATUS))
2552 : : return -ENOSYS;
2553 [ - + ]: 13 : if (!CDROM_CAN(CDC_SELECT_DISC) ||
2554 [ # # ]: 0 : (arg == CDSL_CURRENT || arg == CDSL_NONE))
2555 : 13 : return cdi->ops->drive_status(cdi, CDSL_CURRENT);
2556 [ # # ]: 0 : if (arg >= cdi->capacity)
2557 : : return -EINVAL;
2558 : 0 : return cdrom_slot_status(cdi, arg);
2559 : : }
2560 : :
2561 : : /*
2562 : : * Ok, this is where problems start. The current interface for the
2563 : : * CDROM_DISC_STATUS ioctl is flawed. It makes the false assumption that
2564 : : * CDs are all CDS_DATA_1 or all CDS_AUDIO, etc. Unfortunately, while this
2565 : : * is often the case, it is also very common for CDs to have some tracks
2566 : : * with data, and some tracks with audio. Just because I feel like it,
2567 : : * I declare the following to be the best way to cope. If the CD has ANY
2568 : : * data tracks on it, it will be returned as a data CD. If it has any XA
2569 : : * tracks, I will return it as that. Now I could simplify this interface
2570 : : * by combining these returns with the above, but this more clearly
2571 : : * demonstrates the problem with the current interface. Too bad this
2572 : : * wasn't designed to use bitmasks... -Erik
2573 : : *
2574 : : * Well, now we have the option CDS_MIXED: a mixed-type CD.
2575 : : * User level programmers might feel the ioctl is not very useful.
2576 : : * ---david
2577 : : */
2578 : 0 : static int cdrom_ioctl_disc_status(struct cdrom_device_info *cdi)
2579 : : {
2580 : 0 : tracktype tracks;
2581 : :
2582 : 0 : cd_dbg(CD_DO_IOCTL, "entering CDROM_DISC_STATUS\n");
2583 : :
2584 : 0 : cdrom_count_tracks(cdi, &tracks);
2585 [ # # ]: 0 : if (tracks.error)
2586 : 0 : return tracks.error;
2587 : :
2588 : : /* Policy mode on */
2589 [ # # ]: 0 : if (tracks.audio > 0) {
2590 [ # # # # ]: 0 : if (!tracks.data && !tracks.cdi && !tracks.xa)
2591 : : return CDS_AUDIO;
2592 : : else
2593 : 0 : return CDS_MIXED;
2594 : : }
2595 : :
2596 [ # # ]: 0 : if (tracks.cdi > 0)
2597 : : return CDS_XA_2_2;
2598 [ # # ]: 0 : if (tracks.xa > 0)
2599 : : return CDS_XA_2_1;
2600 [ # # ]: 0 : if (tracks.data > 0)
2601 : 0 : return CDS_DATA_1;
2602 : : /* Policy mode off */
2603 : :
2604 : : cd_dbg(CD_WARNING, "This disc doesn't have any tracks I recognize!\n");
2605 : : return CDS_NO_INFO;
2606 : : }
2607 : :
2608 : 0 : static int cdrom_ioctl_changer_nslots(struct cdrom_device_info *cdi)
2609 : : {
2610 : 0 : cd_dbg(CD_DO_IOCTL, "entering CDROM_CHANGER_NSLOTS\n");
2611 : 0 : return cdi->capacity;
2612 : : }
2613 : :
2614 : 0 : static int cdrom_ioctl_get_subchnl(struct cdrom_device_info *cdi,
2615 : : void __user *argp)
2616 : : {
2617 : 0 : struct cdrom_subchnl q;
2618 : 0 : u8 requested, back;
2619 : 0 : int ret;
2620 : :
2621 : : /* cd_dbg(CD_DO_IOCTL,"entering CDROMSUBCHNL\n");*/
2622 : :
2623 [ # # ]: 0 : if (copy_from_user(&q, argp, sizeof(q)))
2624 : : return -EFAULT;
2625 : :
2626 : 0 : requested = q.cdsc_format;
2627 [ # # ]: 0 : if (requested != CDROM_MSF && requested != CDROM_LBA)
2628 : : return -EINVAL;
2629 : 0 : q.cdsc_format = CDROM_MSF;
2630 : :
2631 : 0 : ret = cdi->ops->audio_ioctl(cdi, CDROMSUBCHNL, &q);
2632 [ # # ]: 0 : if (ret)
2633 : : return ret;
2634 : :
2635 : 0 : back = q.cdsc_format; /* local copy */
2636 : 0 : sanitize_format(&q.cdsc_absaddr, &back, requested);
2637 : 0 : sanitize_format(&q.cdsc_reladdr, &q.cdsc_format, requested);
2638 : :
2639 [ # # ]: 0 : if (copy_to_user(argp, &q, sizeof(q)))
2640 : 0 : return -EFAULT;
2641 : : /* cd_dbg(CD_DO_IOCTL, "CDROMSUBCHNL successful\n"); */
2642 : : return 0;
2643 : : }
2644 : :
2645 : 0 : static int cdrom_ioctl_read_tochdr(struct cdrom_device_info *cdi,
2646 : : void __user *argp)
2647 : : {
2648 : 0 : struct cdrom_tochdr header;
2649 : 0 : int ret;
2650 : :
2651 : : /* cd_dbg(CD_DO_IOCTL, "entering CDROMREADTOCHDR\n"); */
2652 : :
2653 [ # # ]: 0 : if (copy_from_user(&header, argp, sizeof(header)))
2654 : : return -EFAULT;
2655 : :
2656 : 0 : ret = cdi->ops->audio_ioctl(cdi, CDROMREADTOCHDR, &header);
2657 [ # # ]: 0 : if (ret)
2658 : : return ret;
2659 : :
2660 [ # # ]: 0 : if (copy_to_user(argp, &header, sizeof(header)))
2661 : 0 : return -EFAULT;
2662 : : /* cd_dbg(CD_DO_IOCTL, "CDROMREADTOCHDR successful\n"); */
2663 : : return 0;
2664 : : }
2665 : :
2666 : 0 : static int cdrom_ioctl_read_tocentry(struct cdrom_device_info *cdi,
2667 : : void __user *argp)
2668 : : {
2669 : 0 : struct cdrom_tocentry entry;
2670 : 0 : u8 requested_format;
2671 : 0 : int ret;
2672 : :
2673 : : /* cd_dbg(CD_DO_IOCTL, "entering CDROMREADTOCENTRY\n"); */
2674 : :
2675 [ # # ]: 0 : if (copy_from_user(&entry, argp, sizeof(entry)))
2676 : : return -EFAULT;
2677 : :
2678 : 0 : requested_format = entry.cdte_format;
2679 [ # # ]: 0 : if (requested_format != CDROM_MSF && requested_format != CDROM_LBA)
2680 : : return -EINVAL;
2681 : : /* make interface to low-level uniform */
2682 : 0 : entry.cdte_format = CDROM_MSF;
2683 : 0 : ret = cdi->ops->audio_ioctl(cdi, CDROMREADTOCENTRY, &entry);
2684 [ # # ]: 0 : if (ret)
2685 : : return ret;
2686 : 0 : sanitize_format(&entry.cdte_addr, &entry.cdte_format, requested_format);
2687 : :
2688 [ # # ]: 0 : if (copy_to_user(argp, &entry, sizeof(entry)))
2689 : 0 : return -EFAULT;
2690 : : /* cd_dbg(CD_DO_IOCTL, "CDROMREADTOCENTRY successful\n"); */
2691 : : return 0;
2692 : : }
2693 : :
2694 : 0 : static int cdrom_ioctl_play_msf(struct cdrom_device_info *cdi,
2695 : : void __user *argp)
2696 : : {
2697 : 0 : struct cdrom_msf msf;
2698 : :
2699 : 0 : cd_dbg(CD_DO_IOCTL, "entering CDROMPLAYMSF\n");
2700 : :
2701 [ # # ]: 0 : if (!CDROM_CAN(CDC_PLAY_AUDIO))
2702 : : return -ENOSYS;
2703 [ # # ]: 0 : if (copy_from_user(&msf, argp, sizeof(msf)))
2704 : : return -EFAULT;
2705 : 0 : return cdi->ops->audio_ioctl(cdi, CDROMPLAYMSF, &msf);
2706 : : }
2707 : :
2708 : 0 : static int cdrom_ioctl_play_trkind(struct cdrom_device_info *cdi,
2709 : : void __user *argp)
2710 : : {
2711 : 0 : struct cdrom_ti ti;
2712 : 0 : int ret;
2713 : :
2714 : 0 : cd_dbg(CD_DO_IOCTL, "entering CDROMPLAYTRKIND\n");
2715 : :
2716 [ # # ]: 0 : if (!CDROM_CAN(CDC_PLAY_AUDIO))
2717 : : return -ENOSYS;
2718 [ # # ]: 0 : if (copy_from_user(&ti, argp, sizeof(ti)))
2719 : : return -EFAULT;
2720 : :
2721 : 0 : ret = check_for_audio_disc(cdi, cdi->ops);
2722 [ # # ]: 0 : if (ret)
2723 : : return ret;
2724 : 0 : return cdi->ops->audio_ioctl(cdi, CDROMPLAYTRKIND, &ti);
2725 : : }
2726 : 0 : static int cdrom_ioctl_volctrl(struct cdrom_device_info *cdi,
2727 : : void __user *argp)
2728 : : {
2729 : 0 : struct cdrom_volctrl volume;
2730 : :
2731 : 0 : cd_dbg(CD_DO_IOCTL, "entering CDROMVOLCTRL\n");
2732 : :
2733 [ # # ]: 0 : if (!CDROM_CAN(CDC_PLAY_AUDIO))
2734 : : return -ENOSYS;
2735 [ # # ]: 0 : if (copy_from_user(&volume, argp, sizeof(volume)))
2736 : : return -EFAULT;
2737 : 0 : return cdi->ops->audio_ioctl(cdi, CDROMVOLCTRL, &volume);
2738 : : }
2739 : :
2740 : 0 : static int cdrom_ioctl_volread(struct cdrom_device_info *cdi,
2741 : : void __user *argp)
2742 : : {
2743 : 0 : struct cdrom_volctrl volume;
2744 : 0 : int ret;
2745 : :
2746 : 0 : cd_dbg(CD_DO_IOCTL, "entering CDROMVOLREAD\n");
2747 : :
2748 [ # # ]: 0 : if (!CDROM_CAN(CDC_PLAY_AUDIO))
2749 : : return -ENOSYS;
2750 : :
2751 : 0 : ret = cdi->ops->audio_ioctl(cdi, CDROMVOLREAD, &volume);
2752 [ # # ]: 0 : if (ret)
2753 : : return ret;
2754 : :
2755 [ # # ]: 0 : if (copy_to_user(argp, &volume, sizeof(volume)))
2756 : 0 : return -EFAULT;
2757 : : return 0;
2758 : : }
2759 : :
2760 : 0 : static int cdrom_ioctl_audioctl(struct cdrom_device_info *cdi,
2761 : : unsigned int cmd)
2762 : : {
2763 : 0 : int ret;
2764 : :
2765 : 0 : cd_dbg(CD_DO_IOCTL, "doing audio ioctl (start/stop/pause/resume)\n");
2766 : :
2767 [ # # ]: 0 : if (!CDROM_CAN(CDC_PLAY_AUDIO))
2768 : : return -ENOSYS;
2769 : 0 : ret = check_for_audio_disc(cdi, cdi->ops);
2770 [ # # ]: 0 : if (ret)
2771 : : return ret;
2772 : 0 : return cdi->ops->audio_ioctl(cdi, cmd, NULL);
2773 : : }
2774 : :
2775 : : /*
2776 : : * Required when we need to use READ_10 to issue other than 2048 block
2777 : : * reads
2778 : : */
2779 : 0 : static int cdrom_switch_blocksize(struct cdrom_device_info *cdi, int size)
2780 : : {
2781 : 0 : const struct cdrom_device_ops *cdo = cdi->ops;
2782 : 0 : struct packet_command cgc;
2783 : 0 : struct modesel_head mh;
2784 : :
2785 : 0 : memset(&mh, 0, sizeof(mh));
2786 : 0 : mh.block_desc_length = 0x08;
2787 : 0 : mh.block_length_med = (size >> 8) & 0xff;
2788 : 0 : mh.block_length_lo = size & 0xff;
2789 : :
2790 : 0 : memset(&cgc, 0, sizeof(cgc));
2791 : 0 : cgc.cmd[0] = 0x15;
2792 : 0 : cgc.cmd[1] = 1 << 4;
2793 : 0 : cgc.cmd[4] = 12;
2794 : 0 : cgc.buflen = sizeof(mh);
2795 : 0 : cgc.buffer = (char *) &mh;
2796 : 0 : cgc.data_direction = CGC_DATA_WRITE;
2797 : 0 : mh.block_desc_length = 0x08;
2798 : 0 : mh.block_length_med = (size >> 8) & 0xff;
2799 : 0 : mh.block_length_lo = size & 0xff;
2800 : :
2801 : 0 : return cdo->generic_packet(cdi, &cgc);
2802 : : }
2803 : :
2804 : 0 : static int cdrom_get_track_info(struct cdrom_device_info *cdi,
2805 : : __u16 track, __u8 type, track_information *ti)
2806 : : {
2807 : 0 : const struct cdrom_device_ops *cdo = cdi->ops;
2808 : 0 : struct packet_command cgc;
2809 : 0 : int ret, buflen;
2810 : :
2811 : 0 : init_cdrom_command(&cgc, ti, 8, CGC_DATA_READ);
2812 : 0 : cgc.cmd[0] = GPCMD_READ_TRACK_RZONE_INFO;
2813 : 0 : cgc.cmd[1] = type & 3;
2814 : 0 : cgc.cmd[4] = (track & 0xff00) >> 8;
2815 : 0 : cgc.cmd[5] = track & 0xff;
2816 : 0 : cgc.cmd[8] = 8;
2817 : 0 : cgc.quiet = 1;
2818 : :
2819 : 0 : ret = cdo->generic_packet(cdi, &cgc);
2820 [ # # ]: 0 : if (ret)
2821 : : return ret;
2822 : :
2823 : 0 : buflen = be16_to_cpu(ti->track_information_length) +
2824 : : sizeof(ti->track_information_length);
2825 : :
2826 : 0 : if (buflen > sizeof(track_information))
2827 : : buflen = sizeof(track_information);
2828 : :
2829 : 0 : cgc.cmd[8] = cgc.buflen = buflen;
2830 : 0 : ret = cdo->generic_packet(cdi, &cgc);
2831 [ # # ]: 0 : if (ret)
2832 : 0 : return ret;
2833 : :
2834 : : /* return actual fill size */
2835 : : return buflen;
2836 : : }
2837 : :
2838 : : /* return the last written block on the CD-R media. this is for the udf
2839 : : file system. */
2840 : 0 : int cdrom_get_last_written(struct cdrom_device_info *cdi, long *last_written)
2841 : : {
2842 : 0 : struct cdrom_tocentry toc;
2843 : 0 : disc_information di;
2844 : 0 : track_information ti;
2845 : 0 : __u32 last_track;
2846 : 0 : int ret = -1, ti_size;
2847 : :
2848 [ # # ]: 0 : if (!CDROM_CAN(CDC_GENERIC_PACKET))
2849 : 0 : goto use_toc;
2850 : :
2851 : 0 : ret = cdrom_get_disc_info(cdi, &di);
2852 [ # # ]: 0 : if (ret < (int)(offsetof(typeof(di), last_track_lsb)
2853 : : + sizeof(di.last_track_lsb)))
2854 : 0 : goto use_toc;
2855 : :
2856 : : /* if unit didn't return msb, it's zeroed by cdrom_get_disc_info */
2857 : 0 : last_track = (di.last_track_msb << 8) | di.last_track_lsb;
2858 : 0 : ti_size = cdrom_get_track_info(cdi, last_track, 1, &ti);
2859 [ # # ]: 0 : if (ti_size < (int)offsetof(typeof(ti), track_start))
2860 : 0 : goto use_toc;
2861 : :
2862 : : /* if this track is blank, try the previous. */
2863 [ # # ]: 0 : if (ti.blank) {
2864 [ # # ]: 0 : if (last_track == 1)
2865 : 0 : goto use_toc;
2866 : 0 : last_track--;
2867 : 0 : ti_size = cdrom_get_track_info(cdi, last_track, 1, &ti);
2868 : : }
2869 : :
2870 [ # # ]: 0 : if (ti_size < (int)(offsetof(typeof(ti), track_size)
2871 : : + sizeof(ti.track_size)))
2872 : 0 : goto use_toc;
2873 : :
2874 : : /* if last recorded field is valid, return it. */
2875 [ # # # # ]: 0 : if (ti.lra_v && ti_size >= (int)(offsetof(typeof(ti), last_rec_address)
2876 : : + sizeof(ti.last_rec_address))) {
2877 : 0 : *last_written = be32_to_cpu(ti.last_rec_address);
2878 : : } else {
2879 : : /* make it up instead */
2880 : 0 : *last_written = be32_to_cpu(ti.track_start) +
2881 : 0 : be32_to_cpu(ti.track_size);
2882 [ # # ]: 0 : if (ti.free_blocks)
2883 : 0 : *last_written -= (be32_to_cpu(ti.free_blocks) + 7);
2884 : : }
2885 : : return 0;
2886 : :
2887 : : /* this is where we end up if the drive either can't do a
2888 : : GPCMD_READ_DISC_INFO or GPCMD_READ_TRACK_RZONE_INFO or if
2889 : : it doesn't give enough information or fails. then we return
2890 : : the toc contents. */
2891 : 0 : use_toc:
2892 [ # # ]: 0 : if (!CDROM_CAN(CDC_PLAY_AUDIO))
2893 : : return -ENOSYS;
2894 : :
2895 : 0 : toc.cdte_format = CDROM_MSF;
2896 : 0 : toc.cdte_track = CDROM_LEADOUT;
2897 [ # # ]: 0 : if ((ret = cdi->ops->audio_ioctl(cdi, CDROMREADTOCENTRY, &toc)))
2898 : : return ret;
2899 [ # # ]: 0 : sanitize_format(&toc.cdte_addr, &toc.cdte_format, CDROM_LBA);
2900 : 0 : *last_written = toc.cdte_addr.lba;
2901 : 0 : return 0;
2902 : : }
2903 : :
2904 : : /* return the next writable block. also for udf file system. */
2905 : 0 : static int cdrom_get_next_writable(struct cdrom_device_info *cdi,
2906 : : long *next_writable)
2907 : : {
2908 : 0 : disc_information di;
2909 : 0 : track_information ti;
2910 : 0 : __u16 last_track;
2911 : 0 : int ret, ti_size;
2912 : :
2913 [ # # ]: 0 : if (!CDROM_CAN(CDC_GENERIC_PACKET))
2914 : 0 : goto use_last_written;
2915 : :
2916 : 0 : ret = cdrom_get_disc_info(cdi, &di);
2917 [ # # ]: 0 : if (ret < 0 || ret < offsetof(typeof(di), last_track_lsb)
2918 : : + sizeof(di.last_track_lsb))
2919 : 0 : goto use_last_written;
2920 : :
2921 : : /* if unit didn't return msb, it's zeroed by cdrom_get_disc_info */
2922 : 0 : last_track = (di.last_track_msb << 8) | di.last_track_lsb;
2923 : 0 : ti_size = cdrom_get_track_info(cdi, last_track, 1, &ti);
2924 [ # # ]: 0 : if (ti_size < 0 || ti_size < offsetof(typeof(ti), track_start))
2925 : 0 : goto use_last_written;
2926 : :
2927 : : /* if this track is blank, try the previous. */
2928 [ # # ]: 0 : if (ti.blank) {
2929 [ # # ]: 0 : if (last_track == 1)
2930 : 0 : goto use_last_written;
2931 : 0 : last_track--;
2932 : 0 : ti_size = cdrom_get_track_info(cdi, last_track, 1, &ti);
2933 [ # # ]: 0 : if (ti_size < 0)
2934 : 0 : goto use_last_written;
2935 : : }
2936 : :
2937 : : /* if next recordable address field is valid, use it. */
2938 [ # # # # ]: 0 : if (ti.nwa_v && ti_size >= offsetof(typeof(ti), next_writable)
2939 : : + sizeof(ti.next_writable)) {
2940 : 0 : *next_writable = be32_to_cpu(ti.next_writable);
2941 : 0 : return 0;
2942 : : }
2943 : :
2944 : 0 : use_last_written:
2945 : 0 : ret = cdrom_get_last_written(cdi, next_writable);
2946 [ # # ]: 0 : if (ret) {
2947 : 0 : *next_writable = 0;
2948 : 0 : return ret;
2949 : : } else {
2950 : 0 : *next_writable += 7;
2951 : 0 : return 0;
2952 : : }
2953 : : }
2954 : :
2955 : 0 : static noinline int mmc_ioctl_cdrom_read_data(struct cdrom_device_info *cdi,
2956 : : void __user *arg,
2957 : : struct packet_command *cgc,
2958 : : int cmd)
2959 : : {
2960 : 0 : struct scsi_sense_hdr sshdr;
2961 : 0 : struct cdrom_msf msf;
2962 : 0 : int blocksize = 0, format = 0, lba;
2963 : 0 : int ret;
2964 : :
2965 [ # # ]: 0 : switch (cmd) {
2966 : : case CDROMREADRAW:
2967 : : blocksize = CD_FRAMESIZE_RAW;
2968 : : break;
2969 : : case CDROMREADMODE1:
2970 : : blocksize = CD_FRAMESIZE;
2971 : : format = 2;
2972 : : break;
2973 : : case CDROMREADMODE2:
2974 : : blocksize = CD_FRAMESIZE_RAW0;
2975 : : break;
2976 : : }
2977 [ # # ]: 0 : if (copy_from_user(&msf, (struct cdrom_msf __user *)arg, sizeof(msf)))
2978 : : return -EFAULT;
2979 [ # # ]: 0 : lba = msf_to_lba(msf.cdmsf_min0, msf.cdmsf_sec0, msf.cdmsf_frame0);
2980 : : /* FIXME: we need upper bound checking, too!! */
2981 [ # # ]: 0 : if (lba < 0)
2982 : : return -EINVAL;
2983 : :
2984 : 0 : cgc->buffer = kzalloc(blocksize, GFP_KERNEL);
2985 [ # # ]: 0 : if (cgc->buffer == NULL)
2986 : : return -ENOMEM;
2987 : :
2988 : 0 : memset(&sshdr, 0, sizeof(sshdr));
2989 : 0 : cgc->sshdr = &sshdr;
2990 : 0 : cgc->data_direction = CGC_DATA_READ;
2991 : 0 : ret = cdrom_read_block(cdi, cgc, lba, 1, format, blocksize);
2992 [ # # # # ]: 0 : if (ret && sshdr.sense_key == 0x05 &&
2993 [ # # ]: 0 : sshdr.asc == 0x20 &&
2994 [ # # ]: 0 : sshdr.ascq == 0x00) {
2995 : : /*
2996 : : * SCSI-II devices are not required to support
2997 : : * READ_CD, so let's try switching block size
2998 : : */
2999 : : /* FIXME: switch back again... */
3000 : 0 : ret = cdrom_switch_blocksize(cdi, blocksize);
3001 [ # # ]: 0 : if (ret)
3002 : 0 : goto out;
3003 : 0 : cgc->sshdr = NULL;
3004 : 0 : ret = cdrom_read_cd(cdi, cgc, lba, blocksize, 1);
3005 : 0 : ret |= cdrom_switch_blocksize(cdi, blocksize);
3006 : : }
3007 [ # # # # : 0 : if (!ret && copy_to_user(arg, cgc->buffer, blocksize))
# # ]
3008 : 0 : ret = -EFAULT;
3009 : 0 : out:
3010 : 0 : kfree(cgc->buffer);
3011 : 0 : return ret;
3012 : : }
3013 : :
3014 : 0 : static noinline int mmc_ioctl_cdrom_read_audio(struct cdrom_device_info *cdi,
3015 : : void __user *arg)
3016 : : {
3017 : 0 : struct cdrom_read_audio ra;
3018 : 0 : int lba;
3019 : :
3020 : : #ifdef CONFIG_COMPAT
3021 [ # # # # ]: 0 : if (in_compat_syscall()) {
3022 : 0 : struct compat_cdrom_read_audio {
3023 : : union cdrom_addr addr;
3024 : : u8 addr_format;
3025 : : compat_int_t nframes;
3026 : : compat_caddr_t buf;
3027 : : } ra32;
3028 : :
3029 [ # # ]: 0 : if (copy_from_user(&ra32, arg, sizeof(ra32)))
3030 : 0 : return -EFAULT;
3031 : :
3032 : 0 : ra = (struct cdrom_read_audio) {
3033 : : .addr = ra32.addr,
3034 : 0 : .addr_format = ra32.addr_format,
3035 : 0 : .nframes = ra32.nframes,
3036 : 0 : .buf = compat_ptr(ra32.buf),
3037 : : };
3038 : : } else
3039 : : #endif
3040 : : {
3041 [ # # ]: 0 : if (copy_from_user(&ra, (struct cdrom_read_audio __user *)arg,
3042 : : sizeof(ra)))
3043 : : return -EFAULT;
3044 : : }
3045 : :
3046 [ # # ]: 0 : if (ra.addr_format == CDROM_MSF)
3047 : 0 : lba = msf_to_lba(ra.addr.msf.minute,
3048 : 0 : ra.addr.msf.second,
3049 : 0 : ra.addr.msf.frame);
3050 [ # # ]: 0 : else if (ra.addr_format == CDROM_LBA)
3051 : 0 : lba = ra.addr.lba;
3052 : : else
3053 : : return -EINVAL;
3054 : :
3055 : : /* FIXME: we need upper bound checking, too!! */
3056 [ # # # # : 0 : if (lba < 0 || ra.nframes <= 0 || ra.nframes > CD_FRAMES)
# # ]
3057 : : return -EINVAL;
3058 : :
3059 : 0 : return cdrom_read_cdda(cdi, ra.buf, lba, ra.nframes);
3060 : : }
3061 : :
3062 : 0 : static noinline int mmc_ioctl_cdrom_subchannel(struct cdrom_device_info *cdi,
3063 : : void __user *arg)
3064 : : {
3065 : 0 : int ret;
3066 : 0 : struct cdrom_subchnl q;
3067 : 0 : u_char requested, back;
3068 [ # # ]: 0 : if (copy_from_user(&q, (struct cdrom_subchnl __user *)arg, sizeof(q)))
3069 : : return -EFAULT;
3070 : 0 : requested = q.cdsc_format;
3071 [ # # ]: 0 : if (!((requested == CDROM_MSF) ||
3072 : : (requested == CDROM_LBA)))
3073 : : return -EINVAL;
3074 : :
3075 : 0 : ret = cdrom_read_subchannel(cdi, &q, 0);
3076 [ # # ]: 0 : if (ret)
3077 : : return ret;
3078 : 0 : back = q.cdsc_format; /* local copy */
3079 : 0 : sanitize_format(&q.cdsc_absaddr, &back, requested);
3080 : 0 : sanitize_format(&q.cdsc_reladdr, &q.cdsc_format, requested);
3081 [ # # ]: 0 : if (copy_to_user((struct cdrom_subchnl __user *)arg, &q, sizeof(q)))
3082 : 0 : return -EFAULT;
3083 : : /* cd_dbg(CD_DO_IOCTL, "CDROMSUBCHNL successful\n"); */
3084 : : return 0;
3085 : : }
3086 : :
3087 : 0 : static noinline int mmc_ioctl_cdrom_play_msf(struct cdrom_device_info *cdi,
3088 : : void __user *arg,
3089 : : struct packet_command *cgc)
3090 : : {
3091 : 0 : const struct cdrom_device_ops *cdo = cdi->ops;
3092 : 0 : struct cdrom_msf msf;
3093 : 0 : cd_dbg(CD_DO_IOCTL, "entering CDROMPLAYMSF\n");
3094 [ # # ]: 0 : if (copy_from_user(&msf, (struct cdrom_msf __user *)arg, sizeof(msf)))
3095 : : return -EFAULT;
3096 : 0 : cgc->cmd[0] = GPCMD_PLAY_AUDIO_MSF;
3097 : 0 : cgc->cmd[3] = msf.cdmsf_min0;
3098 : 0 : cgc->cmd[4] = msf.cdmsf_sec0;
3099 : 0 : cgc->cmd[5] = msf.cdmsf_frame0;
3100 : 0 : cgc->cmd[6] = msf.cdmsf_min1;
3101 : 0 : cgc->cmd[7] = msf.cdmsf_sec1;
3102 : 0 : cgc->cmd[8] = msf.cdmsf_frame1;
3103 : 0 : cgc->data_direction = CGC_DATA_NONE;
3104 : 0 : return cdo->generic_packet(cdi, cgc);
3105 : : }
3106 : :
3107 : 0 : static noinline int mmc_ioctl_cdrom_play_blk(struct cdrom_device_info *cdi,
3108 : : void __user *arg,
3109 : : struct packet_command *cgc)
3110 : : {
3111 : 0 : const struct cdrom_device_ops *cdo = cdi->ops;
3112 : 0 : struct cdrom_blk blk;
3113 : 0 : cd_dbg(CD_DO_IOCTL, "entering CDROMPLAYBLK\n");
3114 [ # # ]: 0 : if (copy_from_user(&blk, (struct cdrom_blk __user *)arg, sizeof(blk)))
3115 : : return -EFAULT;
3116 : 0 : cgc->cmd[0] = GPCMD_PLAY_AUDIO_10;
3117 : 0 : cgc->cmd[2] = (blk.from >> 24) & 0xff;
3118 : 0 : cgc->cmd[3] = (blk.from >> 16) & 0xff;
3119 : 0 : cgc->cmd[4] = (blk.from >> 8) & 0xff;
3120 : 0 : cgc->cmd[5] = blk.from & 0xff;
3121 : 0 : cgc->cmd[7] = (blk.len >> 8) & 0xff;
3122 : 0 : cgc->cmd[8] = blk.len & 0xff;
3123 : 0 : cgc->data_direction = CGC_DATA_NONE;
3124 : 0 : return cdo->generic_packet(cdi, cgc);
3125 : : }
3126 : :
3127 : 0 : static noinline int mmc_ioctl_cdrom_volume(struct cdrom_device_info *cdi,
3128 : : void __user *arg,
3129 : : struct packet_command *cgc,
3130 : : unsigned int cmd)
3131 : : {
3132 : 0 : struct cdrom_volctrl volctrl;
3133 : 0 : unsigned char buffer[32];
3134 : 0 : char mask[sizeof(buffer)];
3135 : 0 : unsigned short offset;
3136 : 0 : int ret;
3137 : :
3138 : 0 : cd_dbg(CD_DO_IOCTL, "entering CDROMVOLUME\n");
3139 : :
3140 [ # # ]: 0 : if (copy_from_user(&volctrl, (struct cdrom_volctrl __user *)arg,
3141 : : sizeof(volctrl)))
3142 : : return -EFAULT;
3143 : :
3144 : 0 : cgc->buffer = buffer;
3145 : 0 : cgc->buflen = 24;
3146 : 0 : ret = cdrom_mode_sense(cdi, cgc, GPMODE_AUDIO_CTL_PAGE, 0);
3147 [ # # ]: 0 : if (ret)
3148 : : return ret;
3149 : :
3150 : : /* originally the code depended on buffer[1] to determine
3151 : : how much data is available for transfer. buffer[1] is
3152 : : unfortunately ambigious and the only reliable way seem
3153 : : to be to simply skip over the block descriptor... */
3154 : 0 : offset = 8 + be16_to_cpu(*(__be16 *)(buffer + 6));
3155 : :
3156 [ # # ]: 0 : if (offset + 16 > sizeof(buffer))
3157 : : return -E2BIG;
3158 : :
3159 [ # # ]: 0 : if (offset + 16 > cgc->buflen) {
3160 : 0 : cgc->buflen = offset + 16;
3161 : 0 : ret = cdrom_mode_sense(cdi, cgc,
3162 : : GPMODE_AUDIO_CTL_PAGE, 0);
3163 [ # # ]: 0 : if (ret)
3164 : : return ret;
3165 : : }
3166 : :
3167 : : /* sanity check */
3168 [ # # ]: 0 : if ((buffer[offset] & 0x3f) != GPMODE_AUDIO_CTL_PAGE ||
3169 [ # # ]: 0 : buffer[offset + 1] < 14)
3170 : : return -EINVAL;
3171 : :
3172 : : /* now we have the current volume settings. if it was only
3173 : : a CDROMVOLREAD, return these values */
3174 [ # # ]: 0 : if (cmd == CDROMVOLREAD) {
3175 : 0 : volctrl.channel0 = buffer[offset+9];
3176 : 0 : volctrl.channel1 = buffer[offset+11];
3177 : 0 : volctrl.channel2 = buffer[offset+13];
3178 : 0 : volctrl.channel3 = buffer[offset+15];
3179 [ # # ]: 0 : if (copy_to_user((struct cdrom_volctrl __user *)arg, &volctrl,
3180 : : sizeof(volctrl)))
3181 : : return -EFAULT;
3182 : 0 : return 0;
3183 : : }
3184 : :
3185 : : /* get the volume mask */
3186 : 0 : cgc->buffer = mask;
3187 : 0 : ret = cdrom_mode_sense(cdi, cgc, GPMODE_AUDIO_CTL_PAGE, 1);
3188 [ # # ]: 0 : if (ret)
3189 : : return ret;
3190 : :
3191 : 0 : buffer[offset + 9] = volctrl.channel0 & mask[offset + 9];
3192 : 0 : buffer[offset + 11] = volctrl.channel1 & mask[offset + 11];
3193 : 0 : buffer[offset + 13] = volctrl.channel2 & mask[offset + 13];
3194 : 0 : buffer[offset + 15] = volctrl.channel3 & mask[offset + 15];
3195 : :
3196 : : /* set volume */
3197 : 0 : cgc->buffer = buffer + offset - 8;
3198 : 0 : memset(cgc->buffer, 0, 8);
3199 : 0 : return cdrom_mode_select(cdi, cgc);
3200 : : }
3201 : :
3202 : 0 : static noinline int mmc_ioctl_cdrom_start_stop(struct cdrom_device_info *cdi,
3203 : : struct packet_command *cgc,
3204 : : int cmd)
3205 : : {
3206 : 0 : const struct cdrom_device_ops *cdo = cdi->ops;
3207 : 0 : cd_dbg(CD_DO_IOCTL, "entering CDROMSTART/CDROMSTOP\n");
3208 : 0 : cgc->cmd[0] = GPCMD_START_STOP_UNIT;
3209 : 0 : cgc->cmd[1] = 1;
3210 : 0 : cgc->cmd[4] = (cmd == CDROMSTART) ? 1 : 0;
3211 : 0 : cgc->data_direction = CGC_DATA_NONE;
3212 : 0 : return cdo->generic_packet(cdi, cgc);
3213 : : }
3214 : :
3215 : 0 : static noinline int mmc_ioctl_cdrom_pause_resume(struct cdrom_device_info *cdi,
3216 : : struct packet_command *cgc,
3217 : : int cmd)
3218 : : {
3219 : 0 : const struct cdrom_device_ops *cdo = cdi->ops;
3220 : 0 : cd_dbg(CD_DO_IOCTL, "entering CDROMPAUSE/CDROMRESUME\n");
3221 : 0 : cgc->cmd[0] = GPCMD_PAUSE_RESUME;
3222 : 0 : cgc->cmd[8] = (cmd == CDROMRESUME) ? 1 : 0;
3223 : 0 : cgc->data_direction = CGC_DATA_NONE;
3224 : 0 : return cdo->generic_packet(cdi, cgc);
3225 : : }
3226 : :
3227 : 0 : static noinline int mmc_ioctl_dvd_read_struct(struct cdrom_device_info *cdi,
3228 : : void __user *arg,
3229 : : struct packet_command *cgc)
3230 : : {
3231 : 0 : int ret;
3232 : 0 : dvd_struct *s;
3233 : 0 : int size = sizeof(dvd_struct);
3234 : :
3235 [ # # ]: 0 : if (!CDROM_CAN(CDC_DVD))
3236 : : return -ENOSYS;
3237 : :
3238 : 0 : s = memdup_user(arg, size);
3239 [ # # ]: 0 : if (IS_ERR(s))
3240 : 0 : return PTR_ERR(s);
3241 : :
3242 : 0 : cd_dbg(CD_DO_IOCTL, "entering DVD_READ_STRUCT\n");
3243 : :
3244 : 0 : ret = dvd_read_struct(cdi, s, cgc);
3245 [ # # ]: 0 : if (ret)
3246 : 0 : goto out;
3247 : :
3248 [ # # # # ]: 0 : if (copy_to_user(arg, s, size))
3249 : : ret = -EFAULT;
3250 : 0 : out:
3251 : 0 : kfree(s);
3252 : 0 : return ret;
3253 : : }
3254 : :
3255 : 0 : static noinline int mmc_ioctl_dvd_auth(struct cdrom_device_info *cdi,
3256 : : void __user *arg)
3257 : : {
3258 : 0 : int ret;
3259 : 0 : dvd_authinfo ai;
3260 [ # # ]: 0 : if (!CDROM_CAN(CDC_DVD))
3261 : : return -ENOSYS;
3262 : 0 : cd_dbg(CD_DO_IOCTL, "entering DVD_AUTH\n");
3263 [ # # ]: 0 : if (copy_from_user(&ai, (dvd_authinfo __user *)arg, sizeof(ai)))
3264 : : return -EFAULT;
3265 : 0 : ret = dvd_do_auth(cdi, &ai);
3266 [ # # ]: 0 : if (ret)
3267 : : return ret;
3268 [ # # ]: 0 : if (copy_to_user((dvd_authinfo __user *)arg, &ai, sizeof(ai)))
3269 : 0 : return -EFAULT;
3270 : : return 0;
3271 : : }
3272 : :
3273 : 0 : static noinline int mmc_ioctl_cdrom_next_writable(struct cdrom_device_info *cdi,
3274 : : void __user *arg)
3275 : : {
3276 : 0 : int ret;
3277 : 0 : long next = 0;
3278 : 0 : cd_dbg(CD_DO_IOCTL, "entering CDROM_NEXT_WRITABLE\n");
3279 : 0 : ret = cdrom_get_next_writable(cdi, &next);
3280 [ # # ]: 0 : if (ret)
3281 : : return ret;
3282 [ # # ]: 0 : if (copy_to_user((long __user *)arg, &next, sizeof(next)))
3283 : 0 : return -EFAULT;
3284 : : return 0;
3285 : : }
3286 : :
3287 : 0 : static noinline int mmc_ioctl_cdrom_last_written(struct cdrom_device_info *cdi,
3288 : : void __user *arg)
3289 : : {
3290 : 0 : int ret;
3291 : 0 : long last = 0;
3292 : 0 : cd_dbg(CD_DO_IOCTL, "entering CDROM_LAST_WRITTEN\n");
3293 : 0 : ret = cdrom_get_last_written(cdi, &last);
3294 [ # # ]: 0 : if (ret)
3295 : : return ret;
3296 [ # # # # ]: 0 : if (in_compat_syscall())
3297 : 0 : return put_user(last, (__s32 __user *)arg);
3298 : :
3299 : 0 : return put_user(last, (long __user *)arg);
3300 : : }
3301 : :
3302 : 0 : static int mmc_ioctl(struct cdrom_device_info *cdi, unsigned int cmd,
3303 : : unsigned long arg)
3304 : : {
3305 : 0 : struct packet_command cgc;
3306 : 0 : void __user *userptr = (void __user *)arg;
3307 : :
3308 : 0 : memset(&cgc, 0, sizeof(cgc));
3309 : :
3310 : : /* build a unified command and queue it through
3311 : : cdo->generic_packet() */
3312 [ # # # # : 0 : switch (cmd) {
# # # # #
# # # # ]
3313 : 0 : case CDROMREADRAW:
3314 : : case CDROMREADMODE1:
3315 : : case CDROMREADMODE2:
3316 : 0 : return mmc_ioctl_cdrom_read_data(cdi, userptr, &cgc, cmd);
3317 : 0 : case CDROMREADAUDIO:
3318 : 0 : return mmc_ioctl_cdrom_read_audio(cdi, userptr);
3319 : 0 : case CDROMSUBCHNL:
3320 : 0 : return mmc_ioctl_cdrom_subchannel(cdi, userptr);
3321 : 0 : case CDROMPLAYMSF:
3322 : 0 : return mmc_ioctl_cdrom_play_msf(cdi, userptr, &cgc);
3323 : 0 : case CDROMPLAYBLK:
3324 : 0 : return mmc_ioctl_cdrom_play_blk(cdi, userptr, &cgc);
3325 : 0 : case CDROMVOLCTRL:
3326 : : case CDROMVOLREAD:
3327 : 0 : return mmc_ioctl_cdrom_volume(cdi, userptr, &cgc, cmd);
3328 : 0 : case CDROMSTART:
3329 : : case CDROMSTOP:
3330 : 0 : return mmc_ioctl_cdrom_start_stop(cdi, &cgc, cmd);
3331 : 0 : case CDROMPAUSE:
3332 : : case CDROMRESUME:
3333 : 0 : return mmc_ioctl_cdrom_pause_resume(cdi, &cgc, cmd);
3334 : 0 : case DVD_READ_STRUCT:
3335 : 0 : return mmc_ioctl_dvd_read_struct(cdi, userptr, &cgc);
3336 : 0 : case DVD_AUTH:
3337 : 0 : return mmc_ioctl_dvd_auth(cdi, userptr);
3338 : 0 : case CDROM_NEXT_WRITABLE:
3339 : 0 : return mmc_ioctl_cdrom_next_writable(cdi, userptr);
3340 : 0 : case CDROM_LAST_WRITTEN:
3341 : 0 : return mmc_ioctl_cdrom_last_written(cdi, userptr);
3342 : : }
3343 : :
3344 : : return -ENOTTY;
3345 : : }
3346 : :
3347 : : /*
3348 : : * Just about every imaginable ioctl is supported in the Uniform layer
3349 : : * these days.
3350 : : * ATAPI / SCSI specific code now mainly resides in mmc_ioctl().
3351 : : */
3352 : 117 : int cdrom_ioctl(struct cdrom_device_info *cdi, struct block_device *bdev,
3353 : : fmode_t mode, unsigned int cmd, unsigned long arg)
3354 : : {
3355 : 117 : void __user *argp = (void __user *)arg;
3356 : 117 : int ret;
3357 : :
3358 : : /*
3359 : : * Try the generic SCSI command ioctl's first.
3360 : : */
3361 : 117 : ret = scsi_cmd_blk_ioctl(bdev, mode, cmd, argp);
3362 [ + + ]: 117 : if (ret != -ENOTTY)
3363 : : return ret;
3364 : :
3365 [ - - - - : 26 : switch (cmd) {
- - - - -
- - - + -
+ - - - ]
3366 : 0 : case CDROMMULTISESSION:
3367 : 0 : return cdrom_ioctl_multisession(cdi, argp);
3368 : 0 : case CDROMEJECT:
3369 : 0 : return cdrom_ioctl_eject(cdi);
3370 : : case CDROMCLOSETRAY:
3371 [ # # ]: 0 : return cdrom_ioctl_closetray(cdi);
3372 : : case CDROMEJECT_SW:
3373 [ # # ]: 0 : return cdrom_ioctl_eject_sw(cdi, arg);
3374 : 0 : case CDROM_MEDIA_CHANGED:
3375 : 0 : return cdrom_ioctl_media_changed(cdi, arg);
3376 : 0 : case CDROM_SET_OPTIONS:
3377 : 0 : return cdrom_ioctl_set_options(cdi, arg);
3378 : : case CDROM_CLEAR_OPTIONS:
3379 : 0 : return cdrom_ioctl_clear_options(cdi, arg);
3380 : : case CDROM_SELECT_SPEED:
3381 [ # # ]: 0 : return cdrom_ioctl_select_speed(cdi, arg);
3382 : 0 : case CDROM_SELECT_DISC:
3383 : 0 : return cdrom_ioctl_select_disc(cdi, arg);
3384 : 0 : case CDROMRESET:
3385 : 0 : return cdrom_ioctl_reset(cdi, bdev);
3386 : 0 : case CDROM_LOCKDOOR:
3387 : 0 : return cdrom_ioctl_lock_door(cdi, arg);
3388 : : case CDROM_DEBUG:
3389 : 0 : return cdrom_ioctl_debug(cdi, arg);
3390 : 13 : case CDROM_GET_CAPABILITY:
3391 : 13 : return cdrom_ioctl_get_capability(cdi);
3392 : 0 : case CDROM_GET_MCN:
3393 : 0 : return cdrom_ioctl_get_mcn(cdi, argp);
3394 : 13 : case CDROM_DRIVE_STATUS:
3395 : 13 : return cdrom_ioctl_drive_status(cdi, arg);
3396 : 0 : case CDROM_DISC_STATUS:
3397 : 0 : return cdrom_ioctl_disc_status(cdi);
3398 : 0 : case CDROM_CHANGER_NSLOTS:
3399 : 0 : return cdrom_ioctl_changer_nslots(cdi);
3400 : : }
3401 : :
3402 : : /*
3403 : : * Use the ioctls that are implemented through the generic_packet()
3404 : : * interface. this may look at bit funny, but if -ENOTTY is
3405 : : * returned that particular ioctl is not implemented and we
3406 : : * let it go through the device specific ones.
3407 : : */
3408 [ # # ]: 0 : if (CDROM_CAN(CDC_GENERIC_PACKET)) {
3409 : 0 : ret = mmc_ioctl(cdi, cmd, arg);
3410 [ # # ]: 0 : if (ret != -ENOTTY)
3411 : : return ret;
3412 : : }
3413 : :
3414 : : /*
3415 : : * Note: most of the cd_dbg() calls are commented out here,
3416 : : * because they fill up the sys log when CD players poll
3417 : : * the drive.
3418 : : */
3419 [ # # # # : 0 : switch (cmd) {
# # # #
# ]
3420 : 0 : case CDROMSUBCHNL:
3421 : 0 : return cdrom_ioctl_get_subchnl(cdi, argp);
3422 : 0 : case CDROMREADTOCHDR:
3423 : 0 : return cdrom_ioctl_read_tochdr(cdi, argp);
3424 : 0 : case CDROMREADTOCENTRY:
3425 : 0 : return cdrom_ioctl_read_tocentry(cdi, argp);
3426 : 0 : case CDROMPLAYMSF:
3427 : 0 : return cdrom_ioctl_play_msf(cdi, argp);
3428 : 0 : case CDROMPLAYTRKIND:
3429 : 0 : return cdrom_ioctl_play_trkind(cdi, argp);
3430 : 0 : case CDROMVOLCTRL:
3431 : 0 : return cdrom_ioctl_volctrl(cdi, argp);
3432 : 0 : case CDROMVOLREAD:
3433 : 0 : return cdrom_ioctl_volread(cdi, argp);
3434 : 0 : case CDROMSTART:
3435 : : case CDROMSTOP:
3436 : : case CDROMPAUSE:
3437 : : case CDROMRESUME:
3438 : 0 : return cdrom_ioctl_audioctl(cdi, cmd);
3439 : : }
3440 : :
3441 : : return -ENOSYS;
3442 : : }
3443 : :
3444 : : EXPORT_SYMBOL(cdrom_get_last_written);
3445 : : EXPORT_SYMBOL(register_cdrom);
3446 : : EXPORT_SYMBOL(unregister_cdrom);
3447 : : EXPORT_SYMBOL(cdrom_open);
3448 : : EXPORT_SYMBOL(cdrom_release);
3449 : : EXPORT_SYMBOL(cdrom_ioctl);
3450 : : EXPORT_SYMBOL(cdrom_media_changed);
3451 : : EXPORT_SYMBOL(cdrom_number_of_slots);
3452 : : EXPORT_SYMBOL(cdrom_mode_select);
3453 : : EXPORT_SYMBOL(cdrom_mode_sense);
3454 : : EXPORT_SYMBOL(init_cdrom_command);
3455 : : EXPORT_SYMBOL(cdrom_get_media_event);
3456 : :
3457 : : #ifdef CONFIG_SYSCTL
3458 : :
3459 : : #define CDROM_STR_SIZE 1000
3460 : :
3461 : : static struct cdrom_sysctl_settings {
3462 : : char info[CDROM_STR_SIZE]; /* general info */
3463 : : int autoclose; /* close tray upon mount, etc */
3464 : : int autoeject; /* eject on umount */
3465 : : int debug; /* turn on debugging messages */
3466 : : int lock; /* lock the door on device open */
3467 : : int check; /* check media type */
3468 : : } cdrom_sysctl_settings;
3469 : :
3470 : : enum cdrom_print_option {
3471 : : CTL_NAME,
3472 : : CTL_SPEED,
3473 : : CTL_SLOTS,
3474 : : CTL_CAPABILITY
3475 : : };
3476 : :
3477 : 0 : static int cdrom_print_info(const char *header, int val, char *info,
3478 : : int *pos, enum cdrom_print_option option)
3479 : : {
3480 : 0 : const int max_size = sizeof(cdrom_sysctl_settings.info);
3481 : 0 : struct cdrom_device_info *cdi;
3482 : 0 : int ret;
3483 : :
3484 : 0 : ret = scnprintf(info + *pos, max_size - *pos, header);
3485 [ # # ]: 0 : if (!ret)
3486 : : return 1;
3487 : :
3488 : 0 : *pos += ret;
3489 : :
3490 [ # # ]: 0 : list_for_each_entry(cdi, &cdrom_list, list) {
3491 [ # # # # : 0 : switch (option) {
# ]
3492 : 0 : case CTL_NAME:
3493 : 0 : ret = scnprintf(info + *pos, max_size - *pos,
3494 : 0 : "\t%s", cdi->name);
3495 : 0 : break;
3496 : 0 : case CTL_SPEED:
3497 : 0 : ret = scnprintf(info + *pos, max_size - *pos,
3498 : : "\t%d", cdi->speed);
3499 : 0 : break;
3500 : 0 : case CTL_SLOTS:
3501 : 0 : ret = scnprintf(info + *pos, max_size - *pos,
3502 : : "\t%d", cdi->capacity);
3503 : 0 : break;
3504 : 0 : case CTL_CAPABILITY:
3505 : 0 : ret = scnprintf(info + *pos, max_size - *pos,
3506 : 0 : "\t%d", CDROM_CAN(val) != 0);
3507 : 0 : break;
3508 : 0 : default:
3509 : 0 : pr_info("invalid option%d\n", option);
3510 : 0 : return 1;
3511 : : }
3512 [ # # ]: 0 : if (!ret)
3513 : : return 1;
3514 : 0 : *pos += ret;
3515 : : }
3516 : :
3517 : : return 0;
3518 : : }
3519 : :
3520 : 0 : static int cdrom_sysctl_info(struct ctl_table *ctl, int write,
3521 : : void __user *buffer, size_t *lenp, loff_t *ppos)
3522 : : {
3523 : 0 : int pos;
3524 : 0 : char *info = cdrom_sysctl_settings.info;
3525 : 0 : const int max_size = sizeof(cdrom_sysctl_settings.info);
3526 : :
3527 [ # # # # : 0 : if (!*lenp || (*ppos && !write)) {
# # ]
3528 : 0 : *lenp = 0;
3529 : 0 : return 0;
3530 : : }
3531 : :
3532 : 0 : mutex_lock(&cdrom_mutex);
3533 : :
3534 : 0 : pos = sprintf(info, "CD-ROM information, " VERSION "\n");
3535 : :
3536 [ # # ]: 0 : if (cdrom_print_info("\ndrive name:\t", 0, info, &pos, CTL_NAME))
3537 : 0 : goto done;
3538 [ # # ]: 0 : if (cdrom_print_info("\ndrive speed:\t", 0, info, &pos, CTL_SPEED))
3539 : 0 : goto done;
3540 [ # # ]: 0 : if (cdrom_print_info("\ndrive # of slots:", 0, info, &pos, CTL_SLOTS))
3541 : 0 : goto done;
3542 [ # # ]: 0 : if (cdrom_print_info("\nCan close tray:\t",
3543 : : CDC_CLOSE_TRAY, info, &pos, CTL_CAPABILITY))
3544 : 0 : goto done;
3545 [ # # ]: 0 : if (cdrom_print_info("\nCan open tray:\t",
3546 : : CDC_OPEN_TRAY, info, &pos, CTL_CAPABILITY))
3547 : 0 : goto done;
3548 [ # # ]: 0 : if (cdrom_print_info("\nCan lock tray:\t",
3549 : : CDC_LOCK, info, &pos, CTL_CAPABILITY))
3550 : 0 : goto done;
3551 [ # # ]: 0 : if (cdrom_print_info("\nCan change speed:",
3552 : : CDC_SELECT_SPEED, info, &pos, CTL_CAPABILITY))
3553 : 0 : goto done;
3554 [ # # ]: 0 : if (cdrom_print_info("\nCan select disk:",
3555 : : CDC_SELECT_DISC, info, &pos, CTL_CAPABILITY))
3556 : 0 : goto done;
3557 [ # # ]: 0 : if (cdrom_print_info("\nCan read multisession:",
3558 : : CDC_MULTI_SESSION, info, &pos, CTL_CAPABILITY))
3559 : 0 : goto done;
3560 [ # # ]: 0 : if (cdrom_print_info("\nCan read MCN:\t",
3561 : : CDC_MCN, info, &pos, CTL_CAPABILITY))
3562 : 0 : goto done;
3563 [ # # ]: 0 : if (cdrom_print_info("\nReports media changed:",
3564 : : CDC_MEDIA_CHANGED, info, &pos, CTL_CAPABILITY))
3565 : 0 : goto done;
3566 [ # # ]: 0 : if (cdrom_print_info("\nCan play audio:\t",
3567 : : CDC_PLAY_AUDIO, info, &pos, CTL_CAPABILITY))
3568 : 0 : goto done;
3569 [ # # ]: 0 : if (cdrom_print_info("\nCan write CD-R:\t",
3570 : : CDC_CD_R, info, &pos, CTL_CAPABILITY))
3571 : 0 : goto done;
3572 [ # # ]: 0 : if (cdrom_print_info("\nCan write CD-RW:",
3573 : : CDC_CD_RW, info, &pos, CTL_CAPABILITY))
3574 : 0 : goto done;
3575 [ # # ]: 0 : if (cdrom_print_info("\nCan read DVD:\t",
3576 : : CDC_DVD, info, &pos, CTL_CAPABILITY))
3577 : 0 : goto done;
3578 [ # # ]: 0 : if (cdrom_print_info("\nCan write DVD-R:",
3579 : : CDC_DVD_R, info, &pos, CTL_CAPABILITY))
3580 : 0 : goto done;
3581 [ # # ]: 0 : if (cdrom_print_info("\nCan write DVD-RAM:",
3582 : : CDC_DVD_RAM, info, &pos, CTL_CAPABILITY))
3583 : 0 : goto done;
3584 [ # # ]: 0 : if (cdrom_print_info("\nCan read MRW:\t",
3585 : : CDC_MRW, info, &pos, CTL_CAPABILITY))
3586 : 0 : goto done;
3587 [ # # ]: 0 : if (cdrom_print_info("\nCan write MRW:\t",
3588 : : CDC_MRW_W, info, &pos, CTL_CAPABILITY))
3589 : 0 : goto done;
3590 [ # # ]: 0 : if (cdrom_print_info("\nCan write RAM:\t",
3591 : : CDC_RAM, info, &pos, CTL_CAPABILITY))
3592 : 0 : goto done;
3593 [ # # ]: 0 : if (!scnprintf(info + pos, max_size - pos, "\n\n"))
3594 : 0 : goto done;
3595 : 0 : doit:
3596 : 0 : mutex_unlock(&cdrom_mutex);
3597 : 0 : return proc_dostring(ctl, write, buffer, lenp, ppos);
3598 : 0 : done:
3599 : 0 : pr_info("info buffer too small\n");
3600 : 0 : goto doit;
3601 : : }
3602 : :
3603 : : /* Unfortunately, per device settings are not implemented through
3604 : : procfs/sysctl yet. When they are, this will naturally disappear. For now
3605 : : just update all drives. Later this will become the template on which
3606 : : new registered drives will be based. */
3607 : 0 : static void cdrom_update_settings(void)
3608 : : {
3609 : 0 : struct cdrom_device_info *cdi;
3610 : :
3611 : 0 : mutex_lock(&cdrom_mutex);
3612 [ # # ]: 0 : list_for_each_entry(cdi, &cdrom_list, list) {
3613 [ # # # # ]: 0 : if (autoclose && CDROM_CAN(CDC_CLOSE_TRAY))
3614 : 0 : cdi->options |= CDO_AUTO_CLOSE;
3615 [ # # ]: 0 : else if (!autoclose)
3616 : 0 : cdi->options &= ~CDO_AUTO_CLOSE;
3617 [ # # # # ]: 0 : if (autoeject && CDROM_CAN(CDC_OPEN_TRAY))
3618 : 0 : cdi->options |= CDO_AUTO_EJECT;
3619 [ # # ]: 0 : else if (!autoeject)
3620 : 0 : cdi->options &= ~CDO_AUTO_EJECT;
3621 [ # # # # ]: 0 : if (lockdoor && CDROM_CAN(CDC_LOCK))
3622 : 0 : cdi->options |= CDO_LOCK;
3623 [ # # ]: 0 : else if (!lockdoor)
3624 : 0 : cdi->options &= ~CDO_LOCK;
3625 [ # # ]: 0 : if (check_media_type)
3626 : 0 : cdi->options |= CDO_CHECK_TYPE;
3627 : : else
3628 : 0 : cdi->options &= ~CDO_CHECK_TYPE;
3629 : : }
3630 : 0 : mutex_unlock(&cdrom_mutex);
3631 : 0 : }
3632 : :
3633 : 0 : static int cdrom_sysctl_handler(struct ctl_table *ctl, int write,
3634 : : void __user *buffer, size_t *lenp, loff_t *ppos)
3635 : : {
3636 : 0 : int ret;
3637 : :
3638 : 0 : ret = proc_dointvec(ctl, write, buffer, lenp, ppos);
3639 : :
3640 [ # # ]: 0 : if (write) {
3641 : :
3642 : : /* we only care for 1 or 0. */
3643 : 0 : autoclose = !!cdrom_sysctl_settings.autoclose;
3644 : 0 : autoeject = !!cdrom_sysctl_settings.autoeject;
3645 : 0 : debug = !!cdrom_sysctl_settings.debug;
3646 : 0 : lockdoor = !!cdrom_sysctl_settings.lock;
3647 : 0 : check_media_type = !!cdrom_sysctl_settings.check;
3648 : :
3649 : : /* update the option flags according to the changes. we
3650 : : don't have per device options through sysctl yet,
3651 : : but we will have and then this will disappear. */
3652 : 0 : cdrom_update_settings();
3653 : : }
3654 : :
3655 : 0 : return ret;
3656 : : }
3657 : :
3658 : : /* Place files in /proc/sys/dev/cdrom */
3659 : : static struct ctl_table cdrom_table[] = {
3660 : : {
3661 : : .procname = "info",
3662 : : .data = &cdrom_sysctl_settings.info,
3663 : : .maxlen = CDROM_STR_SIZE,
3664 : : .mode = 0444,
3665 : : .proc_handler = cdrom_sysctl_info,
3666 : : },
3667 : : {
3668 : : .procname = "autoclose",
3669 : : .data = &cdrom_sysctl_settings.autoclose,
3670 : : .maxlen = sizeof(int),
3671 : : .mode = 0644,
3672 : : .proc_handler = cdrom_sysctl_handler,
3673 : : },
3674 : : {
3675 : : .procname = "autoeject",
3676 : : .data = &cdrom_sysctl_settings.autoeject,
3677 : : .maxlen = sizeof(int),
3678 : : .mode = 0644,
3679 : : .proc_handler = cdrom_sysctl_handler,
3680 : : },
3681 : : {
3682 : : .procname = "debug",
3683 : : .data = &cdrom_sysctl_settings.debug,
3684 : : .maxlen = sizeof(int),
3685 : : .mode = 0644,
3686 : : .proc_handler = cdrom_sysctl_handler,
3687 : : },
3688 : : {
3689 : : .procname = "lock",
3690 : : .data = &cdrom_sysctl_settings.lock,
3691 : : .maxlen = sizeof(int),
3692 : : .mode = 0644,
3693 : : .proc_handler = cdrom_sysctl_handler,
3694 : : },
3695 : : {
3696 : : .procname = "check_media",
3697 : : .data = &cdrom_sysctl_settings.check,
3698 : : .maxlen = sizeof(int),
3699 : : .mode = 0644,
3700 : : .proc_handler = cdrom_sysctl_handler
3701 : : },
3702 : : { }
3703 : : };
3704 : :
3705 : : static struct ctl_table cdrom_cdrom_table[] = {
3706 : : {
3707 : : .procname = "cdrom",
3708 : : .maxlen = 0,
3709 : : .mode = 0555,
3710 : : .child = cdrom_table,
3711 : : },
3712 : : { }
3713 : : };
3714 : :
3715 : : /* Make sure that /proc/sys/dev is there */
3716 : : static struct ctl_table cdrom_root_table[] = {
3717 : : {
3718 : : .procname = "dev",
3719 : : .maxlen = 0,
3720 : : .mode = 0555,
3721 : : .child = cdrom_cdrom_table,
3722 : : },
3723 : : { }
3724 : : };
3725 : : static struct ctl_table_header *cdrom_sysctl_header;
3726 : :
3727 : 26 : static void cdrom_sysctl_register(void)
3728 : : {
3729 : 26 : static atomic_t initialized = ATOMIC_INIT(0);
3730 : :
3731 [ + + ]: 26 : if (!atomic_add_unless(&initialized, 1, 1))
3732 : : return;
3733 : :
3734 : 13 : cdrom_sysctl_header = register_sysctl_table(cdrom_root_table);
3735 : :
3736 : : /* set the defaults */
3737 : 13 : cdrom_sysctl_settings.autoclose = autoclose;
3738 : 13 : cdrom_sysctl_settings.autoeject = autoeject;
3739 : 13 : cdrom_sysctl_settings.debug = debug;
3740 : 13 : cdrom_sysctl_settings.lock = lockdoor;
3741 : 13 : cdrom_sysctl_settings.check = check_media_type;
3742 : : }
3743 : :
3744 : 0 : static void cdrom_sysctl_unregister(void)
3745 : : {
3746 : 0 : if (cdrom_sysctl_header)
3747 : 0 : unregister_sysctl_table(cdrom_sysctl_header);
3748 : : }
3749 : :
3750 : : #else /* CONFIG_SYSCTL */
3751 : :
3752 : : static void cdrom_sysctl_register(void)
3753 : : {
3754 : : }
3755 : :
3756 : : static void cdrom_sysctl_unregister(void)
3757 : : {
3758 : : }
3759 : :
3760 : : #endif /* CONFIG_SYSCTL */
3761 : :
3762 : 13 : static int __init cdrom_init(void)
3763 : : {
3764 : 13 : cdrom_sysctl_register();
3765 : :
3766 : 13 : return 0;
3767 : : }
3768 : :
3769 : 0 : static void __exit cdrom_exit(void)
3770 : : {
3771 : 0 : pr_info("Uniform CD-ROM driver unloaded\n");
3772 [ # # ]: 0 : cdrom_sysctl_unregister();
3773 : 0 : }
3774 : :
3775 : : module_init(cdrom_init);
3776 : : module_exit(cdrom_exit);
3777 : : MODULE_LICENSE("GPL");
|