LCOV - code coverage report
Current view: top level - drivers/cdrom - cdrom.c (source / functions) Hit Total Coverage
Test: combined.info Lines: 131 1737 7.5 %
Date: 2022-04-01 14:35:51 Functions: 11 93 11.8 %
Branches: 46 866 5.3 %

           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                 :         21 : int register_cdrom(struct cdrom_device_info *cdi)
     590                 :            : {
     591                 :         21 :         static char banner_printed;
     592                 :         21 :         const struct cdrom_device_ops *cdo = cdi->ops;
     593                 :            : 
     594                 :         21 :         cd_dbg(CD_OPEN, "entering register_cdrom\n");
     595                 :            : 
     596   [ +  -  +  - ]:         21 :         if (cdo->open == NULL || cdo->release == NULL)
     597                 :            :                 return -EINVAL;
     598         [ +  - ]:         21 :         if (!banner_printed) {
     599                 :         21 :                 pr_info("Uniform CD-ROM driver " REVISION "\n");
     600                 :         21 :                 banner_printed = 1;
     601                 :         21 :                 cdrom_sysctl_register();
     602                 :            :         }
     603                 :            : 
     604   [ -  +  -  - ]:         21 :         ENSURE(cdo, drive_status, CDC_DRIVE_STATUS);
     605   [ -  +  -  - ]:         21 :         if (cdo->check_events == NULL && cdo->media_changed == NULL)
     606         [ #  # ]:          0 :                 WARN_ON_ONCE(cdo->capability & (CDC_MEDIA_CHANGED | CDC_SELECT_DISC));
     607   [ -  +  -  - ]:         21 :         ENSURE(cdo, tray_move, CDC_CLOSE_TRAY | CDC_OPEN_TRAY);
     608   [ -  +  -  - ]:         21 :         ENSURE(cdo, lock_door, CDC_LOCK);
     609   [ -  +  -  - ]:         21 :         ENSURE(cdo, select_speed, CDC_SELECT_SPEED);
     610   [ -  +  -  - ]:         21 :         ENSURE(cdo, get_last_session, CDC_MULTI_SESSION);
     611   [ -  +  -  - ]:         21 :         ENSURE(cdo, get_mcn, CDC_MCN);
     612   [ -  +  -  - ]:         21 :         ENSURE(cdo, reset, CDC_RESET);
     613   [ -  +  -  - ]:         21 :         ENSURE(cdo, generic_packet, CDC_GENERIC_PACKET);
     614                 :         21 :         cdi->mc_flags = 0;
     615                 :         21 :         cdi->options = CDO_USE_FFLAGS;
     616                 :            : 
     617   [ +  -  +  - ]:         21 :         if (autoclose == 1 && CDROM_CAN(CDC_CLOSE_TRAY))
     618                 :         21 :                 cdi->options |= (int) CDO_AUTO_CLOSE;
     619   [ -  +  -  - ]:         21 :         if (autoeject == 1 && CDROM_CAN(CDC_OPEN_TRAY))
     620                 :          0 :                 cdi->options |= (int) CDO_AUTO_EJECT;
     621         [ +  - ]:         21 :         if (lockdoor == 1)
     622                 :         21 :                 cdi->options |= (int) CDO_LOCK;
     623         [ -  + ]:         21 :         if (check_media_type == 1)
     624                 :          0 :                 cdi->options |= (int) CDO_CHECK_TYPE;
     625                 :            : 
     626         [ +  - ]:         21 :         if (CDROM_CAN(CDC_MRW_W))
     627                 :         21 :                 cdi->exit = cdrom_mrw_exit;
     628                 :            : 
     629         [ +  - ]:         21 :         if (cdi->disk)
     630                 :         21 :                 cdi->cdda_method = CDDA_BPC_FULL;
     631                 :            :         else
     632                 :          0 :                 cdi->cdda_method = CDDA_OLD;
     633                 :            : 
     634         [ -  + ]:         21 :         WARN_ON(!cdo->generic_packet);
     635                 :            : 
     636                 :         21 :         cd_dbg(CD_REG_UNREG, "drive \"/dev/%s\" registered\n", cdi->name);
     637                 :         21 :         mutex_lock(&cdrom_mutex);
     638                 :         21 :         list_add(&cdi->list, &cdrom_list);
     639                 :         21 :         mutex_unlock(&cdrom_mutex);
     640                 :         21 :         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                 :         21 : int cdrom_get_media_event(struct cdrom_device_info *cdi,
     659                 :            :                           struct media_event_desc *med)
     660                 :            : {
     661                 :         21 :         struct packet_command cgc;
     662                 :         21 :         unsigned char buffer[8];
     663                 :         21 :         struct event_header *eh = (struct event_header *)buffer;
     664                 :            : 
     665                 :         21 :         init_cdrom_command(&cgc, buffer, sizeof(buffer), CGC_DATA_READ);
     666                 :         21 :         cgc.cmd[0] = GPCMD_GET_EVENT_STATUS_NOTIFICATION;
     667                 :         21 :         cgc.cmd[1] = 1;         /* IMMED */
     668                 :         21 :         cgc.cmd[4] = 1 << 4;      /* media event */
     669                 :         21 :         cgc.cmd[8] = sizeof(buffer);
     670                 :         21 :         cgc.quiet = 1;
     671                 :            : 
     672         [ +  - ]:         21 :         if (cdi->ops->generic_packet(cdi, &cgc))
     673                 :            :                 return 1;
     674                 :            : 
     675         [ +  - ]:         21 :         if (be16_to_cpu(eh->data_len) < sizeof(*med))
     676                 :            :                 return 1;
     677                 :            : 
     678         [ +  - ]:         21 :         if (eh->nea || eh->notification_class != 0x4)
     679                 :            :                 return 1;
     680                 :            : 
     681                 :         21 :         memcpy(med, &buffer[sizeof(*eh)], sizeof(*med));
     682                 :         21 :         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                 :         21 : static void cdrom_dvd_rw_close_write(struct cdrom_device_info *cdi)
     942                 :            : {
     943                 :         21 :         struct packet_command cgc;
     944                 :            : 
     945         [ -  + ]:         21 :         if (cdi->mmc3_profile != 0x1a) {
     946                 :            :                 cd_dbg(CD_CLOSE, "%s: No DVD+RW\n", cdi->name);
     947                 :         21 :                 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                 :         63 : int cdrom_open(struct cdrom_device_info *cdi, struct block_device *bdev,
    1156                 :            :                fmode_t mode)
    1157                 :            : {
    1158                 :         63 :         int ret;
    1159                 :            : 
    1160                 :         63 :         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                 :         63 :         cdi->use_count++;
    1165   [ +  -  +  - ]:         63 :         if ((mode & FMODE_NDELAY) && (cdi->options & CDO_USE_FFLAGS)) {
    1166                 :         63 :                 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         [ -  + ]:         63 :         if (ret)
    1185                 :          0 :                 goto err;
    1186                 :            : 
    1187                 :         63 :         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                 :         63 : void cdrom_release(struct cdrom_device_info *cdi, fmode_t mode)
    1259                 :            : {
    1260                 :         63 :         const struct cdrom_device_ops *cdo = cdi->ops;
    1261                 :         63 :         int opened_for_data;
    1262                 :            : 
    1263                 :         63 :         cd_dbg(CD_CLOSE, "entering cdrom_release\n");
    1264                 :            : 
    1265         [ +  - ]:         63 :         if (cdi->use_count > 0)
    1266                 :         63 :                 cdi->use_count--;
    1267                 :            : 
    1268         [ +  + ]:         63 :         if (cdi->use_count == 0) {
    1269                 :         21 :                 cd_dbg(CD_CLOSE, "Use count for \"/dev/%s\" now zero\n",
    1270                 :            :                        cdi->name);
    1271                 :         21 :                 cdrom_dvd_rw_close_write(cdi);
    1272                 :            : 
    1273   [ +  -  +  - ]:         21 :                 if ((cdo->capability & CDC_LOCK) && !cdi->keeplocked) {
    1274                 :         21 :                         cd_dbg(CD_CLOSE, "Unlocking door!\n");
    1275                 :         21 :                         cdo->lock_door(cdi, 0);
    1276                 :            :                 }
    1277                 :            :         }
    1278                 :            : 
    1279         [ +  - ]:         63 :         opened_for_data = !(cdi->options & CDO_USE_FFLAGS) ||
    1280         [ +  - ]:         63 :                 !(mode & FMODE_NDELAY);
    1281                 :            : 
    1282                 :            :         /*
    1283                 :            :          * flush cache on last write release
    1284                 :            :          */
    1285                 :         63 :         if (CDROM_CAN(CDC_RAM) && !cdi->use_count && cdi->for_data)
    1286                 :            :                 cdrom_close_write(cdi);
    1287                 :            : 
    1288                 :         63 :         cdo->release(cdi);
    1289         [ +  + ]:         63 :         if (cdi->use_count == 0) {      /* last process that closes dev*/
    1290         [ -  + ]:         21 :                 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                 :         63 : }
    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                 :        192 : static void cdrom_update_events(struct cdrom_device_info *cdi,
    1479                 :            :                                 unsigned int clearing)
    1480                 :            : {
    1481                 :        192 :         unsigned int events;
    1482                 :            : 
    1483                 :        192 :         events = cdi->ops->check_events(cdi, clearing, CDSL_CURRENT);
    1484                 :        192 :         cdi->vfs_events |= events;
    1485                 :        192 :         cdi->ioctl_events |= events;
    1486                 :            : }
    1487                 :            : 
    1488                 :        192 : unsigned int cdrom_check_events(struct cdrom_device_info *cdi,
    1489                 :            :                                 unsigned int clearing)
    1490                 :            : {
    1491                 :        192 :         unsigned int events;
    1492                 :            : 
    1493                 :        192 :         cdrom_update_events(cdi, clearing);
    1494                 :        192 :         events = cdi->vfs_events;
    1495                 :        192 :         cdi->vfs_events = 0;
    1496                 :        192 :         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                 :         21 : void init_cdrom_command(struct packet_command *cgc, void *buf, int len,
    1584                 :            :                         int type)
    1585                 :            : {
    1586                 :         21 :         memset(cgc, 0, sizeof(struct packet_command));
    1587         [ +  - ]:         21 :         if (buf)
    1588                 :         21 :                 memset(buf, 0, len);
    1589                 :         21 :         cgc->buffer = (char *) buf;
    1590                 :         21 :         cgc->buflen = len;
    1591                 :         21 :         cgc->data_direction = type;
    1592         [ #  # ]:          0 :         cgc->timeout = CDROM_DEF_TIMEOUT;
    1593                 :         21 : }
    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                 :         21 : static int cdrom_ioctl_get_capability(struct cdrom_device_info *cdi)
    2515                 :            : {
    2516                 :         21 :         cd_dbg(CD_DO_IOCTL, "entering CDROM_GET_CAPABILITY\n");
    2517                 :         21 :         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                 :         21 : static int cdrom_ioctl_drive_status(struct cdrom_device_info *cdi,
    2547                 :            :                 unsigned long arg)
    2548                 :            : {
    2549                 :         21 :         cd_dbg(CD_DO_IOCTL, "entering CDROM_DRIVE_STATUS\n");
    2550                 :            : 
    2551         [ +  - ]:         21 :         if (!(cdi->ops->capability & CDC_DRIVE_STATUS))
    2552                 :            :                 return -ENOSYS;
    2553         [ -  + ]:         21 :         if (!CDROM_CAN(CDC_SELECT_DISC) ||
    2554         [ #  # ]:          0 :             (arg == CDSL_CURRENT || arg == CDSL_NONE))
    2555                 :         21 :                 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                 :        189 : int cdrom_ioctl(struct cdrom_device_info *cdi, struct block_device *bdev,
    3353                 :            :                 fmode_t mode, unsigned int cmd, unsigned long arg)
    3354                 :            : {
    3355                 :        189 :         void __user *argp = (void __user *)arg;
    3356                 :        189 :         int ret;
    3357                 :            : 
    3358                 :            :         /*
    3359                 :            :          * Try the generic SCSI command ioctl's first.
    3360                 :            :          */
    3361                 :        189 :         ret = scsi_cmd_blk_ioctl(bdev, mode, cmd, argp);
    3362         [ +  + ]:        189 :         if (ret != -ENOTTY)
    3363                 :            :                 return ret;
    3364                 :            : 
    3365   [ -  -  -  -  :         42 :         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                 :         21 :         case CDROM_GET_CAPABILITY:
    3391                 :         21 :                 return cdrom_ioctl_get_capability(cdi);
    3392                 :          0 :         case CDROM_GET_MCN:
    3393                 :          0 :                 return cdrom_ioctl_get_mcn(cdi, argp);
    3394                 :         21 :         case CDROM_DRIVE_STATUS:
    3395                 :         21 :                 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                 :         42 : static void cdrom_sysctl_register(void)
    3728                 :            : {
    3729                 :         42 :         static atomic_t initialized = ATOMIC_INIT(0);
    3730                 :            : 
    3731         [ +  + ]:         42 :         if (!atomic_add_unless(&initialized, 1, 1))
    3732                 :            :                 return;
    3733                 :            : 
    3734                 :         21 :         cdrom_sysctl_header = register_sysctl_table(cdrom_root_table);
    3735                 :            : 
    3736                 :            :         /* set the defaults */
    3737                 :         21 :         cdrom_sysctl_settings.autoclose = autoclose;
    3738                 :         21 :         cdrom_sysctl_settings.autoeject = autoeject;
    3739                 :         21 :         cdrom_sysctl_settings.debug = debug;
    3740                 :         21 :         cdrom_sysctl_settings.lock = lockdoor;
    3741                 :         21 :         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                 :         21 : static int __init cdrom_init(void)
    3763                 :            : {
    3764                 :         21 :         cdrom_sysctl_register();
    3765                 :            : 
    3766                 :         21 :         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");

Generated by: LCOV version 1.14