Some CDROM patches for 2.1.82

Erik Andersen (andersee@debian.org)
Sun, 25 Jan 1998 11:02:57 -0700


Linus,

Here are some patches to take care of some CDROM problems. This should
go into 2.1.82 to fix the following bugs:

In ide-cd.c:
fixed a bug so now changers can change to a new slot when there is no
disc in the current slot, fixed a memory leak where info->changer_info
was malloc'ed but never free'd when closing the device, and cleaned up
the global namespace a bit by making more functions static that should
already have been.

In cdrom.c:
Fixed a bug in the IOCTL_IN and IOCTL_OUT macros. It turns out that
copy_*_user does not return EFAULT on error, but instead return the
number of bytes not copied. I was returning whatever non-zero stuff came
back from the copy_*_user functions directly, which would result in
strange errors.

In cdu31a.c:
Removed the scd_disc_status() function, which was now just dead code
left over from the port to the Uniform CDROM driver.

In cm206.c:
Removed the cm206_disc_status() function, which was also now just dead
code left over from the port to the Uniform CDROM driver.

In sbpcd.c:
Fixed a bug where playing audio left the drive in an unusable state.

Documentation/cdrom/ide-cd:
Some minor documentation updates.

-Erik

--
Erik B. Andersen   Web:    http://www.inconnect.com/~andersen/ 
                   email:  andersee@debian.org
--This message was written using 73% post-consumer electrons--

[-----------------patch follows--------------------]

diff -u --recursive --new-file linux-2.1.81.virgin/Documentation/cdrom/ide-cd linux/Documentation/cdrom/ide-cd --- linux-2.1.81.virgin/Documentation/cdrom/ide-cd Tue Dec 2 12:41:44 1997 +++ linux/Documentation/cdrom/ide-cd Sat Jan 24 21:47:41 1998 @@ -1,12 +1,12 @@ IDE-CD driver documentation -19 May 1996 -scott snyder <snyder@fnald0.fnal.gov> +Originally by scott snyder <snyder@fnald0.fnal.gov> (19 May 1996) +Carrying on the torch is: Erik Andersen <andersee@debian.org> 1. Introduction --------------- -The ide-cd driver should work with all ATAPI 1.2 compliant cdrom -drives which attach to an IDE interface. Note that some cdrom vendors +The ide-cd driver should work with all ATAPI ver 1.2 to ATAPI 2.6 compliant +cdrom drives which attach to an IDE interface. Note that some cdrom vendors (including Mitsumi, Sony, Creative, Aztech, and Goldstar) have made both ATAPI-compliant drives and drives which use a proprietary interface. If your drive uses one of those proprietary interfaces, @@ -28,9 +28,7 @@ - On drives which support it, reading digital audio data directly from audio tracks. The program cdda2wav can be used for this. - Note, however, that only a few drives actually support this - function; the only ones which i've heard of successes with are Sony - and Toshiba drives. + Note, however, that only some drives actually support this. - There is now support for cdrom changers which comply with the ATAPI 2.6 draft standard (such as the NEC CDR-251). This additional @@ -50,10 +48,13 @@ driver. 1. Make sure that the ide and ide-cd drivers are compiled into the - kernel you're using. When configuring the kernel, say `yes' to the - options + kernel you're using. When configuring the kernel, in the section + entitled "Floppy, IDE, and other block devices", say either `Y' + (which will compile the support directly into the kernel) or `M' + (to compile support as a module which can be loaded and unloaded) + to the options: - Enhanced IDE/MFM/RLL disk/cdrom/tape support + Enhanced IDE/MFM/RLL disk/cdrom/tape/floppy support Include IDE/ATAPI CDROM support and `no' to @@ -74,8 +75,8 @@ address and an IRQ number, the standard assignments being 0x170 and 14 for the primary interface and 0x1f0 and 15 for the secondary interface. Each interface can control up to two devices, - where each device can be either a hard drive, a cdrom drive, or a - tape drive. The two devices on an interface are called `master' + where each device can be a hard drive, a cdrom drive, a floppy drive, + or a tape drive. The two devices on an interface are called `master' and `slave'; this is usually selectable via a jumper on the drive. Linux names these devices as follows. The master and slave devices @@ -223,7 +224,9 @@ - If the autoprobing is not finding your drive, you can tell the driver to assume that one exists by using a lilo option of the form `hdX=cdrom', where X is the drive letter corresponding to - where your drive is installed (see section 2). Note that if you + where your drive is installed (see section 2). This is required + for CDROM drives such as the Pioneer DR-A24X, which do not properly + identify themselves as ATAPI CDROM drives. Note that if you do this and you see a boot message like hdX: ATAPI cdrom (?) diff -u --recursive --new-file linux-2.1.81.virgin/drivers/block/ide-cd.c linux/drivers/block/ide-cd.c --- linux-2.1.81.virgin/drivers/block/ide-cd.c Sat Jan 10 11:42:55 1998 +++ linux/drivers/block/ide-cd.c Sun Jan 25 09:56:43 1998 @@ -3,13 +3,14 @@ * linux/drivers/block/ide-cd.c * Copyright (C) 1994, 1995, 1996 scott snyder <snyder@fnald0.fnal.gov> * Copyright (C) 1996-1998 Erik Andersen <andersee@debian.org> + * * May be copied or modified under the terms of the GNU General Public * License. See linux/COPYING for more information. * * ATAPI CD-ROM driver. To be used with ide.c. * See Documentation/cdrom/ide-cd for usage information. * - * Suggestions are welcome. Patches that work are more welcome though. + * Suggestions are welcome. Patches that work are more welcome though. ;-) * For those wishing to work on this driver, please be sure you download * and comply with the latest ATAPI standard. This document can be * obtained by anonymous ftp from fission.dt.wdc.com in directory: @@ -182,10 +183,16 @@ * -- fix speed display for ACER 24X, 18X * 4.09 Jan 04, 1998 -- fix handling of the last block so we return * an end of file instead of an I/O error (Gadi) + * 4.10 Jan 24, 1998 -- fixed a bug so now changers can change to a new + * slot when there is no disc in the current slot. + * -- Fixed a memory leak where info->changer_info was + * malloc'ed but never free'd when closing the device. + * -- Cleaned up the global namespace a bit by making more + * functions static that should already have been. * *************************************************************************/ -#define IDECD_VERSION "4.09" +#define IDECD_VERSION "4.10" #include <linux/config.h> #include <linux/module.h> @@ -1309,7 +1316,7 @@ /**************************************************************************** * cdrom driver request routine. */ - +static void ide_do_rw_cdrom (ide_drive_t *drive, struct request *rq, unsigned long block) { if (rq -> cmd == PACKET_COMMAND || rq -> cmd == REQUEST_SENSE_COMMAND) @@ -2467,10 +2474,6 @@ if (drive->usage > 1) return -EBUSY; - stat = cdrom_check_status (drive, &my_reqbuf); - if (stat && my_reqbuf.sense_key == NOT_READY) - return -ENOENT; - if (slot == CDSL_NONE) { (void) cdrom_load_unload (drive, -1, NULL); cdrom_saw_media_change (drive); @@ -2765,8 +2768,7 @@ printk (" changer w/%d slots", nslots); else printk (" drive"); - printk (" %s/%dkB Cache\n", - (CDROM_CONFIG_FLAGS (drive)->is_changer)? "&" : "w", + printk (", %dkB Cache\n", ntohs(buf.cap.buffer_size) ); return nslots; @@ -2900,7 +2902,7 @@ } /* Forwarding functions to generic routines. */ - +static int ide_cdrom_ioctl (ide_drive_t *drive, struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) @@ -2908,6 +2910,7 @@ return cdrom_fops.ioctl (inode, file, cmd, arg); } +static int ide_cdrom_open (struct inode *ip, struct file *fp, ide_drive_t *drive) { int rc; @@ -2921,6 +2924,7 @@ return rc; } +static void ide_cdrom_release (struct inode *inode, struct file *file, ide_drive_t *drive) { @@ -2928,6 +2932,7 @@ MOD_DEC_USE_COUNT; } +static int ide_cdrom_check_media_change (ide_drive_t *drive) { return cdrom_fops.check_media_change @@ -2936,6 +2941,7 @@ } +static int ide_cdrom_cleanup(ide_drive_t *drive) { struct cdrom_info *info = drive->driver_data; @@ -2947,6 +2953,8 @@ kfree (info->sector_buffer); if (info->toc != NULL) kfree (info->toc); + if (info->changer_info != NULL) + kfree (info->changer_info); if (devinfo->handle == drive && unregister_cdrom (devinfo)) printk ("%s: ide_cdrom_cleanup failed to unregister device from the cdrom driver.\n", drive->name); kfree (info); diff -u --recursive --new-file linux-2.1.81.virgin/drivers/cdrom/cdrom.c linux/drivers/cdrom/cdrom.c --- linux-2.1.81.virgin/drivers/cdrom/cdrom.c Mon Jan 5 01:06:26 1998 +++ linux/drivers/cdrom/cdrom.c Sun Jan 25 09:55:10 1998 @@ -1,6 +1,6 @@ /* linux/drivers/cdrom/cdrom.c. Copyright (c) 1996, 1997 David A. van Leeuwen. - Copyright (c) 1997, 1998 Erik Andersen (andersee@debian.org) + Copyright (c) 1997, 1998 Erik Andersen <andersee@debian.org> May be copied or modified under the terms of the GNU General Public License. See linux/COPYING for more information. @@ -10,46 +10,71 @@ The routines in the file provide a uniform interface between the software that uses CD-ROMs and the various low-level drivers that - actually talk to actual hardware devices. Suggestions are welcome. + actually talk to the hardware. Suggestions are welcome. Patches that work are more welcome though. ;-) + To Do List: + ---------------------------------- - Recent Changes: - ---------------------------------- + -- Modify sysctl/proc interface. I plan on having one directory per + drive, with entries for outputing general drive information, and sysctl + based tunable parameters such as whether the tray should auto-close for + that drive. Suggestions (or patches) for this welcome! - New maintainer! As David A. van Leeuwen has been too busy to activly + -- Change the CDROMREADMODE1, CDROMREADMODE2, CDROMREADAUDIO, and + CDROMREADRAW ioctls so they go through the Uniform CD-ROM driver. + + + + + Revision History + ---------------------------------- + 1.00 Date Unknown -- David van Leeuwen <david@tm.tno.nl> + -- Initial version by David A. van Leeuwen. I don't have a detailed + changelog for the 1.x series, David? + +2.00 Dec 2, 1997 -- Erik Andersen <andersee@debian.org> + -- New maintainer! As David A. van Leeuwen has been too busy to activly maintain and improve this driver, I am now carrying on the torch. If you have a problem with this driver, please feel free to contact me. - Added (rudimentary) sysctl interface. I realize this is really weak - right now, and is _very_ badly implemented. It will be improved... I - plan on having one directory per drive, with entries for outputing - general drive information, and sysctl based tunable parameters such - as whether the tray should auto-close for that drive. Suggestions (or - patches) for improvements are very welcome. + -- Added (rudimentary) sysctl interface. I realize this is really weak + right now, and is _very_ badly implemented. It will be improved... - Modified CDROM_DISC_STATUS so that it is now incorporated into + -- Modified CDROM_DISC_STATUS so that it is now incorporated into the Uniform CD-ROM driver via the cdrom_count_tracks function. The cdrom_count_tracks function helps resolve some of the false assumptions of the CDROM_DISC_STATUS ioctl, and is also used to check for the correct media type when mounting or playing audio from a CD. - Remove the calls to verify_area and only use the copy_from_user and + -- Remove the calls to verify_area and only use the copy_from_user and copy_to_user stuff, since these calls now provide their own memory checking with the 2.1.x kernels. - Major update to return codes so that errors from low-level drivers + -- Major update to return codes so that errors from low-level drivers are passed on through (thanks to Gerd Knorr for pointing out this problem). - Made it so if a function isn't implemented in a low-level driver, + -- Made it so if a function isn't implemented in a low-level driver, ENOSYS is now returned instead of EINVAL. - Simplified some complex logic so that the source code is easier to read. + -- Simplified some complex logic so that the source code is easier to read. + + -- Other stuff I probably forgot to mention (lots of changes). + +2.01 to 2.11 Dec 1997-Jan 1998 + -- TO-DO! Write changelogs for 2.01 to 2.12. - Other stuff I probably forgot to mention (lots of changes). +2.12 Jan 24, 1998 -- Erik Andersen <andersee@debian.org> + -- Fixed a bug in the IOCTL_IN and IOCTL_OUT macros. It turns out that + copy_*_user does not return EFAULT on error, but instead return the number + of bytes not copied. I was returning whatever non-zero stuff came back from + the copy_*_user functions directly, which would result in strange errors. - */ +-------------------------------------------------------------------------*/ + +#define REVISION "Revision: 2.12" +#define VERSION "Id: cdrom.c 2.12 1998/01/24 22:15:45 erik Exp" #include <linux/config.h> @@ -68,10 +93,6 @@ #include <asm/uaccess.h> -#define VERSION "$Id: cdrom.c,v 2.11 1998/01/04 01:11:18 erik Exp $" -#define REVISION "Revision: 2.11" -#define FM_WRITE 0x2 /* file mode write bit */ - /* I use an error-log mask to give fine grain control over the type of error messages dumped to the system logs. The available masks include: */ #define CD_WARNING 0x1 @@ -96,15 +117,17 @@ #define cdinfo(type, fmt, args...) #endif - /* These are used to simplify getting data in from and back to user land */ #define IOCTL_IN(arg, type, in) { \ - int ret=copy_from_user(&in, (type *) arg, sizeof in); \ - if (ret) return ret; } + if ( copy_from_user(&in, (type *) arg, sizeof in) ) \ + return -EFAULT; } #define IOCTL_OUT(arg, type, out) { \ - int ret=copy_to_user((type *) arg, &out, sizeof out); \ - if (ret) return ret; } + if ( copy_to_user((type *) arg, &out, sizeof out) ) \ + return -EFAULT; } + + +#define FM_WRITE 0x2 /* file mode write bit */ /* Not-exported routines. */ static int cdrom_open(struct inode *ip, struct file *fp); diff -u --recursive --new-file linux-2.1.81.virgin/drivers/cdrom/cdu31a.c linux/drivers/cdrom/cdu31a.c --- linux-2.1.81.virgin/drivers/cdrom/cdu31a.c Sat Jan 24 18:06:11 1998 +++ linux/drivers/cdrom/cdu31a.c Sat Jan 24 22:26:22 1998 @@ -186,6 +186,10 @@ * Heiko Eissfeldt <heiko@colossus.escape.de> with additional * changes by Erik Andersen <andersee@debian.org> * + * 24 January 1998 -- Removed the scd_disc_status() function, which was now + * just dead code left over from the port. + * Erik Andersen <andersee@debian.org> + * */ #include <linux/major.h> @@ -1241,35 +1245,6 @@ buf[1] = size / 256; buf[2] = size % 256; } - -#if 0 -/* Uniform cdrom interface function. - Return the status of the current disc: - If it is recognized as CD-I -> return XA Mode 2 Form 2 - If it is recognized as XA -> return XA Mode 2 Form 1 - If there is at least one data track return Mode 1 - else return type AUDIO - */ -static int scd_disc_status(struct cdrom_device_info *cdi) -{ - if (sony_spun_up) - { - int i; - - sony_get_toc(); - /* look into the TOC */ - if (sony_toc.disk_type == 0x10) /* this is a CD-I disc */ - return CDS_XA_2_2; - if (sony_toc.disk_type == 0x20) /* this is a XA disc */ - return CDS_XA_2_1; - for (i = 0; i < sony_toc.track_entries; i++) - if (sony_toc.tracks[i].control & CDROM_DATA_TRACK) - return CDS_DATA_1; - return CDS_AUDIO; - } else - return CDS_NO_INFO; -} -#endif /* Starts a read operation. Returns 0 on success and 1 on failure. The read operation used here allows multiple sequential sectors diff -u --recursive --new-file linux-2.1.81.virgin/drivers/cdrom/cm206.c linux/drivers/cdrom/cm206.c --- linux-2.1.81.virgin/drivers/cdrom/cm206.c Sun Jan 4 11:55:08 1998 +++ linux/drivers/cdrom/cm206.c Sat Jan 24 22:29:10 1998 @@ -149,6 +149,8 @@ 21 dec 1997 1.4 Upgrade to Linux 2.1.72. +24 jan 1998 Removed the cm206_disc_status() function, as it was now dead + code. The Uniform CDROM driver now provides this functionality. * * Parts of the code are based upon lmscd.c written by Kai Petzke, * sbpcd.c written by Eberhard Moenkeberg, and mcd.c by Martin @@ -1140,24 +1142,6 @@ return CDS_DISC_OK; } -/* gives current state of disc in drive */ -int cm206_disc_status(struct cdrom_device_info * cdi) -{ - uch xa; - get_drive_status(); - if ((cd->dsb & dsb_not_useful) | !(cd->dsb & dsb_disc_present)) - return CDS_NO_DISC; - get_disc_status(); - if (DISC_STATUS & cds_all_audio) return CDS_AUDIO; - xa = DISC_STATUS >> 4; - switch (xa) { - case 0: return CDS_DATA_1; /* can we detect CDS_DATA_2? */ - case 1: return CDS_XA_2_1; /* untested */ - case 2: return CDS_XA_2_2; - } - return 0; -} - /* locks or unlocks door lock==1: lock; return 0 upon success */ int cm206_lock_door(struct cdrom_device_info * cdi, int lock) { diff -u --recursive --new-file linux-2.1.81.virgin/drivers/cdrom/sbpcd.c linux/drivers/cdrom/sbpcd.c --- linux-2.1.81.virgin/drivers/cdrom/sbpcd.c Mon Jan 5 01:06:26 1998 +++ linux/drivers/cdrom/sbpcd.c Sun Jan 25 10:03:49 1998 @@ -304,6 +304,9 @@ * Heiko Eissfeldt <heiko@colossus.escape.de> with additional * changes by Erik Andersen <andersee@debian.org> * + * 4.62 Fix a bug where playing audio left the drive in an unusable state. + * Heiko Eissfeldt <heiko@colossus.escape.de> + * * * TODO * implement "read all subchannel data" (96 bytes per frame) @@ -1046,7 +1049,7 @@ sbp_sleep(1); i = 1; } - msg(DBG_LCS,"CDi_stat_loop failed\n"); + msg(DBG_LCS,"CDi_stat_loop failed in line %d\n", __LINE__); return (-1); } /*==========================================================================*/ @@ -4295,7 +4298,7 @@ } if (status_tries == 0) { - msg(DBG_AUD,"read_audio: sbp_status: failed after 3 tries.\n"); + msg(DBG_AUD,"read_audio: sbp_status: failed after 3 tries in line %d.\n", __LINE__); continue; } msg(DBG_AUD,"read_audio: sbp_status: ok.\n"); @@ -4467,7 +4470,7 @@ #endif OLD_BUSY if (data_tries == 0) { - msg(DBG_AUD,"read_audio: failed after 5 tries.\n"); + msg(DBG_AUD,"read_audio: failed after 5 tries in line %d.\n", __LINE__); RETURN_UP(-EIO); } msg(DBG_AUD,"read_audio: successful return.\n"); @@ -4651,6 +4654,7 @@ #endif SAFE_MIXED i=cc_Pause_Resume(1); D_S[d].audio_state=0; + cc_DriveReset(); RETURN_UP(i); case CDROMSTART: /* Spin up the drive */ @@ -4886,7 +4890,7 @@ } if (status_tries == 0) { - msg(DBG_INF,"sbp_status: failed after 3 tries\n"); + msg(DBG_INF,"sbp_status: failed after 3 tries in line %d\n", __LINE__); break; }