Bug 14561

Summary: ioctl (fd, CDIOCEJECT, (void*) 0) doesn't work
Product: Base System Reporter: Ronald F. Guilmette <rfg>
Component: kernAssignee: Kenneth D. Merry <ken>
Status: Closed FIXED    
Severity: Affects Only Me    
Priority: Normal    
Version: 3.3-RELEASE   
Hardware: Any   
OS: Any   

Description Ronald F. Guilmette 1999-10-28 01:00:01 UTC
	Calling ioctl (fd, CDIOCEJECT, (void*) 0) from within a C program
	for an `fd' value which is an open file descriptor for a SCSI CDROM
	drive that *does* have eject capabilities and that *does* currently
	contain a loaded CD fails to cause the drive to perform the eject
	operation, and the call returns with a negative (-1?) result and
	with ERRNO set to the mysterious and uninformative value of `EIO'
	(``Input/output error'').

Fix: 

Manually eject the CD.  (Difficult, if you are not physically adjacent
	to it.)
How-To-Repeat: 
	Compile and run the following trivial program giving it "/dev/cd0c"
	as its one and only command line argument.  Execute the program
	_only_ on a system with a SCSI CDROM drive that has programmed
	ejection capability, and only when there is already a CD loaded
	in the drive.  (I also tried specifying "/dev/rcd0c" and also
	"/dev/cd0a" and even "/dev/rcd0a" and none of these worked any
	better.)

	--------------------------------------------------------------------
	/* eject.c - program for FreeBSD to eject a CD */
	/* Usage:
		eject [device]
	*/
	/* Copyright (c) 1999 Ronald F. Guilmette; all rights reserved. */
	
	#include <stdio.h>
	#include <errno.h>
	#include <string.h>
	#include <fcntl.h>
	#include <unistd.h>
	#include <sys/cdio.h>
	
	static char const *pname;
	
	int
	main (register int const argc, register char const **argv)
	{
	  register int ifd;
	  register char const *filename;
	
	  pname = strrchr (argv[0], '/');
	  pname = pname ? pname + 1 : argv[0];
	
	  filename = argv[1];
	
	  if ((ifd = open (filename, O_RDONLY)) == -1)
	    {
	      fprintf (stderr, "%s: Error opening `%s': %s\n",
		       pname, filename, strerror (errno));
	      return 1;
	    }
	  if (ioctl (ifd, CDIOCEJECT, (void*) 0) == -1)
	    {
	      fprintf (stderr, "%s: Error opening `%s': %s\n",
		       pname, filename, strerror (errno));
	      return 1;
	    }
	  close (ifd);
	  return 0;
	}
	--------------------------------------------------------------------
Comment 1 Kenneth D. Merry freebsd_committer freebsd_triage 1999-10-28 01:09:28 UTC
State Changed
From-To: open->analyzed

This is a known problem, we're working on a fix.  Yes, it is more complicated than it appears.   
Until we get a fix, try using 'camcontrol eject cd0' to eject your CD. 


Comment 2 Kenneth D. Merry freebsd_committer freebsd_triage 1999-10-28 01:09:28 UTC
Responsible Changed
From-To: freebsd-bugs->ken

My driver. 
Comment 3 Kenneth D. Merry freebsd_committer freebsd_triage 2003-03-03 19:08:02 UTC
State Changed
From-To: analyzed->feedback

The program in question should issue the CDIOCALLOW ioctl before issuing 
the CDIOCEJECT ioctl.  CDs are locked in the drive on open(), so you need 
to allow removal before you can eject them. 

If you do that, things should work okay.
Comment 4 Craig Rodrigues freebsd_committer freebsd_triage 2005-10-05 07:22:12 UTC
State Changed
From-To: feedback->closed

Feedback timeout