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>
5 May be copied or modified under the terms of the GNU General Public
6 License. See linux/COPYING for more information.
8 Uniform CD-ROM driver for Linux.
9 See Documentation/cdrom/cdrom-standard.tex for usage information.
11 The routines in the file provide a uniform interface between the
12 software that uses CD-ROMs and the various low-level drivers that
13 actually talk to the hardware. Suggestions are welcome.
14 Patches that work are more welcome though. ;-)
17 ----------------------------------
19 -- Modify sysctl/proc interface. I plan on having one directory per
20 drive, with entries for outputing general drive information, and sysctl
21 based tunable parameters such as whether the tray should auto-close for
22 that drive. Suggestions (or patches) for this welcome!
24 -- Change the CDROMREADMODE1, CDROMREADMODE2, CDROMREADAUDIO, and
25 CDROMREADRAW ioctls so they go through the Uniform CD-ROM driver.
31 ----------------------------------
32 1.00 Date Unknown -- David van Leeuwen <david@tm.tno.nl>
33 -- Initial version by David A. van Leeuwen. I don't have a detailed
34 changelog for the 1.x series, David?
36 2.00 Dec 2, 1997 -- Erik Andersen <andersee@debian.org>
37 -- New maintainer! As David A. van Leeuwen has been too busy to activly
38 maintain and improve this driver, I am now carrying on the torch. If
39 you have a problem with this driver, please feel free to contact me.
41 -- Added (rudimentary) sysctl interface. I realize this is really weak
42 right now, and is _very_ badly implemented. It will be improved...
44 -- Modified CDROM_DISC_STATUS so that it is now incorporated into
45 the Uniform CD-ROM driver via the cdrom_count_tracks function.
46 The cdrom_count_tracks function helps resolve some of the false
47 assumptions of the CDROM_DISC_STATUS ioctl, and is also used to check
48 for the correct media type when mounting or playing audio from a CD.
50 -- Remove the calls to verify_area and only use the copy_from_user and
51 copy_to_user stuff, since these calls now provide their own memory
52 checking with the 2.1.x kernels.
54 -- Major update to return codes so that errors from low-level drivers
55 are passed on through (thanks to Gerd Knorr for pointing out this
58 -- Made it so if a function isn't implemented in a low-level driver,
59 ENOSYS is now returned instead of EINVAL.
61 -- Simplified some complex logic so that the source code is easier to read.
63 -- Other stuff I probably forgot to mention (lots of changes).
65 2.01 to 2.11 Dec 1997-Jan 1998
66 -- TO-DO! Write changelogs for 2.01 to 2.12.
68 2.12 Jan 24, 1998 -- Erik Andersen <andersee@debian.org>
69 -- Fixed a bug in the IOCTL_IN and IOCTL_OUT macros. It turns out that
70 copy_*_user does not return EFAULT on error, but instead return the number
71 of bytes not copied. I was returning whatever non-zero stuff came back from
72 the copy_*_user functions directly, which would result in strange errors.
74 2.13 July 17, 1998 -- Erik Andersen <andersee@debian.org>
75 -- Fixed a bug in CDROM_SELECT_SPEED where you couldn't lower the speed
76 of the drive. Thanks to Tobias Ringstr|m <tori@prosolvia.se> for pointing
77 this out and providing a simple fix.
78 -- Fixed the procfs-unload-module bug with the fill_inode procfs callback.
79 thanks to Andrea Arcangeli <arcangeli@mbox.queen.it>
80 -- Fixed it so that the /proc entry now also shows up when cdrom is
81 compiled into the kernel. Before it only worked when loaded as a module.
83 -------------------------------------------------------------------------*/
85 #define REVISION "Revision: 2.13"
86 #define VERSION "Id: cdrom.c 2.13 1998/07/17 erik"
88 /* I use an error-log mask to give fine grain control over the type of
89 messages dumped to the system logs. The available masks include: */
90 #define CD_NOTHING 0x0
91 #define CD_WARNING 0x1
92 #define CD_REG_UNREG 0x2
93 #define CD_DO_IOCTL 0x4
96 #define CD_COUNT_TRACKS 0x20
98 /* Define this to remove _all_ the debugging messages */
99 /* #define ERRLOGMASK CD_NOTHING */
100 #define ERRLOGMASK (CD_WARNING)
101 /* #define ERRLOGMASK (CD_WARNING|CD_OPEN|CD_COUNT_TRACKS|CD_CLOSE) */
102 /* #define ERRLOGMASK (CD_WARNING|CD_REG_UNREG|CD_DO_IOCTL|CD_OPEN|CD_CLOSE|CD_COUNT_TRACKS) */
105 #include <linux/config.h>
106 #include <linux/module.h>
107 #include <linux/fs.h>
108 #include <linux/major.h>
109 #include <linux/types.h>
110 #include <linux/errno.h>
111 #include <linux/kernel.h>
112 #include <linux/mm.h>
113 #include <linux/malloc.h>
114 #include <linux/cdrom.h>
115 #include <linux/sysctl.h>
116 #include <linux/proc_fs.h>
117 #include <asm/fcntl.h>
118 #include <asm/segment.h>
119 #include <asm/uaccess.h>
121 /* used to tell the module to turn on full debugging messages */
122 static int debug
= 0;
123 /* default compatibility mode */
124 static int autoclose
=1;
125 static int autoeject
=0;
126 static int lockdoor
= 1;
127 static int check_media_type
= 0;
128 MODULE_PARM(debug
, "i");
129 MODULE_PARM(autoclose
, "i");
130 MODULE_PARM(autoeject
, "i");
131 MODULE_PARM(lockdoor
, "i");
132 MODULE_PARM(check_media_type
, "i");
134 #if (ERRLOGMASK!=CD_NOTHING)
135 #define cdinfo(type, fmt, args...) \
136 if ((ERRLOGMASK & type) || debug==1 ) \
137 printk(KERN_INFO "cdrom: " fmt, ## args)
139 #define cdinfo(type, fmt, args...)
142 /* These are used to simplify getting data in from and back to user land */
143 #define IOCTL_IN(arg, type, in) { \
144 if ( copy_from_user(&in, (type *) arg, sizeof in) ) \
147 #define IOCTL_OUT(arg, type, out) { \
148 if ( copy_to_user((type *) arg, &out, sizeof out) ) \
152 #define FM_WRITE 0x2 /* file mode write bit */
154 /* Not-exported routines. */
155 static int cdrom_open(struct inode
*ip
, struct file
*fp
);
156 static int cdrom_release(struct inode
*ip
, struct file
*fp
);
157 static int cdrom_ioctl(struct inode
*ip
, struct file
*fp
,
158 unsigned int cmd
, unsigned long arg
);
159 static int cdrom_media_changed(kdev_t dev
);
160 static int open_for_data(struct cdrom_device_info
* cdi
);
161 static int check_for_audio_disc(struct cdrom_device_info
* cdi
,
162 struct cdrom_device_ops
* cdo
);
163 static void sanitize_format(union cdrom_addr
*addr
,
164 u_char
* curr
, u_char requested
);
165 static void cdrom_sysctl_register(void);
174 static void cdrom_count_tracks(struct cdrom_device_info
*cdi
,tracktype
* tracks
);
175 static struct cdrom_device_info
*topCdromPtr
= NULL
;
177 struct file_operations cdrom_fops
=
180 block_read
, /* read - general block-dev read */
181 block_write
, /* write - general block-dev write */
184 cdrom_ioctl
, /* ioctl */
186 cdrom_open
, /* open */
188 cdrom_release
, /* release */
191 cdrom_media_changed
, /* media_change */
192 NULL
/* revalidate */
195 /* This macro makes sure we don't have to check on cdrom_device_ops
196 * existence in the run-time routines below. Change_capability is a
197 * hack to have the capability flags defined const, while we can still
198 * change it here without gcc complaining at every line.
200 #define ENSURE(call, bits) if (cdo->call == NULL) *change_capability &= ~(bits)
202 int register_cdrom(struct cdrom_device_info
*cdi
)
204 static char banner_printed
= 0;
205 int major
= MAJOR (cdi
->dev
);
206 struct cdrom_device_ops
*cdo
= cdi
->ops
;
207 int *change_capability
= (int *)&cdo
->capability
; /* hack */
209 if (major
< 0 || major
>= MAX_BLKDEV
)
211 if (cdo
->open
== NULL
|| cdo
->release
== NULL
)
213 if ( !banner_printed
) {
214 printk(KERN_INFO
"Uniform CDROM driver " REVISION
"\n");
217 cdrom_sysctl_register();
218 #endif /* CONFIG_SYSCTL */
220 ENSURE(drive_status
, CDC_DRIVE_STATUS
);
221 ENSURE(media_changed
, CDC_MEDIA_CHANGED
);
222 ENSURE(tray_move
, CDC_CLOSE_TRAY
| CDC_OPEN_TRAY
);
223 ENSURE(lock_door
, CDC_LOCK
);
224 ENSURE(select_speed
, CDC_SELECT_SPEED
);
225 ENSURE(select_disc
, CDC_SELECT_DISC
);
226 ENSURE(get_last_session
, CDC_MULTI_SESSION
);
227 ENSURE(get_mcn
, CDC_MCN
);
228 ENSURE(reset
, CDC_RESET
);
229 ENSURE(audio_ioctl
, CDC_PLAY_AUDIO
);
230 ENSURE(dev_ioctl
, CDC_IOCTLS
);
233 cdi
->options
= CDO_USE_FFLAGS
;
235 cdi
->options
|= (int) CDO_AUTO_CLOSE
;
237 cdi
->options
|= (int) CDO_AUTO_EJECT
;
239 cdi
->options
|= (int) CDO_LOCK
;
240 if (check_media_type
==1)
241 cdi
->options
|= (int) CDO_CHECK_TYPE
;
243 cdinfo(CD_REG_UNREG
, "drive \"/dev/%s\" registered\n", cdi
->name
);
244 cdi
->next
= topCdromPtr
;
250 int unregister_cdrom(struct cdrom_device_info
*unreg
)
252 struct cdrom_device_info
*cdi
, *prev
;
253 int major
= MAJOR (unreg
->dev
);
255 if (major
< 0 || major
>= MAX_BLKDEV
)
260 while (cdi
!= NULL
&& cdi
->dev
!= unreg
->dev
) {
268 prev
->next
= cdi
->next
;
270 topCdromPtr
= cdi
->next
;
271 cdi
->ops
->n_minors
--;
272 cdinfo(CD_REG_UNREG
, "drive \"/dev/%s\" unregistered\n", cdi
->name
);
277 struct cdrom_device_info
*cdrom_find_device (kdev_t dev
)
279 struct cdrom_device_info
*cdi
;
282 while (cdi
!= NULL
&& cdi
->dev
!= dev
)
287 /* We use the open-option O_NONBLOCK to indicate that the
288 * purpose of opening is only for subsequent ioctl() calls; no device
289 * integrity checks are performed.
291 * We hope that all cd-player programs will adopt this convention. It
292 * is in their own interest: device control becomes a lot easier
296 int cdrom_open(struct inode
*ip
, struct file
*fp
)
298 kdev_t dev
= ip
->i_rdev
;
299 struct cdrom_device_info
*cdi
= cdrom_find_device(dev
);
300 int purpose
= !!(fp
->f_flags
& O_NONBLOCK
);
303 cdinfo(CD_OPEN
, "entering cdrom_open\n");
306 if (fp
->f_mode
& FM_WRITE
)
308 purpose
= purpose
|| !(cdi
->options
& CDO_USE_FFLAGS
);
309 if (cdi
->use_count
|| purpose
)
310 ret
= cdi
->ops
->open(cdi
, purpose
);
312 ret
= open_for_data(cdi
);
313 if (!ret
) cdi
->use_count
++;
314 cdinfo(CD_OPEN
, "Use count for \"/dev/%s\" now %d\n", cdi
->name
, cdi
->use_count
);
319 int open_for_data(struct cdrom_device_info
* cdi
)
322 struct cdrom_device_ops
*cdo
= cdi
->ops
;
324 cdinfo(CD_OPEN
, "entering open_for_data\n");
325 /* Check if the driver can report drive status. If it can, we
326 can do clever things. If it can't, well, we at least tried! */
327 if (cdo
->drive_status
!= NULL
) {
328 ret
= cdo
->drive_status(cdi
, CDSL_CURRENT
);
329 cdinfo(CD_OPEN
, "drive_status=%d\n", ret
);
330 if (ret
== CDS_TRAY_OPEN
) {
331 cdinfo(CD_OPEN
, "the tray is open...\n");
332 /* can/may i close it? */
333 if (cdo
->capability
& ~cdi
->mask
& CDC_CLOSE_TRAY
&&
334 cdi
->options
& CDO_AUTO_CLOSE
) {
335 cdinfo(CD_OPEN
, "trying to close the tray.\n");
336 ret
=cdo
->tray_move(cdi
,0);
338 cdinfo(CD_OPEN
, "bummer. tried to close the tray but failed.\n");
339 /* Ignore the error from the low
340 level driver. We don't care why it
341 couldn't close the tray. We only care
342 that there is no disc in the drive,
343 since that is the _REAL_ problem here.*/
345 goto clean_up_and_return
;
348 cdinfo(CD_OPEN
, "bummer. this driver can't close the tray.\n");
350 goto clean_up_and_return
;
352 /* Ok, the door should be closed now.. Check again */
353 ret
= cdo
->drive_status(cdi
, CDSL_CURRENT
);
354 if ((ret
== CDS_NO_DISC
) || (ret
==CDS_TRAY_OPEN
)) {
355 cdinfo(CD_OPEN
, "bummer. the tray is still not closed.\n");
357 goto clean_up_and_return
;
359 cdinfo(CD_OPEN
, "the tray is now closed.\n");
361 if (ret
!=CDS_DISC_OK
)
362 goto clean_up_and_return
;
364 cdrom_count_tracks(cdi
, &tracks
);
365 if (tracks
.error
== CDS_NO_DISC
) {
366 cdinfo(CD_OPEN
, "bummer. no disc.\n");
368 goto clean_up_and_return
;
370 /* CD-Players which don't use O_NONBLOCK, workman
371 * for example, need bit CDO_CHECK_TYPE cleared! */
372 if (tracks
.data
==0) {
373 if (cdi
->options
& CDO_CHECK_TYPE
) {
374 cdinfo(CD_OPEN
, "bummer. wrong media type.\n");
376 goto clean_up_and_return
;
379 cdinfo(CD_OPEN
, "wrong media type, but CDO_CHECK_TYPE not set.\n");
383 cdinfo(CD_OPEN
, "all seems well, opening the device.\n");
385 /* all seems well, we can open the device */
386 ret
= cdo
->open(cdi
, 0); /* open for data */
387 cdinfo(CD_OPEN
, "opening the device gave me %d.\n", ret
);
388 /* After all this careful checking, we shouldn't have problems
389 opening the device, but we don't want the device locked if
390 this somehow fails... */
392 cdinfo(CD_OPEN
, "open device failed.\n");
393 goto clean_up_and_return
;
395 if (cdo
->capability
& ~cdi
->mask
& CDC_LOCK
&&
396 cdi
->options
& CDO_LOCK
) {
397 cdo
->lock_door(cdi
, 1);
398 cdinfo(CD_OPEN
, "door locked.\n");
400 cdinfo(CD_OPEN
, "device opened sucessfully.\n");
403 /* Something failed. Try to unlock the drive, because some drivers
404 (notably ide-cd) lock the drive after every command. This produced
405 a nasty bug where after mount failed, the drive would remain locked!
406 This ensures that the drive gets unlocked after a mount fails. This
407 is a goto to avoid bloating the driver with redundant code. */
409 cdinfo(CD_WARNING
, "open failed.\n");
410 if (cdo
->capability
& ~cdi
->mask
& CDC_LOCK
&&
411 cdi
->options
& CDO_LOCK
) {
412 cdo
->lock_door(cdi
, 0);
413 cdinfo(CD_OPEN
, "door unlocked.\n");
418 /* This code is similar to that in open_for_data. The routine is called
419 whenever an audio play operation is requested.
421 int check_for_audio_disc(struct cdrom_device_info
* cdi
,
422 struct cdrom_device_ops
* cdo
)
426 cdinfo(CD_OPEN
, "entering check_for_audio_disc\n");
427 if (!(cdi
->options
& CDO_CHECK_TYPE
))
429 if (cdo
->drive_status
!= NULL
) {
430 ret
= cdo
->drive_status(cdi
, CDSL_CURRENT
);
431 cdinfo(CD_OPEN
, "drive_status=%d\n", ret
);
432 if (ret
== CDS_TRAY_OPEN
) {
433 cdinfo(CD_OPEN
, "the tray is open...\n");
434 /* can/may i close it? */
435 if (cdo
->capability
& ~cdi
->mask
& CDC_CLOSE_TRAY
&&
436 cdi
->options
& CDO_AUTO_CLOSE
) {
437 cdinfo(CD_OPEN
, "trying to close the tray.\n");
438 ret
=cdo
->tray_move(cdi
,0);
440 cdinfo(CD_OPEN
, "bummer. tried to close tray but failed.\n");
441 /* Ignore the error from the low
442 level driver. We don't care why it
443 couldn't close the tray. We only care
444 that there is no disc in the drive,
445 since that is the _REAL_ problem here.*/
449 cdinfo(CD_OPEN
, "bummer. this driver can't close the tray.\n");
452 /* Ok, the door should be closed now.. Check again */
453 ret
= cdo
->drive_status(cdi
, CDSL_CURRENT
);
454 if ((ret
== CDS_NO_DISC
) || (ret
==CDS_TRAY_OPEN
)) {
455 cdinfo(CD_OPEN
, "bummer. the tray is still not closed.\n");
458 if (ret
!=CDS_DISC_OK
) {
459 cdinfo(CD_OPEN
, "bummer. disc isn't ready.\n");
462 cdinfo(CD_OPEN
, "the tray is now closed.\n");
465 cdrom_count_tracks(cdi
, &tracks
);
467 return(tracks
.error
);
476 /* Admittedly, the logic below could be performed in a nicer way. */
478 int cdrom_release(struct inode
*ip
, struct file
*fp
)
480 kdev_t dev
= ip
->i_rdev
;
481 struct cdrom_device_info
*cdi
= cdrom_find_device (dev
);
482 struct cdrom_device_ops
*cdo
= cdi
->ops
;
485 cdinfo(CD_CLOSE
, "entering cdrom_release\n");
488 if (cdi
->use_count
> 0) cdi
->use_count
--;
489 if (cdi
->use_count
== 0)
490 cdinfo(CD_CLOSE
, "Use count for \"/dev/%s\" now zero\n", cdi
->name
);
491 if (cdi
->use_count
== 0 && /* last process that closes dev*/
492 cdo
->capability
& CDC_LOCK
) {
493 cdinfo(CD_CLOSE
, "Unlocking door!\n");
494 cdo
->lock_door(cdi
, 0);
496 opened_for_data
= !(cdi
->options
& CDO_USE_FFLAGS
) ||
497 !(fp
&& fp
->f_flags
& O_NONBLOCK
);
499 if (cdi
->use_count
== 0) { /* last process that closes dev*/
501 invalidate_buffers(dev
);
502 if (opened_for_data
&&
503 cdi
->options
& CDO_AUTO_EJECT
&&
504 cdo
->capability
& ~cdi
->mask
& CDC_OPEN_TRAY
)
505 cdo
->tray_move(cdi
, 1);
510 /* We want to make media_changed accessible to the user through an
511 * ioctl. The main problem now is that we must double-buffer the
512 * low-level implementation, to assure that the VFS and the user both
513 * see a medium change once.
517 int media_changed(struct cdrom_device_info
*cdi
, int queue
)
519 unsigned int mask
= (1 << (queue
& 1));
520 int ret
= !!(cdi
->mc_flags
& mask
);
522 /* changed since last call? */
523 if (cdi
->ops
->media_changed(cdi
, CDSL_CURRENT
)) {
524 cdi
->mc_flags
= 0x3; /* set bit on both queues */
527 cdi
->mc_flags
&= ~mask
; /* clear bit */
532 int cdrom_media_changed(kdev_t dev
)
534 struct cdrom_device_info
*cdi
= cdrom_find_device (dev
);
537 if (cdi
->ops
->media_changed
== NULL
)
539 return media_changed(cdi
, 0);
543 void cdrom_count_tracks(struct cdrom_device_info
*cdi
, tracktype
* tracks
)
545 struct cdrom_tochdr header
;
546 struct cdrom_tocentry entry
;
553 cdinfo(CD_COUNT_TRACKS
, "entering cdrom_count_tracks\n");
554 if (!(cdi
->ops
->capability
& CDC_PLAY_AUDIO
)) {
555 tracks
->error
=CDS_NO_INFO
;
558 /* Grab the TOC header so we can see how many tracks there are */
559 ret
=cdi
->ops
->audio_ioctl(cdi
, CDROMREADTOCHDR
, &header
);
561 tracks
->error
=(ret
== -ENOMEDIUM
) ? CDS_NO_DISC
: CDS_NO_INFO
;
564 /* check what type of tracks are on this disc */
565 entry
.cdte_format
= CDROM_MSF
;
566 for (i
= header
.cdth_trk0
; i
<= header
.cdth_trk1
; i
++) {
567 entry
.cdte_track
= i
;
568 if (cdi
->ops
->audio_ioctl(cdi
, CDROMREADTOCENTRY
, &entry
)) {
569 tracks
->error
=CDS_NO_INFO
;
572 if (entry
.cdte_ctrl
& CDROM_DATA_TRACK
) {
573 if (entry
.cdte_format
== 0x10)
575 else if (entry
.cdte_format
== 0x20)
581 cdinfo(CD_COUNT_TRACKS
, "track %d: format=%d, ctrl=%d\n",
582 i
, entry
.cdte_format
, entry
.cdte_ctrl
);
584 cdinfo(CD_COUNT_TRACKS
, "disc has %d tracks: %d=audio %d=data %d=Cd-I %d=XA\n",
585 header
.cdth_trk1
, tracks
->audio
, tracks
->data
,
586 tracks
->cdi
, tracks
->xa
);
589 /* Requests to the low-level drivers will /always/ be done in the
590 following format convention:
592 CDROM_LBA: all data-related requests.
593 CDROM_MSF: all audio-related requests.
595 However, a low-level implementation is allowed to refuse this
596 request, and return information in its own favorite format.
598 It doesn't make sense /at all/ to ask for a play_audio in LBA
599 format, or ask for multi-session info in MSF format. However, for
600 backward compatibility these format requests will be satisfied, but
601 the requests to the low-level drivers will be sanitized in the more
602 meaningful format indicated above.
606 void sanitize_format(union cdrom_addr
*addr
,
607 u_char
* curr
, u_char requested
)
609 if (*curr
== requested
)
610 return; /* nothing to be done! */
611 if (requested
== CDROM_LBA
) {
612 addr
->lba
= (int) addr
->msf
.frame
+
613 75 * (addr
->msf
.second
- 2 + 60 * addr
->msf
.minute
);
614 } else { /* CDROM_MSF */
616 addr
->msf
.frame
= lba
% 75;
619 addr
->msf
.second
= lba
% 60;
620 addr
->msf
.minute
= lba
/ 60;
625 /* Some of the cdrom ioctls are not implemented here, because these
626 * appear to be either too device-specific, or it is not clear to me
627 * what use they are. These are (number of drivers that support them
628 * in parenthesis): CDROMREADMODE1 (2+ide), CDROMREADMODE2 (2+ide),
629 * CDROMREADAUDIO (2+ide), CDROMREADRAW (2), CDROMREADCOOKED (2),
630 * CDROMSEEK (2), CDROMPLAYBLK (scsi), CDROMREADALL (1). Read-audio,
631 * OK (although i guess the record companies aren't too happy with
632 * this, most drives therefore refuse to transport audio data). But
633 * why are there 5 different READs defined? For now, these functions
634 * are left over to the device-specific ioctl routine,
635 * cdo->dev_ioctl. Note that as a result of this, no
636 * memory-verification is performed for these ioctls.
639 int cdrom_ioctl(struct inode
*ip
, struct file
*fp
,
640 unsigned int cmd
, unsigned long arg
)
642 kdev_t dev
= ip
->i_rdev
;
643 struct cdrom_device_info
*cdi
= cdrom_find_device (dev
);
644 struct cdrom_device_ops
*cdo
;
650 /* the first few commands do not deal with audio drive_info, but
651 only with routines in cdrom device operations. */
653 /* maybe we should order cases after statistics of use? */
655 case CDROMMULTISESSION
: {
657 struct cdrom_multisession ms_info
;
658 u_char requested_format
;
659 cdinfo(CD_DO_IOCTL
, "entering CDROMMULTISESSION\n");
660 if (!(cdo
->capability
& CDC_MULTI_SESSION
))
662 IOCTL_IN(arg
, struct cdrom_multisession
, ms_info
);
663 requested_format
= ms_info
.addr_format
;
664 if (!((requested_format
== CDROM_MSF
) ||
665 (requested_format
== CDROM_LBA
)))
667 ms_info
.addr_format
= CDROM_LBA
;
668 if ((ret
=cdo
->get_last_session(cdi
, &ms_info
)))
670 sanitize_format(&ms_info
.addr
, &ms_info
.addr_format
,
672 IOCTL_OUT(arg
, struct cdrom_multisession
, ms_info
);
673 cdinfo(CD_DO_IOCTL
, "CDROMMULTISESSION sucessful\n");
679 cdinfo(CD_DO_IOCTL
, "entering CDROMEJECT\n");
680 if (!(cdo
->capability
& ~cdi
->mask
& CDC_OPEN_TRAY
))
682 if (cdi
->use_count
!= 1)
684 if (cdo
->capability
& ~cdi
->mask
& CDC_LOCK
) {
685 if ((ret
=cdo
->lock_door(cdi
, 0)))
688 return cdo
->tray_move(cdi
, 1);
692 cdinfo(CD_DO_IOCTL
, "entering CDROMCLOSETRAY\n");
693 if (!(cdo
->capability
& ~cdi
->mask
& CDC_OPEN_TRAY
))
695 return cdo
->tray_move(cdi
, 0);
698 cdinfo(CD_DO_IOCTL
, "entering CDROMEJECT_SW\n");
699 cdi
->options
&= ~(CDO_AUTO_CLOSE
| CDO_AUTO_EJECT
);
701 cdi
->options
|= CDO_AUTO_CLOSE
| CDO_AUTO_EJECT
;
704 case CDROM_MEDIA_CHANGED
: {
705 cdinfo(CD_DO_IOCTL
, "entering CDROM_MEDIA_CHANGED\n");
706 if (!(cdo
->capability
& ~cdi
->mask
& CDC_MEDIA_CHANGED
))
708 if (!(cdo
->capability
& ~cdi
->mask
& CDC_SELECT_DISC
)
709 || arg
== CDSL_CURRENT
)
710 /* cannot select disc or select current disc */
711 return media_changed(cdi
, 1);
712 if ((unsigned int)arg
>= cdi
->capacity
)
714 return cdo
->media_changed (cdi
, arg
);
717 case CDROM_SET_OPTIONS
:
718 cdinfo(CD_DO_IOCTL
, "entering CDROM_SET_OPTIONS\n");
719 cdi
->options
|= (int) arg
;
722 case CDROM_CLEAR_OPTIONS
:
723 cdinfo(CD_DO_IOCTL
, "entering CDROM_CLEAR_OPTIONS\n");
724 cdi
->options
&= ~(int) arg
;
727 case CDROM_SELECT_SPEED
: {
728 cdinfo(CD_DO_IOCTL
, "entering CDROM_SELECT_SPEED\n");
729 if (!(cdo
->capability
& ~cdi
->mask
& CDC_SELECT_SPEED
))
731 return cdo
->select_speed(cdi
, arg
);
734 case CDROM_SELECT_DISC
: {
735 cdinfo(CD_DO_IOCTL
, "entering CDROM_SELECT_DISC\n");
736 if (!(cdo
->capability
& ~cdi
->mask
& CDC_SELECT_DISC
))
738 if ((arg
== CDSL_CURRENT
) || (arg
== CDSL_NONE
))
739 return cdo
->select_disc(cdi
, arg
);
740 if ((int)arg
>= cdi
->capacity
)
741 return -EDRIVE_CANT_DO_THIS
;
742 return cdo
->select_disc(cdi
, arg
);
745 /* The following function is implemented, although very few audio
746 * discs give Universal Product Code information, which should just be
747 * the Medium Catalog Number on the box. Note, that the way the code
748 * is written on the CD is /not/ uniform across all discs!
750 case CDROM_GET_MCN
: {
752 struct cdrom_mcn mcn
;
753 cdinfo(CD_DO_IOCTL
, "entering CDROM_GET_MCN\n");
754 if (!(cdo
->capability
& CDC_MCN
))
756 if ((ret
=cdo
->get_mcn(cdi
, &mcn
)))
758 IOCTL_OUT(arg
, struct cdrom_mcn
, mcn
);
759 cdinfo(CD_DO_IOCTL
, "CDROM_GET_MCN sucessful\n");
763 case CDROM_DRIVE_STATUS
: {
764 cdinfo(CD_DO_IOCTL
, "entering CDROM_DRIVE_STATUS\n");
765 if (!(cdo
->capability
& CDC_DRIVE_STATUS
))
767 if ((arg
== CDSL_CURRENT
) || (arg
== CDSL_NONE
))
768 return cdo
->drive_status(cdi
, arg
);
769 if (((int)arg
> cdi
->capacity
))
771 return cdo
->drive_status(cdi
, arg
);
774 /* Ok, this is where problems start. The current interface for the
775 CDROM_DISC_STATUS ioctl is flawed. It makes the false assumption
776 that CDs are all CDS_DATA_1 or all CDS_AUDIO, etc. Unfortunatly,
777 while this is often the case, it is also very common for CDs to
778 have some tracks with data, and some tracks with audio. Just
779 because I feel like it, I declare the following to be the best
780 way to cope. If the CD has ANY data tracks on it, it will be
781 returned as a data CD. If it has any XA tracks, I will return
782 it as that. Now I could simplify this interface by combining these
783 returns with the above, but this more clearly demonstrates
784 the problem with the current interface. Too bad this wasn't
785 designed to use bitmasks... -Erik
787 Well, now we have the option CDS_MIXED: a mixed-type CD.
788 User level programmers might feel the ioctl is not very useful.
791 case CDROM_DISC_STATUS
: {
793 cdinfo(CD_DO_IOCTL
, "entering CDROM_DISC_STATUS\n");
794 cdrom_count_tracks(cdi
, &tracks
);
796 return(tracks
.error
);
799 if (tracks
.audio
> 0) {
800 if (tracks
.data
==0 && tracks
.cdi
==0 && tracks
.xa
==0)
802 else return CDS_MIXED
;
804 if (tracks
.cdi
> 0) return CDS_XA_2_2
;
805 if (tracks
.xa
> 0) return CDS_XA_2_1
;
806 if (tracks
.data
> 0) return CDS_DATA_1
;
807 /* Policy mode off */
809 cdinfo(CD_WARNING
,"This disc doesn't have any tracks I recognise!\n");
813 case CDROM_CHANGER_NSLOTS
:
814 cdinfo(CD_DO_IOCTL
, "entering CDROM_CHANGER_NSLOTS\n");
815 return cdi
->capacity
;
817 /* The following is not implemented, because there are too many
818 * different data types. We could support /1/ raw mode, that is large
819 * enough to hold everything.
823 case CDROMREADMODE1
: {
825 struct cdrom_msf msf
;
826 char buf
[CD_FRAMESIZE
];
827 cdinfo(CD_DO_IOCTL
, "entering CDROMREADMODE1\n");
828 IOCTL_IN(arg
, struct cdrom_msf
, msf
);
829 if (ret
=cdo
->read_audio(dev
, cmd
, &msf
, &buf
, cdi
))
831 IOCTL_OUT(arg
, __typeof__(buf
), buf
);
837 /* Now all the audio-ioctls follow, they are all routed through the
838 same call audio_ioctl(). */
840 #define CHECKAUDIO if ((ret=check_for_audio_disc(cdi, cdo))) return ret
842 if (!(cdo
->capability
& CDC_PLAY_AUDIO
))
848 struct cdrom_subchnl q
;
849 u_char requested
, back
;
850 /* comment out the cdinfo calls here because they
851 fill up the sys logs when CD players poll the drive*/
852 /* cdinfo(CD_DO_IOCTL,"entering CDROMSUBCHNL\n");*/
853 IOCTL_IN(arg
, struct cdrom_subchnl
, q
);
854 requested
= q
.cdsc_format
;
855 if (!((requested
== CDROM_MSF
) ||
856 (requested
== CDROM_LBA
)))
858 q
.cdsc_format
= CDROM_MSF
;
859 if ((ret
=cdo
->audio_ioctl(cdi
, cmd
, &q
)))
861 back
= q
.cdsc_format
; /* local copy */
862 sanitize_format(&q
.cdsc_absaddr
, &back
, requested
);
863 sanitize_format(&q
.cdsc_reladdr
, &q
.cdsc_format
, requested
);
864 IOCTL_OUT(arg
, struct cdrom_subchnl
, q
);
865 /* cdinfo(CD_DO_IOCTL, "CDROMSUBCHNL sucessful\n"); */
868 case CDROMREADTOCHDR
: {
870 struct cdrom_tochdr header
;
871 /* comment out the cdinfo calls here because they
872 fill up the sys logs when CD players poll the drive*/
873 /* cdinfo(CD_DO_IOCTL, "entering CDROMREADTOCHDR\n"); */
874 IOCTL_IN(arg
, struct cdrom_tochdr
, header
);
875 if ((ret
=cdo
->audio_ioctl(cdi
, cmd
, &header
)))
877 IOCTL_OUT(arg
, struct cdrom_tochdr
, header
);
878 /* cdinfo(CD_DO_IOCTL, "CDROMREADTOCHDR sucessful\n"); */
881 case CDROMREADTOCENTRY
: {
883 struct cdrom_tocentry entry
;
884 u_char requested_format
;
885 /* comment out the cdinfo calls here because they
886 fill up the sys logs when CD players poll the drive*/
887 /* cdinfo(CD_DO_IOCTL, "entering CDROMREADTOCENTRY\n"); */
888 IOCTL_IN(arg
, struct cdrom_tocentry
, entry
);
889 requested_format
= entry
.cdte_format
;
890 if (!((requested_format
== CDROM_MSF
) ||
891 (requested_format
== CDROM_LBA
)))
893 /* make interface to low-level uniform */
894 entry
.cdte_format
= CDROM_MSF
;
895 if ((ret
=cdo
->audio_ioctl(cdi
, cmd
, &entry
)))
897 sanitize_format(&entry
.cdte_addr
,
898 &entry
.cdte_format
, requested_format
);
899 IOCTL_OUT(arg
, struct cdrom_tocentry
, entry
);
900 /* cdinfo(CD_DO_IOCTL, "CDROMREADTOCENTRY sucessful\n"); */
905 struct cdrom_msf msf
;
906 cdinfo(CD_DO_IOCTL
, "entering CDROMPLAYMSF\n");
907 IOCTL_IN(arg
, struct cdrom_msf
, msf
);
909 return cdo
->audio_ioctl(cdi
, cmd
, &msf
);
911 case CDROMPLAYTRKIND
: {
914 cdinfo(CD_DO_IOCTL
, "entering CDROMPLAYTRKIND\n");
915 IOCTL_IN(arg
, struct cdrom_ti
, ti
);
917 return cdo
->audio_ioctl(cdi
, cmd
, &ti
);
920 struct cdrom_volctrl volume
;
921 cdinfo(CD_DO_IOCTL
, "entering CDROMVOLCTRL\n");
922 IOCTL_IN(arg
, struct cdrom_volctrl
, volume
);
923 return cdo
->audio_ioctl(cdi
, cmd
, &volume
);
927 struct cdrom_volctrl volume
;
928 cdinfo(CD_DO_IOCTL
, "entering CDROMVOLREAD\n");
929 if ((ret
=cdo
->audio_ioctl(cdi
, cmd
, &volume
)))
931 IOCTL_OUT(arg
, struct cdrom_volctrl
, volume
);
939 cdinfo(CD_DO_IOCTL
, "doing audio ioctl (start/stop/pause/resume)\n");
941 return cdo
->audio_ioctl(cdi
, cmd
, NULL
);
946 /* device specific ioctls? */
947 if (!(cdo
->capability
& CDC_IOCTLS
))
950 return cdo
->dev_ioctl(cdi
, cmd
, arg
);
953 EXPORT_SYMBOL(register_cdrom
);
954 EXPORT_SYMBOL(unregister_cdrom
);
955 EXPORT_SYMBOL(cdrom_fops
);
959 #define CDROM_STR_SIZE 1000
961 static char cdrom_drive_info
[CDROM_STR_SIZE
]="info\n";
963 int cdrom_sysctl_info(ctl_table
*ctl
, int write
, struct file
* filp
,
964 void *buffer
, size_t *lenp
)
967 struct cdrom_device_info
*cdi
;
969 pos
= sprintf(cdrom_drive_info
, "CD-ROM information\n");
971 pos
+= sprintf(cdrom_drive_info
+pos
, "\ndrive name:\t");
972 for (cdi
=topCdromPtr
;cdi
!=NULL
;cdi
=cdi
->next
)
973 pos
+= sprintf(cdrom_drive_info
+pos
, "\t%s", cdi
->name
);
975 pos
+= sprintf(cdrom_drive_info
+pos
, "\ndrive speed:\t");
976 for (cdi
=topCdromPtr
;cdi
!=NULL
;cdi
=cdi
->next
)
977 pos
+= sprintf(cdrom_drive_info
+pos
, "\t%d", cdi
->speed
);
979 pos
+= sprintf(cdrom_drive_info
+pos
, "\ndrive # of slots:");
980 for (cdi
=topCdromPtr
;cdi
!=NULL
;cdi
=cdi
->next
)
981 pos
+= sprintf(cdrom_drive_info
+pos
, "\t%d", cdi
->capacity
);
983 pos
+= sprintf(cdrom_drive_info
+pos
, "\nCan close tray:\t");
984 for (cdi
=topCdromPtr
;cdi
!=NULL
;cdi
=cdi
->next
)
985 pos
+= sprintf(cdrom_drive_info
+pos
, "\t%d",
986 ((cdi
->ops
->capability
& CDC_CLOSE_TRAY
)!=0));
988 pos
+= sprintf(cdrom_drive_info
+pos
, "\nCan open tray:\t");
989 for (cdi
=topCdromPtr
;cdi
!=NULL
;cdi
=cdi
->next
)
990 pos
+= sprintf(cdrom_drive_info
+pos
, "\t%d",
991 ((cdi
->ops
->capability
& CDC_OPEN_TRAY
)!=0));
993 pos
+= sprintf(cdrom_drive_info
+pos
, "\nCan lock tray:\t");
994 for (cdi
=topCdromPtr
;cdi
!=NULL
;cdi
=cdi
->next
)
995 pos
+= sprintf(cdrom_drive_info
+pos
, "\t%d",
996 ((cdi
->ops
->capability
& CDC_LOCK
)!=0));
998 pos
+= sprintf(cdrom_drive_info
+pos
, "\nCan change speed:");
999 for (cdi
=topCdromPtr
;cdi
!=NULL
;cdi
=cdi
->next
)
1000 pos
+= sprintf(cdrom_drive_info
+pos
, "\t%d",
1001 ((cdi
->ops
->capability
& CDC_SELECT_SPEED
)!=0));
1003 pos
+= sprintf(cdrom_drive_info
+pos
, "\nCan select disk:");
1004 for (cdi
=topCdromPtr
;cdi
!=NULL
;cdi
=cdi
->next
)
1005 pos
+= sprintf(cdrom_drive_info
+pos
, "\t%d",
1006 ((cdi
->ops
->capability
& CDC_SELECT_DISC
)!=0));
1008 pos
+= sprintf(cdrom_drive_info
+pos
, "\nCan read multisession:");
1009 for (cdi
=topCdromPtr
;cdi
!=NULL
;cdi
=cdi
->next
)
1010 pos
+= sprintf(cdrom_drive_info
+pos
, "\t%d",
1011 ((cdi
->ops
->capability
& CDC_MULTI_SESSION
)!=0));
1013 pos
+= sprintf(cdrom_drive_info
+pos
, "\nCan read MCN:\t");
1014 for (cdi
=topCdromPtr
;cdi
!=NULL
;cdi
=cdi
->next
)
1015 pos
+= sprintf(cdrom_drive_info
+pos
, "\t%d",
1016 ((cdi
->ops
->capability
& CDC_MCN
)!=0));
1018 pos
+= sprintf(cdrom_drive_info
+pos
, "\nReports media changed:");
1019 for (cdi
=topCdromPtr
;cdi
!=NULL
;cdi
=cdi
->next
)
1020 pos
+= sprintf(cdrom_drive_info
+pos
, "\t%d",
1021 ((cdi
->ops
->capability
& CDC_MEDIA_CHANGED
)!=0));
1023 pos
+= sprintf(cdrom_drive_info
+pos
, "\nCan play audio:\t");
1024 for (cdi
=topCdromPtr
;cdi
!=NULL
;cdi
=cdi
->next
)
1025 pos
+= sprintf(cdrom_drive_info
+pos
, "\t%d",
1026 ((cdi
->ops
->capability
& CDC_PLAY_AUDIO
)!=0));
1028 strcpy(cdrom_drive_info
+pos
,"\n\n");
1031 retv
= proc_dostring(ctl
, write
, filp
, buffer
, lenp
);
1034 retv
= proc_dostring(ctl
, write
, filp
, buffer
, lenp
);
1038 /* Place files in /proc/sys/dev/cdrom */
1039 ctl_table cdrom_table
[] = {
1040 {DEV_CDROM_INFO
, "info", &cdrom_drive_info
,
1041 CDROM_STR_SIZE
*sizeof(char), 0444, NULL
, &cdrom_sysctl_info
},
1045 ctl_table cdrom_cdrom_table
[] = {
1046 {DEV_CDROM
, "cdrom", NULL
, 0, 0555, cdrom_table
},
1050 /* Make sure that /proc/sys/dev is there */
1051 ctl_table cdrom_root_table
[] = {
1052 {CTL_DEV
, "dev", NULL
, 0, 0555, cdrom_cdrom_table
},
1056 static struct ctl_table_header
*cdrom_sysctl_header
;
1059 * This is called as the fill_inode function when an inode
1060 * is going into (fill = 1) or out of service (fill = 0).
1061 * We use it here to manage the module use counts.
1063 * Note: only the top-level directory needs to do this; if
1064 * a lower level is referenced, the parent will be as well.
1066 static void cdrom_procfs_modcount(struct inode
*inode
, int fill
)
1074 static void cdrom_sysctl_register(void)
1076 static int initialized
= 0;
1078 if ( initialized
== 1 )
1080 cdrom_sysctl_header
= register_sysctl_table(cdrom_root_table
, 0);
1081 cdrom_root_table
->de
->fill_inode
= &cdrom_procfs_modcount
;
1086 static void cdrom_sysctl_unregister(void)
1088 unregister_sysctl_table(cdrom_sysctl_header
);
1090 #endif /* endif MODULE */
1091 #endif /* endif CONFIG_SYSCTL */
1095 int init_module(void)
1097 #ifdef CONFIG_SYSCTL
1098 cdrom_sysctl_register();
1099 #endif /* CONFIG_SYSCTL */
1103 void cleanup_module(void)
1105 printk(KERN_INFO
"Uniform CD-ROM driver unloaded\n");
1106 #ifdef CONFIG_SYSCTL
1107 cdrom_sysctl_unregister();
1108 #endif /* CONFIG_SYSCTL */
1111 #endif /* endif MODULE */
1117 * comment-column: 40
1118 * compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/include -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -pipe -fno-strength-reduce -m486 -DCPU=486 -DMODULE -DMODVERSIONS -include /usr/src/linux/include/linux/modversions.h -c -o cdrom.o cdrom.c"