patch-2.2.4 linux/drivers/cdrom/cdrom.c
Next file: linux/drivers/cdrom/cm206.c
Previous file: linux/drivers/block/swim3.c
Back to the patch index
Back to the overall index
- Lines: 225
- Date:
Sun Mar 21 18:37:56 1999
- Orig file:
v2.2.3/linux/drivers/cdrom/cdrom.c
- Orig date:
Tue Jan 19 11:32:51 1999
diff -u --recursive --new-file v2.2.3/linux/drivers/cdrom/cdrom.c linux/drivers/cdrom/cdrom.c
@@ -24,8 +24,9 @@
-- Change the CDROMREADMODE1, CDROMREADMODE2, CDROMREADAUDIO, and
CDROMREADRAW ioctls so they go through the Uniform CD-ROM driver.
-
-
+
+ -- Sync options and capability flags.
+
Revision History
@@ -97,17 +98,33 @@
cdi->options in various ioctl.
-- Added version to proc entry.
- 2.52 Jan 16, 1998 - Jens Axboe <axboe@image.dk>
+ 2.52 Jan 16, 1999 - Jens Axboe <axboe@image.dk>
-- Fixed an error in open_for_data where we would sometimes not return
the correct error value. Thanks Huba Gaspar <huba@softcell.hu>.
-- Fixed module usage count - usage was based on /proc/sys/dev
instead of /proc/sys/dev/cdrom. This could lead to an oops when other
- modules had entries in dev.
+ modules had entries in dev. Feb 02 - real bug was in sysctl.c where
+ dev would be removed even though it was used. cdrom.c just illuminated
+ that bug.
+
+ 2.53 Feb 22, 1999 - Jens Axboe <axboe@image.dk>
+ -- Fixup of several ioctl calls, in particular CDROM_SET_OPTIONS has
+ been "rewritten" because capabilities and options aren't in sync. They
+ should be...
+ -- Added CDROM_LOCKDOOR ioctl. Locks the door and keeps it that way.
+ -- Added CDROM_RESET ioctl.
+ -- Added CDROM_DEBUG ioctl. Enable debug messages on-the-fly.
+ -- Added CDROM_GET_CAPABILITY ioctl. This relieves userspace programs
+ from parsing /proc/sys/dev/cdrom/info.
+
+ 2.54 Mar 15, 1999 - Jens Axboe <axboe@image.dk>
+ -- Check capability mask from low level driver when counting tracks as
+ per suggestion from Corey J. Scotts <cstotts@blue.weeg.uiowa.edu>.
-------------------------------------------------------------------------*/
-#define REVISION "Revision: 2.52"
-#define VERSION "Id: cdrom.c 2.52 1999/01/16"
+#define REVISION "Revision: 2.54"
+#define VERSION "Id: cdrom.c 2.54 1999/03/15"
/* I use an error-log mask to give fine grain control over the type of
messages dumped to the system logs. The available masks include: */
@@ -144,6 +161,8 @@
/* used to tell the module to turn on full debugging messages */
static int debug = 0;
+/* used to keep tray locked at all times */
+static int keeplocked = 0;
/* default compatibility mode */
static int autoclose=1;
static int autoeject=0;
@@ -164,13 +183,11 @@
#endif
/* These are used to simplify getting data in from and back to user land */
-#define IOCTL_IN(arg, type, in) { \
- if ( copy_from_user(&in, (type *) arg, sizeof in) ) \
- return -EFAULT; }
-
-#define IOCTL_OUT(arg, type, out) { \
- if ( copy_to_user((type *) arg, &out, sizeof out) ) \
- return -EFAULT; }
+#define IOCTL_IN(arg, type, in) \
+ copy_from_user_ret(&in, (type *) arg, sizeof in, -EFAULT)
+
+#define IOCTL_OUT(arg, type, out) \
+ copy_to_user_ret((type *) arg, &out, sizeof out, -EFAULT)
#define FM_WRITE 0x2 /* file mode write bit */
@@ -328,7 +345,7 @@
if (fp->f_mode & FM_WRITE)
return -EROFS;
purpose = purpose || !(cdi->options & CDO_USE_FFLAGS);
- if (cdi->use_count || purpose)
+ if (purpose)
ret = cdi->ops->open(cdi, purpose);
else
ret = open_for_data(cdi);
@@ -517,10 +534,10 @@
if (cdi->use_count == 0)
cdinfo(CD_CLOSE, "Use count for \"/dev/%s\" now zero\n", cdi->name);
if (cdi->use_count == 0 && /* last process that closes dev*/
- cdo->capability & CDC_LOCK) {
+ cdo->capability & CDC_LOCK && !keeplocked) {
cdinfo(CD_CLOSE, "Unlocking door!\n");
cdo->lock_door(cdi, 0);
- }
+ }
opened_for_data = !(cdi->options & CDO_USE_FFLAGS) ||
!(fp && fp->f_flags & O_NONBLOCK);
cdo->release(cdi);
@@ -588,14 +605,17 @@
tracks->xa=0;
tracks->error=0;
cdinfo(CD_COUNT_TRACKS, "entering cdrom_count_tracks\n");
- if (!(cdi->ops->capability & CDC_PLAY_AUDIO)) {
+ if (!(cdi->ops->capability & ~cdi->mask & CDC_PLAY_AUDIO)) {
tracks->error=CDS_NO_INFO;
return;
}
/* Grab the TOC header so we can see how many tracks there are */
- ret=cdi->ops->audio_ioctl(cdi, CDROMREADTOCHDR, &header);
+ ret = cdi->ops->audio_ioctl(cdi, CDROMREADTOCHDR, &header);
if (ret) {
- tracks->error=(ret == -ENOMEDIUM) ? CDS_NO_DISC : CDS_NO_INFO;
+ if (ret == -ENOMEDIUM)
+ tracks->error = CDS_NO_DISC;
+ else
+ tracks->error = CDS_NO_INFO;
return;
}
/* check what type of tracks are on this disc */
@@ -716,18 +736,18 @@
cdinfo(CD_DO_IOCTL, "entering CDROMEJECT\n");
if (!(cdo->capability & ~cdi->mask & CDC_OPEN_TRAY))
return -ENOSYS;
- if (cdi->use_count != 1)
+ if (cdi->use_count != 1 || keeplocked)
return -EBUSY;
- if (cdo->capability & ~cdi->mask & CDC_LOCK) {
+ if (cdo->capability & ~cdi->mask & CDC_LOCK)
if ((ret=cdo->lock_door(cdi, 0)))
return ret;
- }
+
return cdo->tray_move(cdi, 1);
}
case CDROMCLOSETRAY:
cdinfo(CD_DO_IOCTL, "entering CDROMCLOSETRAY\n");
- if (!(cdo->capability & ~cdi->mask & CDC_OPEN_TRAY))
+ if (!(cdo->capability & ~cdi->mask & CDC_CLOSE_TRAY))
return -ENOSYS;
return cdo->tray_move(cdi, 0);
@@ -735,6 +755,8 @@
cdinfo(CD_DO_IOCTL, "entering CDROMEJECT_SW\n");
if (!(cdo->capability & ~cdi->mask & CDC_OPEN_TRAY))
return -ENOSYS;
+ if (keeplocked)
+ return -EBUSY;
cdi->options &= ~(CDO_AUTO_CLOSE | CDO_AUTO_EJECT);
if (arg)
cdi->options |= CDO_AUTO_CLOSE | CDO_AUTO_EJECT;
@@ -755,8 +777,23 @@
case CDROM_SET_OPTIONS:
cdinfo(CD_DO_IOCTL, "entering CDROM_SET_OPTIONS\n");
- if (cdo->capability & arg & ~cdi->mask)
- return -ENOSYS;
+ /* options need to be in sync with capability. too late for
+ that, so we have to check each one separately... */
+ switch (arg) {
+ case CDO_USE_FFLAGS:
+ case CDO_CHECK_TYPE:
+ break;
+ case CDO_LOCK:
+ if (!(cdo->capability & ~cdi->mask & CDC_LOCK))
+ return -ENOSYS;
+ break;
+ case 0:
+ return cdi->options;
+ /* default is basically CDO_[AUTO_CLOSE|AUTO_EJECT] */
+ default:
+ if (!(cdo->capability & ~cdi->mask & arg))
+ return -ENOSYS;
+ }
cdi->options |= (int) arg;
return cdi->options;
@@ -783,6 +820,36 @@
return cdo->select_disc(cdi, arg);
}
+ case CDROMRESET: {
+ cdinfo(CD_DO_IOCTL, "entering CDROM_RESET\n");
+ if (!(cdo->capability & ~cdi->mask & CDC_RESET))
+ return -ENOSYS;
+ return cdo->reset(cdi);
+ }
+
+ case CDROM_LOCKDOOR: {
+ cdinfo(CD_DO_IOCTL, "%socking door.\n",arg?"L":"Unl");
+ if (!(cdo->capability & ~cdi->mask & CDC_LOCK)) {
+ return -EDRIVE_CANT_DO_THIS;
+ } else {
+ keeplocked = arg ? 1 : 0;
+ return cdo->lock_door(cdi, arg);
+ }
+ }
+
+ case CDROM_DEBUG: {
+ if (!capable(CAP_SYS_ADMIN))
+ return -EACCES;
+ cdinfo(CD_DO_IOCTL, "%sabling debug.\n",arg?"En":"Dis");
+ debug = arg ? 1 : 0;
+ return debug;
+ }
+
+ case CDROM_GET_CAPABILITY: {
+ cdinfo(CD_DO_IOCTL, "entering CDROM_GET_CAPABILITY\n");
+ return cdo->capability;
+ }
+
/* The following function is implemented, although very few audio
* discs give Universal Product Code information, which should just be
* the Medium Catalog Number on the box. Note, that the way the code
@@ -1123,7 +1190,7 @@
return;
cdrom_sysctl_header = register_sysctl_table(cdrom_root_table, 1);
- cdrom_root_table->de->fill_inode = &cdrom_procfs_modcount;
+ cdrom_root_table->child->de->fill_inode = &cdrom_procfs_modcount;
initialized = 1;
}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)