Import 2.1.118
[davej-history.git] / drivers / cdrom / cdrom.c
blobaf5fb70219af96be8dd4dc1512fbb87fbb77bee5
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. ;-)
16 To Do List:
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.
30 Revision History
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
56 problem).
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
94 #define CD_OPEN 0x8
95 #define CD_CLOSE 0x10
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)
138 #else
139 #define cdinfo(type, fmt, args...)
140 #endif
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) ) \
145 return -EFAULT; }
147 #define IOCTL_OUT(arg, type, out) { \
148 if ( copy_to_user((type *) arg, &out, sizeof out) ) \
149 return -EFAULT; }
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);
166 typedef struct {
167 int data;
168 int audio;
169 int cdi;
170 int xa;
171 long error;
172 } tracktype;
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 =
179 NULL, /* lseek */
180 block_read, /* read - general block-dev read */
181 block_write, /* write - general block-dev write */
182 NULL, /* readdir */
183 NULL, /* poll */
184 cdrom_ioctl, /* ioctl */
185 NULL, /* mmap */
186 cdrom_open, /* open */
187 NULL, /* flush */
188 cdrom_release, /* release */
189 NULL, /* fsync */
190 NULL, /* fasync */
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)
210 return -1;
211 if (cdo->open == NULL || cdo->release == NULL)
212 return -2;
213 if ( !banner_printed ) {
214 printk(KERN_INFO "Uniform CDROM driver " REVISION "\n");
215 banner_printed = 1;
216 #ifdef CONFIG_SYSCTL
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);
231 cdi->mc_flags = 0;
232 cdo->n_minors = 0;
233 cdi->options = CDO_USE_FFLAGS;
234 if (autoclose==1)
235 cdi->options |= (int) CDO_AUTO_CLOSE;
236 if (autoeject==1)
237 cdi->options |= (int) CDO_AUTO_EJECT;
238 if (lockdoor==1)
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;
245 topCdromPtr = cdi;
246 return 0;
248 #undef ENSURE
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)
256 return -1;
258 prev = NULL;
259 cdi = topCdromPtr;
260 while (cdi != NULL && cdi->dev != unreg->dev) {
261 prev = cdi;
262 cdi = cdi->next;
265 if (cdi == NULL)
266 return -2;
267 if (prev)
268 prev->next = cdi->next;
269 else
270 topCdromPtr = cdi->next;
271 cdi->ops->n_minors--;
272 cdinfo(CD_REG_UNREG, "drive \"/dev/%s\" unregistered\n", cdi->name);
273 return 0;
276 static
277 struct cdrom_device_info *cdrom_find_device (kdev_t dev)
279 struct cdrom_device_info *cdi;
281 cdi = topCdromPtr;
282 while (cdi != NULL && cdi->dev != dev)
283 cdi = cdi->next;
284 return cdi;
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
293 * this way.
295 static
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);
301 int ret=0;
303 cdinfo(CD_OPEN, "entering cdrom_open\n");
304 if (cdi == NULL)
305 return -ENODEV;
306 if (fp->f_mode & FM_WRITE)
307 return -EROFS;
308 purpose = purpose || !(cdi->options & CDO_USE_FFLAGS);
309 if (cdi->use_count || purpose)
310 ret = cdi->ops->open(cdi, purpose);
311 else
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);
315 return ret;
318 static
319 int open_for_data(struct cdrom_device_info * cdi)
321 int ret;
322 struct cdrom_device_ops *cdo = cdi->ops;
323 tracktype tracks;
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);
337 if (ret) {
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.*/
344 ret=-ENOMEDIUM;
345 goto clean_up_and_return;
347 } else {
348 cdinfo(CD_OPEN, "bummer. this driver can't close the tray.\n");
349 ret=-ENOMEDIUM;
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");
356 ret=-ENOMEDIUM;
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");
367 ret=-ENOMEDIUM;
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");
375 ret=-EMEDIUMTYPE;
376 goto clean_up_and_return;
378 else {
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... */
391 if (ret) {
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");
401 return ret;
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. */
408 clean_up_and_return:
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");
415 return ret;
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)
424 int ret;
425 tracktype tracks;
426 cdinfo(CD_OPEN, "entering check_for_audio_disc\n");
427 if (!(cdi->options & CDO_CHECK_TYPE))
428 return 0;
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);
439 if (ret) {
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.*/
446 return -ENOMEDIUM;
448 } else {
449 cdinfo(CD_OPEN, "bummer. this driver can't close the tray.\n");
450 return -ENOMEDIUM;
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");
456 return -ENOMEDIUM;
458 if (ret!=CDS_DISC_OK) {
459 cdinfo(CD_OPEN, "bummer. disc isn't ready.\n");
460 return -EIO;
462 cdinfo(CD_OPEN, "the tray is now closed.\n");
465 cdrom_count_tracks(cdi, &tracks);
466 if (tracks.error)
467 return(tracks.error);
469 if (tracks.audio==0)
470 return -EMEDIUMTYPE;
472 return 0;
476 /* Admittedly, the logic below could be performed in a nicer way. */
477 static
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;
483 int opened_for_data;
485 cdinfo(CD_CLOSE, "entering cdrom_release\n");
486 if (cdi == NULL)
487 return 0;
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);
498 cdo->release(cdi);
499 if (cdi->use_count == 0) { /* last process that closes dev*/
500 sync_dev(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);
507 return 0;
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.
516 static
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 */
525 ret |= 1;
527 cdi->mc_flags &= ~mask; /* clear bit */
528 return ret;
531 static
532 int cdrom_media_changed(kdev_t dev)
534 struct cdrom_device_info *cdi = cdrom_find_device (dev);
535 if (cdi == NULL)
536 return -ENODEV;
537 if (cdi->ops->media_changed == NULL)
538 return -ENOSYS;
539 return media_changed(cdi, 0);
542 static
543 void cdrom_count_tracks(struct cdrom_device_info *cdi, tracktype* tracks)
545 struct cdrom_tochdr header;
546 struct cdrom_tocentry entry;
547 int ret, i;
548 tracks->data=0;
549 tracks->audio=0;
550 tracks->cdi=0;
551 tracks->xa=0;
552 tracks->error=0;
553 cdinfo(CD_COUNT_TRACKS, "entering cdrom_count_tracks\n");
554 if (!(cdi->ops->capability & CDC_PLAY_AUDIO)) {
555 tracks->error=CDS_NO_INFO;
556 return;
558 /* Grab the TOC header so we can see how many tracks there are */
559 ret=cdi->ops->audio_ioctl(cdi, CDROMREADTOCHDR, &header);
560 if (ret) {
561 tracks->error=(ret == -ENOMEDIUM) ? CDS_NO_DISC : CDS_NO_INFO;
562 return;
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;
570 return;
572 if (entry.cdte_ctrl & CDROM_DATA_TRACK) {
573 if (entry.cdte_format == 0x10)
574 tracks->cdi++;
575 else if (entry.cdte_format == 0x20)
576 tracks->xa++;
577 else
578 tracks->data++;
579 } else
580 tracks->audio++;
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.
605 static
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 */
615 int lba = addr->lba;
616 addr->msf.frame = lba % 75;
617 lba /= 75;
618 lba += 2;
619 addr->msf.second = lba % 60;
620 addr->msf.minute = lba / 60;
622 *curr = requested;
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.
638 static
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;
646 if (cdi == NULL)
647 return -ENODEV;
648 cdo = cdi->ops;
650 /* the first few commands do not deal with audio drive_info, but
651 only with routines in cdrom device operations. */
652 switch (cmd) {
653 /* maybe we should order cases after statistics of use? */
655 case CDROMMULTISESSION: {
656 int ret;
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))
661 return -ENOSYS;
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)))
666 return -EINVAL;
667 ms_info.addr_format = CDROM_LBA;
668 if ((ret=cdo->get_last_session(cdi, &ms_info)))
669 return ret;
670 sanitize_format(&ms_info.addr, &ms_info.addr_format,
671 requested_format);
672 IOCTL_OUT(arg, struct cdrom_multisession, ms_info);
673 cdinfo(CD_DO_IOCTL, "CDROMMULTISESSION sucessful\n");
674 return 0;
677 case CDROMEJECT: {
678 int ret;
679 cdinfo(CD_DO_IOCTL, "entering CDROMEJECT\n");
680 if (!(cdo->capability & ~cdi->mask & CDC_OPEN_TRAY))
681 return -ENOSYS;
682 if (cdi->use_count != 1)
683 return -EBUSY;
684 if (cdo->capability & ~cdi->mask & CDC_LOCK) {
685 if ((ret=cdo->lock_door(cdi, 0)))
686 return ret;
688 return cdo->tray_move(cdi, 1);
691 case CDROMCLOSETRAY:
692 cdinfo(CD_DO_IOCTL, "entering CDROMCLOSETRAY\n");
693 if (!(cdo->capability & ~cdi->mask & CDC_OPEN_TRAY))
694 return -ENOSYS;
695 return cdo->tray_move(cdi, 0);
697 case CDROMEJECT_SW:
698 cdinfo(CD_DO_IOCTL, "entering CDROMEJECT_SW\n");
699 cdi->options &= ~(CDO_AUTO_CLOSE | CDO_AUTO_EJECT);
700 if (arg)
701 cdi->options |= CDO_AUTO_CLOSE | CDO_AUTO_EJECT;
702 return 0;
704 case CDROM_MEDIA_CHANGED: {
705 cdinfo(CD_DO_IOCTL, "entering CDROM_MEDIA_CHANGED\n");
706 if (!(cdo->capability & ~cdi->mask & CDC_MEDIA_CHANGED))
707 return -ENOSYS;
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)
713 return -EINVAL;
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;
720 return cdi->options;
722 case CDROM_CLEAR_OPTIONS:
723 cdinfo(CD_DO_IOCTL, "entering CDROM_CLEAR_OPTIONS\n");
724 cdi->options &= ~(int) arg;
725 return cdi->options;
727 case CDROM_SELECT_SPEED: {
728 cdinfo(CD_DO_IOCTL, "entering CDROM_SELECT_SPEED\n");
729 if (!(cdo->capability & ~cdi->mask & CDC_SELECT_SPEED))
730 return -ENOSYS;
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))
737 return -ENOSYS;
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: {
751 int ret;
752 struct cdrom_mcn mcn;
753 cdinfo(CD_DO_IOCTL, "entering CDROM_GET_MCN\n");
754 if (!(cdo->capability & CDC_MCN))
755 return -ENOSYS;
756 if ((ret=cdo->get_mcn(cdi, &mcn)))
757 return ret;
758 IOCTL_OUT(arg, struct cdrom_mcn, mcn);
759 cdinfo(CD_DO_IOCTL, "CDROM_GET_MCN sucessful\n");
760 return 0;
763 case CDROM_DRIVE_STATUS: {
764 cdinfo(CD_DO_IOCTL, "entering CDROM_DRIVE_STATUS\n");
765 if (!(cdo->capability & CDC_DRIVE_STATUS))
766 return -ENOSYS;
767 if ((arg == CDSL_CURRENT) || (arg == CDSL_NONE))
768 return cdo->drive_status(cdi, arg);
769 if (((int)arg > cdi->capacity))
770 return -EINVAL;
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.
789 ---david
791 case CDROM_DISC_STATUS: {
792 tracktype tracks;
793 cdinfo(CD_DO_IOCTL, "entering CDROM_DISC_STATUS\n");
794 cdrom_count_tracks(cdi, &tracks);
795 if (tracks.error)
796 return(tracks.error);
798 /* Policy mode on */
799 if (tracks.audio > 0) {
800 if (tracks.data==0 && tracks.cdi==0 && tracks.xa==0)
801 return CDS_AUDIO;
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");
810 return CDS_NO_INFO;
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.
822 #if 0
823 case CDROMREADMODE1: {
824 int ret;
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))
830 return ret;
831 IOCTL_OUT(arg, __typeof__(buf), buf);
832 return 0;
834 #endif
835 } /* switch */
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))
843 return -ENOSYS;
844 else {
845 switch (cmd) {
846 case CDROMSUBCHNL: {
847 int ret;
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)))
857 return -EINVAL;
858 q.cdsc_format = CDROM_MSF;
859 if ((ret=cdo->audio_ioctl(cdi, cmd, &q)))
860 return ret;
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"); */
866 return 0;
868 case CDROMREADTOCHDR: {
869 int ret;
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)))
876 return ret;
877 IOCTL_OUT(arg, struct cdrom_tochdr, header);
878 /* cdinfo(CD_DO_IOCTL, "CDROMREADTOCHDR sucessful\n"); */
879 return 0;
881 case CDROMREADTOCENTRY: {
882 int ret;
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)))
892 return -EINVAL;
893 /* make interface to low-level uniform */
894 entry.cdte_format = CDROM_MSF;
895 if ((ret=cdo->audio_ioctl(cdi, cmd, &entry)))
896 return ret;
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"); */
901 return 0;
903 case CDROMPLAYMSF: {
904 int ret;
905 struct cdrom_msf msf;
906 cdinfo(CD_DO_IOCTL, "entering CDROMPLAYMSF\n");
907 IOCTL_IN(arg, struct cdrom_msf, msf);
908 CHECKAUDIO;
909 return cdo->audio_ioctl(cdi, cmd, &msf);
911 case CDROMPLAYTRKIND: {
912 int ret;
913 struct cdrom_ti ti;
914 cdinfo(CD_DO_IOCTL, "entering CDROMPLAYTRKIND\n");
915 IOCTL_IN(arg, struct cdrom_ti, ti);
916 CHECKAUDIO;
917 return cdo->audio_ioctl(cdi, cmd, &ti);
919 case CDROMVOLCTRL: {
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);
925 case CDROMVOLREAD: {
926 int ret;
927 struct cdrom_volctrl volume;
928 cdinfo(CD_DO_IOCTL, "entering CDROMVOLREAD\n");
929 if ((ret=cdo->audio_ioctl(cdi, cmd, &volume)))
930 return ret;
931 IOCTL_OUT(arg, struct cdrom_volctrl, volume);
932 return 0;
934 case CDROMSTART:
935 case CDROMSTOP:
936 case CDROMPAUSE:
937 case CDROMRESUME: {
938 int ret;
939 cdinfo(CD_DO_IOCTL, "doing audio ioctl (start/stop/pause/resume)\n");
940 CHECKAUDIO;
941 return cdo->audio_ioctl(cdi, cmd, NULL);
943 } /* switch */
946 /* device specific ioctls? */
947 if (!(cdo->capability & CDC_IOCTLS))
948 return -ENOSYS;
949 else
950 return cdo->dev_ioctl(cdi, cmd, arg);
953 EXPORT_SYMBOL(register_cdrom);
954 EXPORT_SYMBOL(unregister_cdrom);
955 EXPORT_SYMBOL(cdrom_fops);
957 #ifdef CONFIG_SYSCTL
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)
966 int retv,pos;
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");
1029 *lenp=pos+3;
1030 if (!write) {
1031 retv = proc_dostring(ctl, write, filp, buffer, lenp);
1033 else
1034 retv = proc_dostring(ctl, write, filp, buffer, lenp);
1035 return retv;
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)
1068 if (fill)
1069 MOD_INC_USE_COUNT;
1070 else
1071 MOD_DEC_USE_COUNT;
1074 static void cdrom_sysctl_register(void)
1076 static int initialized = 0;
1078 if ( initialized == 1 )
1079 return;
1080 cdrom_sysctl_header = register_sysctl_table(cdrom_root_table, 0);
1081 cdrom_root_table->de->fill_inode = &cdrom_procfs_modcount;
1082 initialized = 1;
1085 #ifdef MODULE
1086 static void cdrom_sysctl_unregister(void)
1088 unregister_sysctl_table(cdrom_sysctl_header);
1090 #endif /* endif MODULE */
1091 #endif /* endif CONFIG_SYSCTL */
1093 #ifdef MODULE
1095 int init_module(void)
1097 #ifdef CONFIG_SYSCTL
1098 cdrom_sysctl_register();
1099 #endif /* CONFIG_SYSCTL */
1100 return 0;
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 */
1116 * Local variables:
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"
1119 * End: