diff options
author | Ralf Baechle <ralf@linux-mips.org> | 1998-08-25 09:12:35 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 1998-08-25 09:12:35 +0000 |
commit | c7fc24dc4420057f103afe8fc64524ebc25c5d37 (patch) | |
tree | 3682407a599b8f9f03fc096298134cafba1c9b2f /drivers/cdrom | |
parent | 1d793fade8b063fde3cf275bf1a5c2d381292cd9 (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.c | 110 | ||||
-rw-r--r-- | drivers/cdrom/cdu31a.c | 86 | ||||
-rw-r--r-- | drivers/cdrom/cm206.c | 8 | ||||
-rw-r--r-- | drivers/cdrom/mcd.c | 1 | ||||
-rw-r--r-- | drivers/cdrom/sbpcd.c | 8 | ||||
-rw-r--r-- | drivers/cdrom/sonycd535.c | 2 |
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. * |