Commit 5e4a8497 authored by Linus Torvalds's avatar Linus Torvalds

Import 1.1.24

parent 2651e5f8
VERSION = 1 VERSION = 1
PATCHLEVEL = 1 PATCHLEVEL = 1
SUBLEVEL = 23 SUBLEVEL = 24
all: Version zImage all: Version zImage
......
...@@ -825,7 +825,7 @@ idVRAM: .ascii "Stealth VRAM" ...@@ -825,7 +825,7 @@ idVRAM: .ascii "Stealth VRAM"
! Number of modes is the number of chip-specific svga modes plus the extended ! Number of modes is the number of chip-specific svga modes plus the extended
! modes available on any vga (currently 2) ! modes available on any vga (currently 2)
moati: .byte 0x04, 0x23, 0x33 moati: .byte 0x06, 0x23, 0x33, 0x22, 0x21
moahead: .byte 0x07, 0x22, 0x23, 0x24, 0x2f, 0x34 moahead: .byte 0x07, 0x22, 0x23, 0x24, 0x2f, 0x34
mocandt: .byte 0x04, 0x60, 0x61 mocandt: .byte 0x04, 0x60, 0x61
mocirrus: .byte 0x06, 0x1f, 0x20, 0x22, 0x31 mocirrus: .byte 0x06, 0x1f, 0x20, 0x22, 0x31
...@@ -844,7 +844,7 @@ mounknown: .byte 0x02 ...@@ -844,7 +844,7 @@ mounknown: .byte 0x02
! The first two modes are standard vga modes available on any vga. ! The first two modes are standard vga modes available on any vga.
! mode 0 is 80x50 and mode 1 is 80x28 ! mode 0 is 80x50 and mode 1 is 80x28
dscati: .word 0x5032, 0x501c, 0x8419, 0x842c dscati: .word 0x5032, 0x501c, 0x8419, 0x842c, 0x641e, 0x6419
dscahead: .word 0x5032, 0x501c, 0x842c, 0x8419, 0x841c, 0xa032, 0x5042 dscahead: .word 0x5032, 0x501c, 0x842c, 0x8419, 0x841c, 0xa032, 0x5042
dsccandt: .word 0x5032, 0x501c, 0x8419, 0x8432 dsccandt: .word 0x5032, 0x501c, 0x8419, 0x8432
dsccirrus: .word 0x5032, 0x501c, 0x8419, 0x842c, 0x841e, 0x6425 dsccirrus: .word 0x5032, 0x501c, 0x8419, 0x842c, 0x841e, 0x6425
......
This README belongs to release 2.0 of the SoundBlaster Pro (Matsushita, This README belongs to release 2.1 of the SoundBlaster Pro (Matsushita,
Kotobuki, Panasonic, CreativeLabs) CD-ROM driver for Linux. Kotobuki, Panasonic, CreativeLabs) CD-ROM driver for Linux.
The driver is able to drive the whole family of IDE-style The driver is able to drive the whole family of IDE-style
...@@ -48,14 +48,21 @@ CDplayer and WorkBone - tell me if it is not compatible with other software. ...@@ -48,14 +48,21 @@ CDplayer and WorkBone - tell me if it is not compatible with other software.
With the "new" drive family CR-562 and CR-563, the reading of audio frames is With the "new" drive family CR-562 and CR-563, the reading of audio frames is
possible. This is currently implemented by an IOCTL function which reads only possible. This is currently implemented by an IOCTL function which reads only
one frame of 2352 bytes at a time. The transfer rate is as slow as 32 kB/sec. up to 4 frames of 2352 bytes at once. Reading more than 1 frame at once gives
This will get better, and the software interface may change. We have to very poor quality. Reading the same frame a second time gives different data;
standardize it the day the SCSI driver supports it too. it seems that the drive is out-of-sync at the beginning. See the program
example below. This lack has to get corrected by higher level software.
MultiSession is supported (even my "old" CR-521 can handle it), "ManySession" The transfer rate with reading audio (1-frame-pieces) is as slow as 32 kB/sec.
(not recommended, see below) alternatively. This could be better reading bigger chunks, but the out-of-sync parts occur at
Photo CDs work, too. At ftp.gwdg.de:/pub/linux/hpcdtoppm/ is Hadmut Danisch's the beginning of each single frame.
package to convert photo CD image files. The software interface possibly may change a bit the day the SCSI driver
supports it too.
MultiSession is supported, "ManySession" (not recommended, see below)
alternatively.
Photo CDs work, too (even with my "old" CR-521).
At ftp.gwdg.de:/pub/linux/hpcdtoppm/ is Hadmut Danisch's package to convert
photo CD image files.
The transfer rate will reach 150 kB/sec with "old" drives and 300 kB/sec with The transfer rate will reach 150 kB/sec with "old" drives and 300 kB/sec with
double-speed drives. XA (PhotoCD) disks with "old" drives give only 50 kB/sec. double-speed drives. XA (PhotoCD) disks with "old" drives give only 50 kB/sec.
...@@ -340,6 +347,10 @@ entry[track+1].cdte_addr.lba=190; ...@@ -340,6 +347,10 @@ entry[track+1].cdte_addr.lba=190;
} }
/*===================== end program ========================================*/ /*===================== end program ========================================*/
At ftp.gwdg.de:/pub/linux/misc/cdda2wav-sbpcd.tar.gz is an adapted version of
Heiko Eissfeldt's digital-audio to .WAV converter (the original is there, too).
This is preliminary, as Heiko himself will care about it.
Known problems: Known problems:
--------------- ---------------
......
...@@ -407,7 +407,7 @@ void request_done(int uptodate) ...@@ -407,7 +407,7 @@ void request_done(int uptodate)
* to the desired drive, but it will probably not survive the sleep if * to the desired drive, but it will probably not survive the sleep if
* several floppies are used at the same time: thus the loop. * several floppies are used at the same time: thus the loop.
*/ */
int floppy_change(struct buffer_head * bh) static int floppy_change(struct buffer_head * bh)
{ {
unsigned int mask = 1 << (bh->b_dev & 0x03); unsigned int mask = 1 << (bh->b_dev & 0x03);
...@@ -1289,14 +1289,13 @@ static int floppy_open(struct inode * inode, struct file * filp) ...@@ -1289,14 +1289,13 @@ static int floppy_open(struct inode * inode, struct file * filp)
int drive; int drive;
int old_dev; int old_dev;
if (floppy_grab_irq_and_dma()) {
return -EBUSY;
}
drive = inode->i_rdev & 3; drive = inode->i_rdev & 3;
old_dev = fd_device[drive]; old_dev = fd_device[drive];
if (fd_ref[drive]) if (fd_ref[drive])
if (old_dev != inode->i_rdev) if (old_dev != inode->i_rdev)
return -EBUSY; return -EBUSY;
if (floppy_grab_irq_and_dma())
return -EBUSY;
fd_ref[drive]++; fd_ref[drive]++;
fd_device[drive] = inode->i_rdev; fd_device[drive] = inode->i_rdev;
buffer_drive = buffer_track = -1; buffer_drive = buffer_track = -1;
...@@ -1309,7 +1308,7 @@ static int floppy_open(struct inode * inode, struct file * filp) ...@@ -1309,7 +1308,7 @@ static int floppy_open(struct inode * inode, struct file * filp)
static void floppy_release(struct inode * inode, struct file * filp) static void floppy_release(struct inode * inode, struct file * filp)
{ {
sync_dev(inode->i_rdev); fsync_dev(inode->i_rdev);
if (!fd_ref[inode->i_rdev & 3]--) { if (!fd_ref[inode->i_rdev & 3]--) {
printk("floppy_release with fd_ref == 0"); printk("floppy_release with fd_ref == 0");
fd_ref[inode->i_rdev & 3] = 0; fd_ref[inode->i_rdev & 3] = 0;
...@@ -1317,6 +1316,18 @@ static void floppy_release(struct inode * inode, struct file * filp) ...@@ -1317,6 +1316,18 @@ static void floppy_release(struct inode * inode, struct file * filp)
floppy_release_irq_and_dma(); floppy_release_irq_and_dma();
} }
static int check_floppy_change(dev_t dev)
{
int i;
struct buffer_head * bh;
if (!(bh = getblk(dev,0,1024)))
return 0;
i = floppy_change(bh);
brelse(bh);
return i;
}
static struct file_operations floppy_fops = { static struct file_operations floppy_fops = {
NULL, /* lseek - default */ NULL, /* lseek - default */
block_read, /* read - general block-dev read */ block_read, /* read - general block-dev read */
...@@ -1327,26 +1338,13 @@ static struct file_operations floppy_fops = { ...@@ -1327,26 +1338,13 @@ static struct file_operations floppy_fops = {
NULL, /* mmap */ NULL, /* mmap */
floppy_open, /* open */ floppy_open, /* open */
floppy_release, /* release */ floppy_release, /* release */
block_fsync /* fsync */ block_fsync, /* fsync */
NULL, /* fasync */
check_floppy_change, /* media_change */
NULL /* revalidate */
}; };
/*
* The version command is not supposed to generate an interrupt, but
* my FDC does, except when booting in SVGA screen mode.
* When it does generate an interrupt, it doesn't return any status bytes.
* It appears to have something to do with the version command...
*
* This should never be called, because of the reset after the version check.
*/
static void ignore_interrupt(void)
{
printk(DEVICE_NAME ": weird interrupt ignored (%d)\n", result());
reset = 1;
CLEAR_INTR; /* ignore only once */
}
static void floppy_interrupt(int unused) static void floppy_interrupt(int unused)
{ {
void (*handler)(void) = DEVICE_INTR; void (*handler)(void) = DEVICE_INTR;
...@@ -1381,7 +1379,6 @@ void floppy_init(void) ...@@ -1381,7 +1379,6 @@ void floppy_init(void)
timer_active &= ~(1 << FLOPPY_TIMER); timer_active &= ~(1 << FLOPPY_TIMER);
config_types(); config_types();
/* Try to determine the floppy controller type */ /* Try to determine the floppy controller type */
DEVICE_INTR = ignore_interrupt; /* don't ask ... */
output_byte(FD_VERSION); /* get FDC version code */ output_byte(FD_VERSION); /* get FDC version code */
if (result() != 1) { if (result() != 1) {
printk(DEVICE_NAME ": FDC failed to return version byte\n"); printk(DEVICE_NAME ": FDC failed to return version byte\n");
...@@ -1404,8 +1401,12 @@ void floppy_init(void) ...@@ -1404,8 +1401,12 @@ void floppy_init(void)
} }
} }
static int usage_count = 0;
static int floppy_grab_irq_and_dma(void) static int floppy_grab_irq_and_dma(void)
{ {
if (usage_count++)
return 0;
if (irqaction(FLOPPY_IRQ,&floppy_sigaction)) { if (irqaction(FLOPPY_IRQ,&floppy_sigaction)) {
printk("Unable to grab IRQ%d for the floppy driver\n", FLOPPY_IRQ); printk("Unable to grab IRQ%d for the floppy driver\n", FLOPPY_IRQ);
return -1; return -1;
...@@ -1421,6 +1422,8 @@ static int floppy_grab_irq_and_dma(void) ...@@ -1421,6 +1422,8 @@ static int floppy_grab_irq_and_dma(void)
static void floppy_release_irq_and_dma(void) static void floppy_release_irq_and_dma(void)
{ {
if (--usage_count)
return;
disable_dma(FLOPPY_DMA); disable_dma(FLOPPY_DMA);
free_dma(FLOPPY_DMA); free_dma(FLOPPY_DMA);
disable_irq(FLOPPY_IRQ); disable_irq(FLOPPY_IRQ);
......
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
* and for "no-sound" interfaces like Lasermate and the * and for "no-sound" interfaces like Lasermate and the
* Panasonic CI-101P. * Panasonic CI-101P.
* *
* NOTE: This is release 2.0. * NOTE: This is release 2.1.
* It works with my SbPro & drive CR-521 V2.11 from 2/92 * It works with my SbPro & drive CR-521 V2.11 from 2/92
* and with the new CR-562-B V0.75 on a "naked" Panasonic * and with the new CR-562-B V0.75 on a "naked" Panasonic
* CI-101P interface. And vice versa. * CI-101P interface. And vice versa.
...@@ -106,6 +106,21 @@ ...@@ -106,6 +106,21 @@
* reset the drive and do again. Needs lots of resets here and sometimes * reset the drive and do again. Needs lots of resets here and sometimes
* that does not cure, so this can't be the solution. * that does not cure, so this can't be the solution.
* *
* 2.1 Found bug with multisession CDs (accessing frame 16).
* "read audio" works now with address type CDROM_MSF, too.
* Bigger audio frame buffer: allows reading max. 4 frames at time; but
* reading more than one frame at once gives poor quality.
*
*
* TODO
*
* disk change detection
* allow & synchronize multi-activity
* (data + audio + ioctl + disk change, multiple drives)
* implement multi-controller-support with a single driver
* implement "read all subchannel data" (96 bytes per frame)
*
*
* special thanks to Kai Makisara (kai.makisara@vtt.fi) for his fine * special thanks to Kai Makisara (kai.makisara@vtt.fi) for his fine
* elaborated speed-up experiments (and the fabulous results!), for * elaborated speed-up experiments (and the fabulous results!), for
* the "push" towards load-free wait loops, and for the extensive mail * the "push" towards load-free wait loops, and for the extensive mail
...@@ -172,7 +187,7 @@ ...@@ -172,7 +187,7 @@
#include "blk.h" #include "blk.h"
#define VERSION "2.0 Eberhard Moenkeberg <emoenke@gwdg.de>" #define VERSION "2.1 Eberhard Moenkeberg <emoenke@gwdg.de>"
#define SBPCD_DEBUG #define SBPCD_DEBUG
...@@ -198,7 +213,6 @@ ...@@ -198,7 +213,6 @@
#define XA_TEST2 #define XA_TEST2
#define TEST_UPC 0 #define TEST_UPC 0
#define READ_AUDIO 1
#define SPEA_TEST 0 #define SPEA_TEST 0
#define PRINTK_BUG 0 #define PRINTK_BUG 0
#define TEST_STI 0 #define TEST_STI 0
...@@ -289,10 +303,11 @@ static int autoprobe[] = ...@@ -289,10 +303,11 @@ static int autoprobe[] =
{ {
CDROM_PORT, SBPRO, /* probe with user's setup first */ CDROM_PORT, SBPRO, /* probe with user's setup first */
0x230, 1, /* Soundblaster Pro and 16 (default) */ 0x230, 1, /* Soundblaster Pro and 16 (default) */
0x300, 0, /* CI-101P (default), Galaxy (default), Reveal (one default) */ 0x300, 0, /* CI-101P (default), WDH-7001C (default),
Galaxy (default), Reveal (one default) */
0x250, 1, /* OmniCD default, Soundblaster Pro and 16 */ 0x250, 1, /* OmniCD default, Soundblaster Pro and 16 */
0x260, 1, /* OmniCD */ 0x260, 1, /* OmniCD */
0x320, 0, /* Lasermate, CI-101P, Galaxy, Reveal (other default) */ 0x320, 0, /* Lasermate, CI-101P, WDH-7001C, Galaxy, Reveal (other default) */
0x340, 0, /* Lasermate, CI-101P */ 0x340, 0, /* Lasermate, CI-101P */
0x360, 0, /* Lasermate, CI-101P */ 0x360, 0, /* Lasermate, CI-101P */
0x270, 1, /* Soundblaster 16 */ 0x270, 1, /* Soundblaster 16 */
...@@ -304,11 +319,11 @@ static int autoprobe[] = ...@@ -304,11 +319,11 @@ static int autoprobe[] =
0x350, 2, /* SPEA Media FX */ 0x350, 2, /* SPEA Media FX */
#if 0 #if 0
/* some "hazardous" locations (ethernet cards) */ /* some "hazardous" locations (ethernet cards) */
0x330, 0, /* Lasermate, CI-101P */ 0x330, 0, /* Lasermate, CI-101P, WDH-7001C */
0x350, 0, /* Lasermate, CI-101P */ 0x350, 0, /* Lasermate, CI-101P */
0x370, 0, /* Lasermate, CI-101P */ 0x370, 0, /* Lasermate, CI-101P */
0x290, 1, /* Soundblaster 16 */ 0x290, 1, /* Soundblaster 16 */
0x310, 0, /* Lasermate, CI-101P */ 0x310, 0, /* Lasermate, CI-101P, WDH-7001C */
/* excluded due to incomplete address decoding of the SbPro card */ /* excluded due to incomplete address decoding of the SbPro card */
0x630, 0, /* "sound card #9" (default) */ 0x630, 0, /* "sound card #9" (default) */
0x650, 0, /* "sound card #9" */ 0x650, 0, /* "sound card #9" */
...@@ -323,8 +338,9 @@ static int autoprobe[] = ...@@ -323,8 +338,9 @@ static int autoprobe[] =
* the forward references: * the forward references:
*/ */
static void sbp_read_cmd(void); static void sbp_read_cmd(void);
static int sbp_data(void); static int sbp_data(void);
static int cmd_out(void); static int cmd_out(void);
static int DiskInfo(void);
/*==========================================================================*/ /*==========================================================================*/
...@@ -370,12 +386,7 @@ static int sbpcd_debug = (1<<DBG_INF) | ...@@ -370,12 +386,7 @@ static int sbpcd_debug = (1<<DBG_INF) |
#else #else
static int sbpcd_debug = (1<<DBG_INF) | static int sbpcd_debug = (1<<DBG_INF) |
(1<<DBG_TOC) | (1<<DBG_TOC) |
(1<<DBG_UPC) | (1<<DBG_UPC);
(1<<DBG_TIM) |
(1<<DBG_LCK) |
(1<<DBG_CHK) |
(1<<DBG_AUD) |
(1<<DBG_IOX);
#endif #endif
#endif #endif
static int sbpcd_ioaddr = CDROM_PORT; /* default I/O base address */ static int sbpcd_ioaddr = CDROM_PORT; /* default I/O base address */
...@@ -404,7 +415,8 @@ static struct wait_queue *sbp_waitq = NULL; ...@@ -404,7 +415,8 @@ static struct wait_queue *sbp_waitq = NULL;
/*==========================================================================*/ /*==========================================================================*/
#define SBP_BUFFER_FRAMES 4 /* driver's own read_ahead */ #define SBP_BUFFER_FRAMES 4 /* driver's own read_ahead, data mode */
#define SBP_BUFFER_AUDIO_FRAMES 4 /* driver's own read_ahead, read audio mode */
/*==========================================================================*/ /*==========================================================================*/
...@@ -419,6 +431,7 @@ static u_char infobuf[20]; ...@@ -419,6 +431,7 @@ static u_char infobuf[20];
static u_char xa_head_buf[CD_XA_HEAD]; static u_char xa_head_buf[CD_XA_HEAD];
static u_char xa_tail_buf[CD_XA_TAIL]; static u_char xa_tail_buf[CD_XA_TAIL];
static u_char busy_data=0, busy_audio=0; /* true semaphores would be safer */
static u_char timed_out=0; static u_char timed_out=0;
static u_int datarate= 1000000; static u_int datarate= 1000000;
static u_int maxtim16=16000000; static u_int maxtim16=16000000;
...@@ -460,11 +473,8 @@ static struct { ...@@ -460,11 +473,8 @@ static struct {
int sbp_current; /* Frame being currently read */ int sbp_current; /* Frame being currently read */
u_char mode; /* read_mode: READ_M1, READ_M2, READ_SC, READ_AU */ u_char mode; /* read_mode: READ_M1, READ_M2, READ_SC, READ_AU */
#if READ_AUDIO
u_char *aud_buf; /* Pointer to audio data buffer, u_char *aud_buf; /* Pointer to audio data buffer,
space allocated during sbpcd_init() */ space allocated during sbpcd_init() */
#endif READ_AUDIO
u_char drv_type; u_char drv_type;
u_char drv_options; u_char drv_options;
u_char status_byte; u_char status_byte;
...@@ -671,22 +681,34 @@ static int msf2blk(int msfx) ...@@ -671,22 +681,34 @@ static int msf2blk(int msfx)
return (i); return (i);
} }
/*==========================================================================*/ /*==========================================================================*/
/*
* convert m-s-f_number (3 bytes only) to logical_block_address
*/
static int msf2lba(u_char *msf)
{
int i;
i=(msf[0] * CD_SECS + msf[1]) * CD_FRAMES + msf[2] - CD_BLOCK_OFFSET;
if (i<0) return (0);
return (i);
}
/*==========================================================================*/
/* evaluate xx_ReadError code (still mysterious) */ /* evaluate xx_ReadError code (still mysterious) */
static int sta2err(int sta) static int sta2err(int sta)
{ {
if (sta<=2) return (sta); if (sta<=2) return (sta);
if (sta==0x05) return (-4); if (sta==0x05) return (-4); /* CRC error */
if (sta==0x06) return (-6); if (sta==0x06) return (-6); /* seek error */
if (sta==0x0d) return (-6); if (sta==0x0d) return (-6); /* seek error */
if (sta==0x0e) return (-3); if (sta==0x0e) return (-3); /* unknown command */
if (sta==0x14) return (-3); if (sta==0x14) return (-3); /* unknown command */
if (sta==0x0c) return (-11); if (sta==0x0c) return (-11); /* read fault */
if (sta==0x0f) return (-11); if (sta==0x0f) return (-11); /* read fault */
if (sta==0x10) return (-11); if (sta==0x10) return (-11); /* read fault */
if (sta>=0x16) return (-12); if (sta>=0x16) return (-12); /* general failure */
DriveStruct[d].CD_changed=0xFF; DriveStruct[d].CD_changed=0xFF;
if (sta==0x11) return (-15); if (sta==0x11) return (-15); /* invalid disk change */
return (-2); return (-2); /* drive not ready */
} }
/*==========================================================================*/ /*==========================================================================*/
static void clr_cmdbuf(void) static void clr_cmdbuf(void)
...@@ -1208,6 +1230,7 @@ static int xy_DriveReset(void) ...@@ -1208,6 +1230,7 @@ static int xy_DriveReset(void)
response_count=0; response_count=0;
i=cmd_out(); i=cmd_out();
} }
sbp_sleep(100); /* wait a second */
flush_status(); flush_status();
i=GetStatus(); i=GetStatus();
if (i>=0) return -1; if (i>=0) return -1;
...@@ -1244,7 +1267,7 @@ static int DriveReset(void) ...@@ -1244,7 +1267,7 @@ static int DriveReset(void)
} }
while (!st_diskok); while (!st_diskok);
DriveStruct[d].CD_changed=1; DriveStruct[d].CD_changed=1;
i=SetSpeed(); i=DiskInfo();
if (i<0) return (-2); if (i<0) return (-2);
return (0); return (0);
} }
...@@ -1730,13 +1753,13 @@ static int yy_CheckMultiSession(void) ...@@ -1730,13 +1753,13 @@ static int yy_CheckMultiSession(void)
/*==========================================================================*/ /*==========================================================================*/
#if FUTURE #if FUTURE
static int yy_SubChanInfo(int frame, int count, u_char *buffer) static int yy_SubChanInfo(int frame, int count, u_char *buffer)
/* "frame" is a RED BOOK address */ /* "frame" is a RED BOOK (msf-bin) address */
{ {
int i; int i;
if (!new_drive) return (-3); if (!new_drive) return (-ENOSYS); /* drive firmware lacks it */
#if 0 #if 0
if (DriveStruct[d].audio_state!=audio_playing) return (-2); if (DriveStruct[d].audio_state!=audio_playing) return (-ENODATA);
#endif #endif
clr_cmdbuf(); clr_cmdbuf();
drvcmd[0]=0x11; drvcmd[0]=0x11;
...@@ -1748,7 +1771,7 @@ static int yy_SubChanInfo(int frame, int count, u_char *buffer) ...@@ -1748,7 +1771,7 @@ static int yy_SubChanInfo(int frame, int count, u_char *buffer)
flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check; flags_cmd_out=f_putcmd|f_respo2|f_ResponseStatus|f_obey_p_check;
cmd_type=READ_SC; cmd_type=READ_SC;
DriveStruct[d].frame_size=CD_FRAMESIZE_SUB; DriveStruct[d].frame_size=CD_FRAMESIZE_SUB;
i=cmd_out(); /* read directly into user's buffer */ i=cmd_out(); /* which buffer to use? */
return (i); return (i);
} }
#endif FUTURE #endif FUTURE
...@@ -2076,7 +2099,7 @@ static int ReadToC(void) ...@@ -2076,7 +2099,7 @@ static int ReadToC(void)
/* fake entry for LeadOut Track */ /* fake entry for LeadOut Track */
DriveStruct[d].TocBuffer[j].nixbyte=0; DriveStruct[d].TocBuffer[j].nixbyte=0;
DriveStruct[d].TocBuffer[j].ctl_adr=0; DriveStruct[d].TocBuffer[j].ctl_adr=0;
DriveStruct[d].TocBuffer[j].number=0; DriveStruct[d].TocBuffer[j].number=CDROM_LEADOUT;
DriveStruct[d].TocBuffer[j].format=0; DriveStruct[d].TocBuffer[j].format=0;
DriveStruct[d].TocBuffer[j].address=DriveStruct[d].size_msf; DriveStruct[d].TocBuffer[j].address=DriveStruct[d].size_msf;
...@@ -2088,9 +2111,7 @@ static int DiskInfo(void) ...@@ -2088,9 +2111,7 @@ static int DiskInfo(void)
{ {
int i, j; int i, j;
#if READ_AUDIO
DriveStruct[d].mode=READ_M1; DriveStruct[d].mode=READ_M1;
#endif READ_AUDIO
#undef LOOP_COUNT #undef LOOP_COUNT
#define LOOP_COUNT 20 /* needed for some "old" drives */ #define LOOP_COUNT 20 /* needed for some "old" drives */
...@@ -2579,7 +2600,6 @@ static int SBPCD_IOCTL(struct inode *inode, struct file *file, u_int cmd, ...@@ -2579,7 +2600,6 @@ static int SBPCD_IOCTL(struct inode *inode, struct file *file, u_int cmd,
DriveStruct[d].mode=READ_M2; DriveStruct[d].mode=READ_M2;
return (0); return (0);
#if READ_AUDIO
case CDROMREADAUDIO: case CDROMREADAUDIO:
{ /* start of CDROMREADAUDIO */ { /* start of CDROMREADAUDIO */
int i=0, j=0, frame, block; int i=0, j=0, frame, block;
...@@ -2596,21 +2616,30 @@ static int SBPCD_IOCTL(struct inode *inode, struct file *file, u_int cmd, ...@@ -2596,21 +2616,30 @@ static int SBPCD_IOCTL(struct inode *inode, struct file *file, u_int cmd,
DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMREADAUDIO requested.\n")); DPRINTF((DBG_IOC,"SBPCD: ioctl: CDROMREADAUDIO requested.\n"));
#if 0
if (!new_drive) return (-EINVAL);
#endif
if (DriveStruct[d].aud_buf==NULL) return (-EINVAL);
i=verify_area(VERIFY_READ, (void *) arg, sizeof(struct cdrom_read_audio)); i=verify_area(VERIFY_READ, (void *) arg, sizeof(struct cdrom_read_audio));
if (i) return (i); if (i) return (i);
memcpy_fromfs(&read_audio, (void *) arg, sizeof(struct cdrom_read_audio)); memcpy_fromfs(&read_audio, (void *) arg, sizeof(struct cdrom_read_audio));
i=verify_area(VERIFY_WRITE, read_audio.buf, CD_FRAMESIZE_RAW); if (read_audio.nframes>SBP_BUFFER_AUDIO_FRAMES) return (-EINVAL);
i=verify_area(VERIFY_WRITE, read_audio.buf,
read_audio.nframes*CD_FRAMESIZE_RAW);
if (i) return (i); if (i) return (i);
if (read_audio.addr_format==CDROM_MSF) /* MSF-bin specification of where to start */ if (read_audio.addr_format==CDROM_MSF) /* MSF-bin specification of where to start */
block=msf2blk(read_audio.addr.lba); block=msf2lba(&read_audio.addr.msf.minute);
else if (read_audio.addr_format==CDROM_LBA) /* lba specification of where to start */ else if (read_audio.addr_format==CDROM_LBA) /* lba specification of where to start */
block=read_audio.addr.lba; block=read_audio.addr.lba;
else return (-EINVAL); else return (-EINVAL);
if (read_audio.nframes!=1) return (-EINVAL);
DPRINTF((DBG_AUD,"SBPCD: read_audio: lba: %d, msf: %06X\n", DPRINTF((DBG_AUD,"SBPCD: read_audio: lba: %d, msf: %06X\n",
block, blk2msf(block))); block, blk2msf(block)));
DPRINTF((DBG_AUD,"SBPCD: read_audio: before xx_ReadStatus.\n")); DPRINTF((DBG_AUD,"SBPCD: read_audio: before xx_ReadStatus.\n"));
while (busy_data) sbp_sleep(10); /* wait a bit */
busy_audio=1;
for (data_tries=5; data_tries>0; data_tries--) for (data_tries=5; data_tries>0; data_tries--)
{ {
DPRINTF((DBG_AUD,"SBPCD: data_tries=%d ...\n", data_tries)); DPRINTF((DBG_AUD,"SBPCD: data_tries=%d ...\n", data_tries));
...@@ -2641,7 +2670,7 @@ static int SBPCD_IOCTL(struct inode *inode, struct file *file, u_int cmd, ...@@ -2641,7 +2670,7 @@ static int SBPCD_IOCTL(struct inode *inode, struct file *file, u_int cmd,
drvcmd[2]=(block>>8)&0x000000ff; drvcmd[2]=(block>>8)&0x000000ff;
drvcmd[3]=block&0x000000ff; drvcmd[3]=block&0x000000ff;
drvcmd[4]=0; drvcmd[4]=0;
drvcmd[5]=1; /* # of frames */ drvcmd[5]=read_audio.nframes; /* # of frames */
drvcmd[6]=0; drvcmd[6]=0;
} }
else /* if new_drive */ else /* if new_drive */
...@@ -2692,7 +2721,13 @@ static int SBPCD_IOCTL(struct inode *inode, struct file *file, u_int cmd, ...@@ -2692,7 +2721,13 @@ static int SBPCD_IOCTL(struct inode *inode, struct file *file, u_int cmd,
error_flag=0; error_flag=0;
p = DriveStruct[d].aud_buf; p = DriveStruct[d].aud_buf;
if (sbpro_type==1) OUT(CDo_sel_d_i,0x01); if (sbpro_type==1) OUT(CDo_sel_d_i,0x01);
READ_DATA(CDi_data, p, CD_FRAMESIZE_RAW); #if 0
cli();
#endif
READ_DATA(CDi_data, p, read_audio.nframes*CD_FRAMESIZE_RAW);
#if 0
sti();
#endif
if (sbpro_type==1) OUT(CDo_sel_d_i,0x00); if (sbpro_type==1) OUT(CDo_sel_d_i,0x00);
data_retrying = 0; data_retrying = 0;
} }
...@@ -2747,13 +2782,15 @@ static int SBPCD_IOCTL(struct inode *inode, struct file *file, u_int cmd, ...@@ -2747,13 +2782,15 @@ static int SBPCD_IOCTL(struct inode *inode, struct file *file, u_int cmd,
continue; continue;
} }
memcpy_tofs((u_char *) read_audio.buf, memcpy_tofs((u_char *) read_audio.buf,
(u_char *) DriveStruct[d].aud_buf, CD_FRAMESIZE_RAW); (u_char *) DriveStruct[d].aud_buf,
read_audio.nframes*CD_FRAMESIZE_RAW);
DPRINTF((DBG_AUD,"SBPCD: read_audio: memcpy_tofs done.\n")); DPRINTF((DBG_AUD,"SBPCD: read_audio: memcpy_tofs done.\n"));
break; break;
} }
xx_ModeSelect(CD_FRAMESIZE); xx_ModeSelect(CD_FRAMESIZE);
xx_ModeSense(); xx_ModeSense();
DriveStruct[d].mode=READ_M1; DriveStruct[d].mode=READ_M1;
busy_audio=0;
if (data_tries == 0) if (data_tries == 0)
{ {
DPRINTF((DBG_AUD,"SBPCD: read_audio: failed after 5 tries.\n")); DPRINTF((DBG_AUD,"SBPCD: read_audio: failed after 5 tries.\n"));
...@@ -2762,7 +2799,6 @@ static int SBPCD_IOCTL(struct inode *inode, struct file *file, u_int cmd, ...@@ -2762,7 +2799,6 @@ static int SBPCD_IOCTL(struct inode *inode, struct file *file, u_int cmd,
DPRINTF((DBG_AUD,"SBPCD: read_audio: successful return.\n")); DPRINTF((DBG_AUD,"SBPCD: read_audio: successful return.\n"));
return (0); return (0);
} /* end of CDROMREADAUDIO */ } /* end of CDROMREADAUDIO */
#endif READ_AUDIO
case BLKRASET: case BLKRASET:
if(!suser()) return -EACCES; if(!suser()) return -EACCES;
...@@ -2811,14 +2847,14 @@ static void DO_SBPCD_REQUEST(void) ...@@ -2811,14 +2847,14 @@ static void DO_SBPCD_REQUEST(void)
sti(); sti();
if ((CURRENT==NULL)||(CURRENT->dev<0)) return; if ((CURRENT==NULL)||(CURRENT->dev<0)) goto done;
if (CURRENT -> sector == -1) return; if (CURRENT -> sector == -1) goto done;
dev = MINOR(CURRENT->dev); dev = MINOR(CURRENT->dev);
if ( (dev<0) || (dev>=NR_SBPCD) ) if ( (dev<0) || (dev>=NR_SBPCD) )
{ {
printk("SBPCD: do_request: bad device: %d\n", dev); printk("SBPCD: do_request: bad device: %d\n", dev);
return; goto done;
} }
switch_drive(dev); switch_drive(dev);
...@@ -2847,6 +2883,9 @@ static void DO_SBPCD_REQUEST(void) ...@@ -2847,6 +2883,9 @@ static void DO_SBPCD_REQUEST(void)
if (i!=0) if (i!=0)
DPRINTF((DBG_INF,"SBPCD: \"prepare\" tells error %d -- ignored\n", i)); DPRINTF((DBG_INF,"SBPCD: \"prepare\" tells error %d -- ignored\n", i));
while (busy_audio) sbp_sleep(100); /* wait a bit */
busy_data=1;
if (!st_spinning) xx_SpinUp(); if (!st_spinning) xx_SpinUp();
#ifdef XA_TEST1 #ifdef XA_TEST1
...@@ -2884,6 +2923,10 @@ static void DO_SBPCD_REQUEST(void) ...@@ -2884,6 +2923,10 @@ static void DO_SBPCD_REQUEST(void)
end_request(0); end_request(0);
sbp_sleep(10); /* wait a bit, try again */ sbp_sleep(10); /* wait a bit, try again */
goto request_loop; goto request_loop;
done:
busy_data=0;
return;
} }
/*==========================================================================*/ /*==========================================================================*/
/* /*
...@@ -2904,13 +2947,13 @@ static void sbp_read_cmd(void) ...@@ -2904,13 +2947,13 @@ static void sbp_read_cmd(void)
DPRINTF((DBG_MUL,"SBPCD: read MSF %08X\n", blk2msf(block))); DPRINTF((DBG_MUL,"SBPCD: read MSF %08X\n", blk2msf(block)));
if ( (DriveStruct[d].f_multisession) && (multisession_valid) ) if ( (DriveStruct[d].f_multisession) && (multisession_valid) )
{ {
DPRINTF((DBG_MUL,"SBPCD: MultiSession: use %08X for %08X (msf)\n", DPRINTF((DBG_MUL,"SBPCD: ManySession: use %08X for %08X (msf)\n",
blk2msf(DriveStruct[d].lba_multi+block), blk2msf(DriveStruct[d].lba_multi+block),
blk2msf(block))); blk2msf(block)));
block=DriveStruct[d].lba_multi+block; block=DriveStruct[d].lba_multi+block;
} }
#else #else
if ( (block==CD_BLOCK_OFFSET+16) && (DriveStruct[d].f_multisession) && (multisession_valid) ) if ( (block==16) && (DriveStruct[d].f_multisession) && (multisession_valid) )
{ {
DPRINTF((DBG_MUL,"SBPCD: MultiSession: use %08X for %08X (msf)\n", DPRINTF((DBG_MUL,"SBPCD: MultiSession: use %08X for %08X (msf)\n",
blk2msf(DriveStruct[d].lba_multi+16), blk2msf(DriveStruct[d].lba_multi+16),
...@@ -3418,6 +3461,9 @@ unsigned long SBPCD_INIT(u_long mem_start, u_long mem_end) ...@@ -3418,6 +3461,9 @@ unsigned long SBPCD_INIT(u_long mem_start, u_long mem_end)
check_datarate(); check_datarate();
DPRINTF((DBG_INI,"SBPCD: check_datarate done.\n")); DPRINTF((DBG_INI,"SBPCD: check_datarate done.\n"));
OUT(CDo_reset,0);
sbp_sleep(100);
for (j=0;j<NR_SBPCD;j++) for (j=0;j<NR_SBPCD;j++)
{ {
if (DriveStruct[j].drv_minor==-1) continue; if (DriveStruct[j].drv_minor==-1) continue;
...@@ -3484,10 +3530,12 @@ unsigned long SBPCD_INIT(u_long mem_start, u_long mem_end) ...@@ -3484,10 +3530,12 @@ unsigned long SBPCD_INIT(u_long mem_start, u_long mem_end)
*/ */
DriveStruct[j].sbp_buf=(u_char *)mem_start; DriveStruct[j].sbp_buf=(u_char *)mem_start;
mem_start += SBP_BUFFER_FRAMES*CD_FRAMESIZE; mem_start += SBP_BUFFER_FRAMES*CD_FRAMESIZE;
#if READ_AUDIO if (new_drive)
DriveStruct[j].aud_buf=(u_char *)mem_start; {
mem_start += CD_FRAMESIZE_RAW; DriveStruct[j].aud_buf=(u_char *)mem_start;
#endif READ_AUDIO mem_start += SBP_BUFFER_AUDIO_FRAMES*CD_FRAMESIZE_RAW;
}
else DriveStruct[j].aud_buf=NULL;
/* /*
* set the block size * set the block size
*/ */
......
...@@ -29,25 +29,6 @@ ...@@ -29,25 +29,6 @@
#include <asm/segment.h> #include <asm/segment.h>
#include <asm/io.h> #include <asm/io.h>
#ifdef CONFIG_SCSI
#ifdef CONFIG_BLK_DEV_SR
extern int check_cdrom_media_change(int, int);
#endif
#ifdef CONFIG_BLK_DEV_SD
extern int check_scsidisk_media_change(int, int);
extern int revalidate_scsidisk(int, int);
#endif
#endif
#ifdef CONFIG_CDU31A
extern int check_cdu31a_media_change(int, int);
#endif
#ifdef CONFIG_MCD
extern int check_mcd_media_change(int, int);
#endif
#ifdef CONFIG_SBPCD
extern int check_sbpcd_media_change(int, int);
#endif
#define NR_SIZES 4 #define NR_SIZES 4
static char buffersize_index[9] = {-1, 0, 1, -1, 2, -1, -1, -1, 3}; static char buffersize_index[9] = {-1, 0, 1, -1, 2, -1, -1, -1, 3};
static short int bufferindex_size[NR_SIZES] = {512, 1024, 2048, 4096}; static short int bufferindex_size[NR_SIZES] = {512, 1024, 2048, 4096};
...@@ -286,85 +267,6 @@ void invalidate_buffers(dev_t dev) ...@@ -286,85 +267,6 @@ void invalidate_buffers(dev_t dev)
} }
} }
/*
* This routine checks whether a floppy has been changed, and
* invalidates all buffer-cache-entries in that case. This
* is a relatively slow routine, so we have to try to minimize using
* it. Thus it is called only upon a 'mount' or 'open'. This
* is the best way of combining speed and utility, I think.
* People changing diskettes in the middle of an operation deserve
* to loose :-)
*
* NOTE! Although currently this is only for floppies, the idea is
* that any additional removable block-device will use this routine,
* and that mount/open needn't know that floppies/whatever are
* special.
*/
void check_disk_change(dev_t dev)
{
int i;
struct buffer_head * bh;
switch(MAJOR(dev)){
case FLOPPY_MAJOR:
if (!(bh = getblk(dev,0,1024)))
return;
i = floppy_change(bh);
brelse(bh);
break;
#if defined(CONFIG_BLK_DEV_SD) && defined(CONFIG_SCSI)
case SCSI_DISK_MAJOR:
i = check_scsidisk_media_change(dev, 0);
break;
#endif
#if defined(CONFIG_BLK_DEV_SR) && defined(CONFIG_SCSI)
case SCSI_CDROM_MAJOR:
i = check_cdrom_media_change(dev, 0);
break;
#endif
#if defined(CONFIG_CDU31A)
case CDU31A_CDROM_MAJOR:
i = check_cdu31a_media_change(dev, 0);
break;
#endif
#if defined(CONFIG_MCD)
case MITSUMI_CDROM_MAJOR:
i = check_mcd_media_change(dev, 0);
break;
#endif
#if defined(CONFIG_SBPCD)
case MATSUSHITA_CDROM_MAJOR:
i = check_sbpcd_media_change(dev, 0);
break;
#endif
default:
return;
};
if (!i) return;
printk("VFS: Disk change detected on device %d/%d\n",
MAJOR(dev), MINOR(dev));
for (i=0 ; i<NR_SUPER ; i++)
if (super_blocks[i].s_dev == dev)
put_super(super_blocks[i].s_dev);
invalidate_inodes(dev);
invalidate_buffers(dev);
#if defined(CONFIG_BLK_DEV_SD) && defined(CONFIG_SCSI)
/* This is trickier for a removable hardisk, because we have to invalidate
all of the partitions that lie on the disk. */
if (MAJOR(dev) == SCSI_DISK_MAJOR)
revalidate_scsidisk(dev, 0);
#endif
}
#define _hashfn(dev,block) (((unsigned)(dev^block))%nr_hash) #define _hashfn(dev,block) (((unsigned)(dev^block))%nr_hash)
#define hash(dev,block) hash_table[_hashfn(dev,block)] #define hash(dev,block) hash_table[_hashfn(dev,block)]
......
...@@ -15,6 +15,29 @@ ...@@ -15,6 +15,29 @@
#include <linux/fcntl.h> #include <linux/fcntl.h>
#include <linux/errno.h> #include <linux/errno.h>
/*
* Ugly. We'll fix this once all the drivers use the f_ops->check_media_change()
* stuff instead..
*/
#ifdef CONFIG_SCSI
#ifdef CONFIG_BLK_DEV_SR
extern int check_cdrom_media_change(int, int);
#endif
#ifdef CONFIG_BLK_DEV_SD
extern int check_scsidisk_media_change(int, int);
extern int revalidate_scsidisk(int, int);
#endif
#endif
#ifdef CONFIG_CDU31A
extern int check_cdu31a_media_change(int, int);
#endif
#ifdef CONFIG_MCD
extern int check_mcd_media_change(int, int);
#endif
#ifdef CONFIG_SBPCD
extern int check_sbpcd_media_change(int, int);
#endif
struct device_struct { struct device_struct {
const char * name; const char * name;
struct file_operations * fops; struct file_operations * fops;
...@@ -110,6 +133,88 @@ int unregister_blkdev(unsigned int major, const char * name) ...@@ -110,6 +133,88 @@ int unregister_blkdev(unsigned int major, const char * name)
return 0; return 0;
} }
/*
* This routine checks whether a removable media has been changed,
* and invalidates all buffer-cache-entries in that case. This
* is a relatively slow routine, so we have to try to minimize using
* it. Thus it is called only upon a 'mount' or 'open'. This
* is the best way of combining speed and utility, I think.
* People changing diskettes in the middle of an operation deserve
* to loose :-)
*/
void check_disk_change(dev_t dev)
{
int i;
struct file_operations * fops;
i = MAJOR(dev);
if (i >= MAX_BLKDEV || (fops = blkdevs[i].fops) == NULL)
return;
if (fops->check_media_change != NULL) {
if (!fops->check_media_change(dev))
return;
}
#if 1 /* this will go soon.. */
else switch(MAJOR(dev)){
#if defined(CONFIG_BLK_DEV_SD) && defined(CONFIG_SCSI)
case SCSI_DISK_MAJOR:
if (!check_scsidisk_media_change(dev, 0))
return;
break;
#endif
#if defined(CONFIG_BLK_DEV_SR) && defined(CONFIG_SCSI)
case SCSI_CDROM_MAJOR:
if (!check_cdrom_media_change(dev, 0))
return;
break;
#endif
#if defined(CONFIG_CDU31A)
case CDU31A_CDROM_MAJOR:
if (!check_cdu31a_media_change(dev, 0))
return;
break;
#endif
#if defined(CONFIG_MCD)
case MITSUMI_CDROM_MAJOR:
if (!check_mcd_media_change(dev, 0))
return;
break;
#endif
#if defined(CONFIG_SBPCD)
case MATSUSHITA_CDROM_MAJOR:
if (!check_sbpcd_media_change(dev, 0))
return;
break;
#endif
default:
return;
}
#endif /* will go away */
printk("VFS: Disk change detected on device %d/%d\n",
MAJOR(dev), MINOR(dev));
for (i=0 ; i<NR_SUPER ; i++)
if (super_blocks[i].s_dev == dev)
put_super(super_blocks[i].s_dev);
invalidate_inodes(dev);
invalidate_buffers(dev);
if (fops->revalidate)
fops->revalidate(dev);
#if defined(CONFIG_BLK_DEV_SD) && defined(CONFIG_SCSI)
/* This is trickier for a removable hardisk, because we have to invalidate
all of the partitions that lie on the disk. */
if (MAJOR(dev) == SCSI_DISK_MAJOR)
revalidate_scsidisk(dev, 0);
#endif
}
/* /*
* Called every time a block special file is opened * Called every time a block special file is opened
*/ */
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
/* /*
* some fix numbers * some fix numbers
*/ */
#define CD_MINS 75 /* minutes per CD */ #define CD_MINS 74 /* max. minutes per CD */
#define CD_SECS 60 /* seconds per minute */ #define CD_SECS 60 /* seconds per minute */
#define CD_FRAMES 75 /* frames per second */ #define CD_FRAMES 75 /* frames per second */
#define CD_FRAMESIZE 2048 /* bytes per frame, cooked mode */ #define CD_FRAMESIZE 2048 /* bytes per frame, cooked mode */
...@@ -238,9 +238,8 @@ struct cdrom_tocentry ...@@ -238,9 +238,8 @@ struct cdrom_tocentry
/* /*
* CD-ROM address types (cdrom_tocentry.cdte_format) * CD-ROM address types (cdrom_tocentry.cdte_format)
*/ */
#define CDROM_LBA 0x01 /* "logical block": first frame is #0 */
#define CDROM_LBA 0x01 #define CDROM_MSF 0x02 /* "minute-second-frame": binary, not bcd here! */
#define CDROM_MSF 0x02
/* /*
* bit to tell whether track is data or audio * bit to tell whether track is data or audio
...@@ -328,7 +327,7 @@ struct cdrom_read_audio ...@@ -328,7 +327,7 @@ struct cdrom_read_audio
int lba; int lba;
} addr; /* frame address */ } addr; /* frame address */
u_char addr_format; /* CDROM_LBA or CDROM_MSF */ u_char addr_format; /* CDROM_LBA or CDROM_MSF */
int nframes; /* number of 2352-byte-frames to read at once, currently only 1 allowed */ int nframes; /* number of 2352-byte-frames to read at once, limited by the drivers */
u_char *buf; /* frame buffer (size: nframes*2352 bytes) */ u_char *buf; /* frame buffer (size: nframes*2352 bytes) */
}; };
...@@ -366,7 +365,7 @@ struct cdrom_read_audio ...@@ -366,7 +365,7 @@ struct cdrom_read_audio
/* vlume control */ /* vlume control */
#define CDROMSUBCHNL 0x530b /* (struct cdrom_subchnl) */ #define CDROMSUBCHNL 0x530b /* (struct cdrom_subchnl) */
/* read sub-channel data */ /* read Q sub-channel data */
#define CDROMREADMODE2 0x530c /* (struct cdrom_read) */ #define CDROMREADMODE2 0x530c /* (struct cdrom_read) */
/* read type-2 data (not suppt) */ /* read type-2 data (not suppt) */
......
...@@ -292,6 +292,8 @@ struct file_operations { ...@@ -292,6 +292,8 @@ struct file_operations {
void (*release) (struct inode *, struct file *); void (*release) (struct inode *, struct file *);
int (*fsync) (struct inode *, struct file *); int (*fsync) (struct inode *, struct file *);
int (*fasync) (struct inode *, struct file *, int); int (*fasync) (struct inode *, struct file *, int);
int (*check_media_change) (dev_t dev);
int (*revalidate) (dev_t dev);
}; };
struct inode_operations { struct inode_operations {
...@@ -414,7 +416,6 @@ extern inline void mark_buffer_dirty(struct buffer_head * bh, int flag) ...@@ -414,7 +416,6 @@ extern inline void mark_buffer_dirty(struct buffer_head * bh, int flag)
extern void check_disk_change(dev_t dev); extern void check_disk_change(dev_t dev);
extern void invalidate_inodes(dev_t dev); extern void invalidate_inodes(dev_t dev);
extern void invalidate_buffers(dev_t dev); extern void invalidate_buffers(dev_t dev);
extern int floppy_change(struct buffer_head * first_block);
extern void sync_inodes(dev_t dev); extern void sync_inodes(dev_t dev);
extern void sync_dev(dev_t dev); extern void sync_dev(dev_t dev);
extern int fsync_dev(dev_t dev); extern int fsync_dev(dev_t dev);
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
#define MCD_BASE_ADDR 0x300 #define MCD_BASE_ADDR 0x300
/* *** change this to set the interrupt number */ /* *** change this to set the interrupt number */
#define MCD_INTR_NR 11 #define MCD_INTR_NR 10
/* Increase this if you get lots of timeouts */ /* Increase this if you get lots of timeouts */
#define MCD_STATUS_DELAY 100 #define MCD_STATUS_DELAY 100
......
...@@ -23,7 +23,7 @@ ...@@ -23,7 +23,7 @@
* and specify the type of your interface in SBPRO. * and specify the type of your interface in SBPRO.
* *
* SBPRO addresses typically are 0x0230 (=0x220+0x10), 0x0250, ... * SBPRO addresses typically are 0x0230 (=0x220+0x10), 0x0250, ...
* LASERMATE (CI-101P) adresses typically are 0x0300, 0x0310, ... * LASERMATE (CI-101P, WDH-7001C) adresses typically are 0x0300, 0x0310, ...
* SPEA addresses are 0x320, 0x330, 0x340, 0x350 * SPEA addresses are 0x320, 0x330, 0x340, 0x350
* there are some soundcards on the market with 0x0630, 0x0650, ... * there are some soundcards on the market with 0x0630, 0x0650, ...
* *
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment