summaryrefslogtreecommitdiffstats
path: root/drivers/cdrom
diff options
context:
space:
mode:
authorRalf Baechle <ralf@linux-mips.org>1998-08-25 09:12:35 +0000
committerRalf Baechle <ralf@linux-mips.org>1998-08-25 09:12:35 +0000
commitc7fc24dc4420057f103afe8fc64524ebc25c5d37 (patch)
tree3682407a599b8f9f03fc096298134cafba1c9b2f /drivers/cdrom
parent1d793fade8b063fde3cf275bf1a5c2d381292cd9 (diff)
o Merge with Linux 2.1.116.
o New Newport console code. o New G364 console code.
Diffstat (limited to 'drivers/cdrom')
-rw-r--r--drivers/cdrom/cdrom.c110
-rw-r--r--drivers/cdrom/cdu31a.c86
-rw-r--r--drivers/cdrom/cm206.c8
-rw-r--r--drivers/cdrom/mcd.c1
-rw-r--r--drivers/cdrom/sbpcd.c8
-rw-r--r--drivers/cdrom/sonycd535.c2
6 files changed, 114 insertions, 101 deletions
diff --git a/drivers/cdrom/cdrom.c b/drivers/cdrom/cdrom.c
index 30c8e969f..a2806b858 100644
--- a/drivers/cdrom/cdrom.c
+++ b/drivers/cdrom/cdrom.c
@@ -71,10 +71,19 @@
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.
+2.13 July 17, 1998 -- Erik Andersen <andersee@debian.org>
+ -- Fixed a bug in CDROM_SELECT_SPEED where you couldn't lower the speed
+ of the drive. Thanks to Tobias Ringstr|m <tori@prosolvia.se> for pointing
+ this out and providing a simple fix.
+ -- Fixed the procfs-unload-module bug with the fill_inode procfs callback.
+ thanks to Andrea Arcangeli <arcangeli@mbox.queen.it>
+ -- Fixed it so that the /proc entry now also shows up when cdrom is
+ compiled into the kernel. Before it only worked when loaded as a module.
+
-------------------------------------------------------------------------*/
-#define REVISION "Revision: 2.12"
-#define VERSION "Id: cdrom.c 2.12 1998/01/24 22:15:45 erik Exp"
+#define REVISION "Revision: 2.13"
+#define VERSION "Id: cdrom.c 2.13 1998/07/17 erik"
/* 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: */
@@ -104,14 +113,28 @@
#include <linux/malloc.h>
#include <linux/cdrom.h>
#include <linux/sysctl.h>
+#include <linux/proc_fs.h>
#include <asm/fcntl.h>
#include <asm/segment.h>
#include <asm/uaccess.h>
+/* used to tell the module to turn on full debugging messages */
+static int debug = 0;
+/* default compatibility mode */
+static int autoclose=1;
+static int autoeject=0;
+static int lockdoor = 1;
+static int check_media_type = 0;
+MODULE_PARM(debug, "i");
+MODULE_PARM(autoclose, "i");
+MODULE_PARM(autoeject, "i");
+MODULE_PARM(lockdoor, "i");
+MODULE_PARM(check_media_type, "i");
#if (ERRLOGMASK!=CD_NOTHING)
#define cdinfo(type, fmt, args...) \
- if (ERRLOGMASK & type) printk(KERN_INFO "cdrom: " fmt, ## args)
+ if ((ERRLOGMASK & type) || debug==1 ) \
+ printk(KERN_INFO "cdrom: " fmt, ## args)
#else
#define cdinfo(type, fmt, args...)
#endif
@@ -139,6 +162,7 @@ static int check_for_audio_disc(struct cdrom_device_info * cdi,
struct cdrom_device_ops * cdo);
static void sanitize_format(union cdrom_addr *addr,
u_char * curr, u_char requested);
+static void cdrom_sysctl_register(void);
typedef struct {
int data;
int audio;
@@ -176,6 +200,7 @@ struct file_operations cdrom_fops =
int register_cdrom(struct cdrom_device_info *cdi)
{
+ static char banner_printed = 0;
int major = MAJOR (cdi->dev);
struct cdrom_device_ops *cdo = cdi->ops;
int *change_capability = (int *)&cdo->capability; /* hack */
@@ -184,6 +209,13 @@ int register_cdrom(struct cdrom_device_info *cdi)
return -1;
if (cdo->open == NULL || cdo->release == NULL)
return -2;
+ if ( !banner_printed ) {
+ printk(KERN_INFO "Uniform CDROM driver " REVISION "\n");
+ banner_printed = 1;
+#ifdef CONFIG_SYSCTL
+ cdrom_sysctl_register();
+#endif /* CONFIG_SYSCTL */
+ }
ENSURE(drive_status, CDC_DRIVE_STATUS );
ENSURE(media_changed, CDC_MEDIA_CHANGED);
ENSURE(tray_move, CDC_CLOSE_TRAY | CDC_OPEN_TRAY);
@@ -195,18 +227,17 @@ int register_cdrom(struct cdrom_device_info *cdi)
ENSURE(reset, CDC_RESET);
ENSURE(audio_ioctl, CDC_PLAY_AUDIO);
ENSURE(dev_ioctl, CDC_IOCTLS);
- cdi->options = CDO_AUTO_CLOSE | CDO_USE_FFLAGS | CDO_LOCK;
- /* default compatibility mode */
cdi->mc_flags = 0;
cdo->n_minors = 0;
-
- {
- static char banner_printed = 0;
- if ( !banner_printed ) {
- printk(KERN_INFO "Uniform CD-ROM driver " REVISION "\n");
- banner_printed = 1;
- }
- }
+ cdi->options = CDO_USE_FFLAGS;
+ if (autoclose==1)
+ cdi->options |= (int) CDO_AUTO_CLOSE;
+ if (autoeject==1)
+ cdi->options |= (int) CDO_AUTO_EJECT;
+ if (lockdoor==1)
+ cdi->options |= (int) CDO_LOCK;
+ if (check_media_type==1)
+ cdi->options |= (int) CDO_CHECK_TYPE;
cdinfo(CD_REG_UNREG, "drive \"/dev/%s\" registered\n", cdi->name);
cdi->next = topCdromPtr;
@@ -290,7 +321,7 @@ int open_for_data(struct cdrom_device_info * cdi)
struct cdrom_device_ops *cdo = cdi->ops;
tracktype tracks;
cdinfo(CD_OPEN, "entering open_for_data\n");
- /* Check if the driver can report drive status. If it can we
+ /* Check if the driver can report drive status. If it can, we
can do clever things. If it can't, well, we at least tried! */
if (cdo->drive_status != NULL) {
ret = cdo->drive_status(cdi, CDSL_CURRENT);
@@ -337,10 +368,15 @@ int open_for_data(struct cdrom_device_info * cdi)
}
/* CD-Players which don't use O_NONBLOCK, workman
* for example, need bit CDO_CHECK_TYPE cleared! */
- if (cdi->options & CDO_CHECK_TYPE && tracks.data==0) {
- cdinfo(CD_OPEN, "bummer. wrong media type.\n");
- ret=-EMEDIUMTYPE;
- goto clean_up_and_return;
+ if (tracks.data==0) {
+ if (cdi->options & CDO_CHECK_TYPE) {
+ cdinfo(CD_OPEN, "bummer. wrong media type.\n");
+ ret=-EMEDIUMTYPE;
+ goto clean_up_and_return;
+ }
+ else {
+ cdinfo(CD_OPEN, "wrong media type, but CDO_CHECK_TYPE not set.\n");
+ }
}
cdinfo(CD_OPEN, "all seems well, opening the device.\n");
@@ -367,7 +403,7 @@ int open_for_data(struct cdrom_device_info * cdi)
(notably ide-cd) lock the drive after every command. This produced
a nasty bug where after mount failed, the drive would remain locked!
This ensures that the drive gets unlocked after a mount fails. This
- is a goto to avoid adding bloating the driver with redundant code. */
+ is a goto to avoid bloating the driver with redundant code. */
clean_up_and_return:
cdinfo(CD_WARNING, "open failed.\n");
if (cdo->capability & ~cdi->mask & CDC_LOCK &&
@@ -379,8 +415,7 @@ clean_up_and_return:
}
/* This code is similar to that in open_for_data. The routine is called
- in case a audio play operation is requested. It doesn't make much sense
- to do this on a data disc.
+ whenever an audio play operation is requested.
*/
int check_for_audio_disc(struct cdrom_device_info * cdi,
struct cdrom_device_ops * cdo)
@@ -692,8 +727,6 @@ int cdrom_ioctl(struct inode *ip, struct file *fp,
cdinfo(CD_DO_IOCTL, "entering CDROM_SELECT_SPEED\n");
if (!(cdo->capability & ~cdi->mask & CDC_SELECT_SPEED))
return -ENOSYS;
- if ((int)arg > cdi->speed )
- return -EINVAL;
return cdo->select_speed(cdi, arg);
}
@@ -1019,18 +1052,33 @@ ctl_table cdrom_root_table[] = {
{0}
};
-#endif /* endif CONFIG_SYSCTL */
-
-
-#ifdef MODULE
-
-#ifdef CONFIG_SYSCTL
-
static struct ctl_table_header *cdrom_sysctl_header;
+/*
+ * This is called as the fill_inode function when an inode
+ * is going into (fill = 1) or out of service (fill = 0).
+ * We use it here to manage the module use counts.
+ *
+ * Note: only the top-level directory needs to do this; if
+ * a lower level is referenced, the parent will be as well.
+ */
+static void cdrom_procfs_modcount(struct inode *inode, int fill)
+{
+ if (fill)
+ MOD_INC_USE_COUNT;
+ else
+ MOD_DEC_USE_COUNT;
+}
+
static void cdrom_sysctl_register(void)
{
+ static int initialized = 0;
+
+ if ( initialized == 1 )
+ return;
cdrom_sysctl_header = register_sysctl_table(cdrom_root_table, 0);
+ cdrom_root_table->de->fill_inode = &cdrom_procfs_modcount;
+ initialized = 1;
}
static void cdrom_sysctl_unregister(void)
@@ -1039,6 +1087,8 @@ static void cdrom_sysctl_unregister(void)
}
#endif /* endif CONFIG_SYSCTL */
+#ifdef MODULE
+
int init_module(void)
{
#ifdef CONFIG_SYSCTL
diff --git a/drivers/cdrom/cdu31a.c b/drivers/cdrom/cdu31a.c
index 15481c9a8..465d24545 100644
--- a/drivers/cdrom/cdu31a.c
+++ b/drivers/cdrom/cdu31a.c
@@ -5,6 +5,8 @@
*
* Colossians 3:17
*
+* See Documentation/cdrom/cdu31a for additional details about this driver.
+*
* The Sony interface device driver handles Sony interface CDROM
* drives and provides a complete block-level interface as well as an
* ioctl() interface compatible with the Sun (as specified in
@@ -106,69 +108,15 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
+ * TODO:
+ * CDs with form1 and form2 sectors cause problems
+ * with current read-ahead strategy.
*
* Credits:
* Heiko Eissfeldt <heiko@colossus.escape.de>
* For finding abug in the return of the track numbers.
- */
-/* conversion to Uniform cdrom layer.
- TOC processing redone for proper multisession support.
-
- TODO:
- CDs with form1 and form2 sectors cause problems
- with current read-ahead strategy.
- Heiko Eissfeldt Sep 97 */
-
-/*
+ * TOC processing redone for proper multisession support.
*
- * Setting up the Sony CDU31A/CDU33A drive interface card. If
- * You have another card, you are on your own.
- *
- * +----------+-----------------+----------------------+
- * | JP1 | 34 Pin Conn | |
- * | JP2 +-----------------+ |
- * | JP3 |
- * | JP4 |
- * | +--+
- * | | +-+
- * | | | | External
- * | | | | Connector
- * | | | |
- * | | +-+
- * | +--+
- * | |
- * | +--------+
- * | |
- * +------------------------------------------+
- *
- * JP1 sets the Base Address, using the following settings:
- *
- * Address Pin 1 Pin 2
- * ------- ----- -----
- * 0x320 Short Short
- * 0x330 Short Open
- * 0x340 Open Short
- * 0x360 Open Open
- *
- * JP2 and JP3 configure the DMA channel; they must be set the same.
- *
- * DMA Pin 1 Pin 2 Pin 3
- * --- ----- ----- -----
- * 1 On Off On
- * 2 Off On Off
- * 3 Off Off On
- *
- * JP4 Configures the IRQ:
- *
- * IRQ Pin 1 Pin 2 Pin 3 Pin 4
- * --- ----- ----- ----- -----
- * 3 Off Off On Off
- * 4 Off Off* Off On
- * 5 On Off Off Off
- * 6 Off On Off Off
- *
- * * The documentation states to set this for interrupt
- * 4, but I think that is a mistake.
*
* It probably a little late to be adding a history, but I guess I
* will start.
@@ -190,6 +138,10 @@
* just dead code left over from the port.
* Erik Andersen <andersee@debian.org>
*
+ * 16 July 1998 -- Drive donated to Erik Andersen by John Kodis
+ * <kodis@jagunet.com>. Work begun on fixing driver to
+ * work under 2.1.X. Added temporary extra printks
+ * which seem to slow it down enough to work.
*/
#include <linux/major.h>
@@ -257,6 +209,7 @@ static struct
static int handle_sony_cd_attention(void);
static int read_subcode(void);
static void sony_get_toc(void);
+static int scd_spinup(void);
/*static int scd_open(struct inode *inode, struct file *filp);*/
static int scd_open(struct cdrom_device_info *, int);
static void do_sony_cd_cmd(unsigned char cmd,
@@ -419,9 +372,10 @@ static int scd_drive_status(struct cdrom_device_info *cdi, int slot_nr)
/* we have no changer support */
return -EINVAL;
}
-
- /*return sony_spun_up ? CDS_DISC_OK : CDS_DRIVE_NOT_READY;*/
- return sony_spun_up ? CDS_DISC_OK : CDS_TRAY_OPEN;
+ if (scd_spinup() == 0) {
+ sony_spun_up = 1;
+ }
+ return sony_spun_up ? CDS_DISC_OK : CDS_DRIVE_NOT_READY;
}
static inline void
@@ -1680,7 +1634,6 @@ read_data_block(char *buffer,
#endif
}
-static int scd_spinup(void);
/*
* The OS calls this to perform a read or write operation to the drive.
@@ -1984,8 +1937,11 @@ gettoc_drive_spinning:
session = 1;
while (1)
{
-#if DEBUG
- printk("Trying session %d\n", session);
+/* This seems to slow things down enough to make it work. This
+ * appears to be a problem in do_sony_cd_cmd. This printk seems
+ * to address the symptoms... -Erik */
+#if 1
+ printk("cdu31a: Trying session %d\n", session);
#endif
parms[0] = session;
do_sony_cd_cmd(SONY_READ_TOC_SPEC_CMD,
@@ -2001,6 +1957,8 @@ gettoc_drive_spinning:
if ((res_size < 2) || ((res_reg[0] & 0xf0) == 0x20))
{
/* An error reading the TOC, this must be past the last session. */
+ if (session == 1)
+ printk("Yikes! Couldn't read any sessions!");
break;
}
#if DEBUG
diff --git a/drivers/cdrom/cm206.c b/drivers/cdrom/cm206.c
index c0bcc7bf4..d1e114301 100644
--- a/drivers/cdrom/cm206.c
+++ b/drivers/cdrom/cm206.c
@@ -299,7 +299,7 @@ void send_command_polled(int command)
{
int loop=POLLOOP;
while (!(inw(r_line_status) & ls_transmitter_buffer_empty) && loop>0) {
- udelay(1000); /* one millisec delay */
+ mdelay(1); /* one millisec delay */
--loop;
}
outw(command, r_uart_transmit);
@@ -309,7 +309,7 @@ uch receive_echo_polled(void)
{
int loop=POLLOOP;
while (!(inw(r_line_status) & ls_receive_buffer_full) && loop>0) {
- udelay(1000);
+ mdelay(1);
--loop;
}
return ((uch) inw(r_uart_receive));
@@ -1194,7 +1194,7 @@ int cm206_reset(struct cdrom_device_info * cdi)
stop_read();
reset_cm260();
outw(dc_normal | dc_break | READ_AHEAD, r_data_control);
- udelay(1000); /* 750 musec minimum */
+ mdelay(1); /* 750 musec minimum */
outw(dc_normal | READ_AHEAD, r_data_control);
cd->sector_last = -1; /* flag no data buffered */
cd->adapter_last = -1;
@@ -1358,7 +1358,7 @@ __initfunc(int cm206_init(void))
/* Now, the problem here is that reset_cm260 can generate an
interrupt. It seems that this can cause a kernel oops some time
later. So we wait a while and `service' this interrupt. */
- udelay(1000);
+ mdelay(1);
outw(dc_normal | READ_AHEAD, r_data_control);
sti();
printk(" using IRQ %d\n", cm206_irq);
diff --git a/drivers/cdrom/mcd.c b/drivers/cdrom/mcd.c
index 1de0f7ba7..46866f4c2 100644
--- a/drivers/cdrom/mcd.c
+++ b/drivers/cdrom/mcd.c
@@ -157,6 +157,7 @@ int mitsumi_bug_93_wait = 0;
static short mcd_port = MCD_BASE_ADDR; /* used as "mcd" by "insmod" */
static int mcd_irq = MCD_INTR_NR; /* must directly follow mcd_port */
+MODULE_PARM(mcd, "1-2i");
static int McdTimeout, McdTries;
static struct wait_queue *mcd_waitq = NULL;
diff --git a/drivers/cdrom/sbpcd.c b/drivers/cdrom/sbpcd.c
index 539794595..428964d8f 100644
--- a/drivers/cdrom/sbpcd.c
+++ b/drivers/cdrom/sbpcd.c
@@ -5124,14 +5124,16 @@ static int sbp_data(struct request *req)
msg(DBG_000, "sbp_data: beginning to read.\n");
p = D_S[d].sbp_buf + frame * CD_FRAMESIZE;
if (sbpro_type==1) OUT(CDo_sel_i_d,1);
- if (cmd_type==READ_M2)
+ if (cmd_type==READ_M2) {
if (do_16bit) insw(CDi_data, xa_head_buf, CD_XA_HEAD>>1);
else insb(CDi_data, xa_head_buf, CD_XA_HEAD);
+ }
if (do_16bit) insw(CDi_data, p, CD_FRAMESIZE>>1);
else insb(CDi_data, p, CD_FRAMESIZE);
- if (cmd_type==READ_M2)
+ if (cmd_type==READ_M2) {
if (do_16bit) insw(CDi_data, xa_tail_buf, CD_XA_TAIL>>1);
else insb(CDi_data, xa_tail_buf, CD_XA_TAIL);
+ }
D_S[d].sbp_current++;
if (sbpro_type==1) OUT(CDo_sel_i_d,0);
if (cmd_type==READ_M2)
@@ -5667,8 +5669,10 @@ __initfunc(int SBPCD_INIT(void))
i=ResponseStatus(); /* returns orig. status or p_busy_new */
if (famT_drive) i=ResponseStatus(); /* returns orig. status or p_busy_new */
if (i<0)
+ {
if (i!=-402)
msg(DBG_INF,"init: ResponseStatus returns %d.\n",i);
+ }
else
{
if (st_check)
diff --git a/drivers/cdrom/sonycd535.c b/drivers/cdrom/sonycd535.c
index 5e0ae01b7..52e64890e 100644
--- a/drivers/cdrom/sonycd535.c
+++ b/drivers/cdrom/sonycd535.c
@@ -4,7 +4,7 @@
* This is a modified version of the CDU-31A device driver (see below).
* Changes were made using documentation for the CDU-531 (which Sony
* assures me is very similar to the 535) and partial disassembly of the
- * DOS driver. I used Minyard's driver and replaced the the CDU-31A
+ * DOS driver. I used Minyard's driver and replaced the CDU-31A
* commands with the CDU-531 commands. This was complicated by a different
* interface protocol with the drive. The driver is still polled.
*