Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
5e4a8497
Commit
5e4a8497
authored
Nov 23, 2007
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Import 1.1.24
parent
2651e5f8
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
with
265 additions
and
196 deletions
+265
-196
Makefile
Makefile
+1
-1
boot/setup.S
boot/setup.S
+2
-2
drivers/block/README.sbpcd
drivers/block/README.sbpcd
+20
-9
drivers/block/floppy.c
drivers/block/floppy.c
+26
-23
drivers/block/sbpcd.c
drivers/block/sbpcd.c
+102
-54
fs/buffer.c
fs/buffer.c
+0
-98
fs/devices.c
fs/devices.c
+105
-0
include/linux/cdrom.h
include/linux/cdrom.h
+5
-6
include/linux/fs.h
include/linux/fs.h
+2
-1
include/linux/mcd.h
include/linux/mcd.h
+1
-1
include/linux/sbpcd.h
include/linux/sbpcd.h
+1
-1
No files found.
Makefile
View file @
5e4a8497
VERSION
=
1
PATCHLEVEL
=
1
SUBLEVEL
=
2
3
SUBLEVEL
=
2
4
all
:
Version zImage
...
...
boot/setup.S
View file @
5e4a8497
...
...
@@ -825,7 +825,7 @@ idVRAM: .ascii "Stealth VRAM"
!
Number
of
modes
is
the
number
of
chip
-
specific
svga
modes
plus
the
extended
!
modes
available
on
any
vga
(
currently
2
)
moati
:
.
byte
0x0
4
,
0x23
,
0x33
moati
:
.
byte
0x0
6
,
0x23
,
0x33
,
0x22
,
0x21
moahead
:
.
byte
0x07
,
0x22
,
0x23
,
0x24
,
0x2f
,
0x34
mocandt
:
.
byte
0x04
,
0x60
,
0x61
mocirrus
:
.
byte
0x06
,
0x1f
,
0x20
,
0x22
,
0x31
...
...
@@ -844,7 +844,7 @@ mounknown: .byte 0x02
!
The
first
two
modes
are
standard
vga
modes
available
on
any
vga
.
!
mode
0
is
80
x50
and
mode
1
is
80
x28
dscati
:
.
word
0x5032
,
0x501c
,
0x8419
,
0x842c
dscati
:
.
word
0x5032
,
0x501c
,
0x8419
,
0x842c
,
0x641e
,
0x6419
dscahead
:
.
word
0x5032
,
0x501c
,
0x842c
,
0x8419
,
0x841c
,
0xa032
,
0x5042
dsccandt
:
.
word
0x5032
,
0x501c
,
0x8419
,
0x8432
dsccirrus
:
.
word
0x5032
,
0x501c
,
0x8419
,
0x842c
,
0x841e
,
0x6425
...
...
drivers/block/README.sbpcd
View file @
5e4a8497
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.
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.
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
one frame of 2352 bytes at a time. The transfer rate is as slow as 32 kB/sec.
This will get better, and the software interface may change. We have to
standardize it the day the SCSI driver supports it too.
MultiSession is supported (even my "old" CR-521 can handle it), "ManySession"
(not recommended, see below) alternatively.
Photo CDs work, too. At ftp.gwdg.de:/pub/linux/hpcdtoppm/ is Hadmut Danisch'
s
package
to
convert
photo
CD
image
files
.
up to 4 frames of 2352 bytes at once. Reading more than 1 frame at once gives
very poor quality. Reading the same frame a second time gives different data;
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.
The transfer rate with reading audio (1-frame-pieces) is as slow as 32 kB/sec.
This could be better reading bigger chunks, but the out-of-sync parts occur at
the beginning of each single frame.
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
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;
}
/*===================== 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:
---------------
...
...
drivers/block/floppy.c
View file @
5e4a8497
...
...
@@ -407,7 +407,7 @@ void request_done(int uptodate)
* to the desired drive, but it will probably not survive the sleep if
* 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
);
...
...
@@ -1289,14 +1289,13 @@ static int floppy_open(struct inode * inode, struct file * filp)
int
drive
;
int
old_dev
;
if
(
floppy_grab_irq_and_dma
())
{
return
-
EBUSY
;
}
drive
=
inode
->
i_rdev
&
3
;
old_dev
=
fd_device
[
drive
];
if
(
fd_ref
[
drive
])
if
(
old_dev
!=
inode
->
i_rdev
)
return
-
EBUSY
;
if
(
floppy_grab_irq_and_dma
())
return
-
EBUSY
;
fd_ref
[
drive
]
++
;
fd_device
[
drive
]
=
inode
->
i_rdev
;
buffer_drive
=
buffer_track
=
-
1
;
...
...
@@ -1309,7 +1308,7 @@ static int floppy_open(struct inode * inode, struct file * filp)
static
void
floppy_release
(
struct
inode
*
inode
,
struct
file
*
filp
)
{
sync_dev
(
inode
->
i_rdev
);
f
sync_dev
(
inode
->
i_rdev
);
if
(
!
fd_ref
[
inode
->
i_rdev
&
3
]
--
)
{
printk
(
"floppy_release with fd_ref == 0"
);
fd_ref
[
inode
->
i_rdev
&
3
]
=
0
;
...
...
@@ -1317,6 +1316,18 @@ static void floppy_release(struct inode * inode, struct file * filp)
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
=
{
NULL
,
/* lseek - default */
block_read
,
/* read - general block-dev read */
...
...
@@ -1327,26 +1338,13 @@ static struct file_operations floppy_fops = {
NULL
,
/* mmap */
floppy_open
,
/* open */
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
)
{
void
(
*
handler
)(
void
)
=
DEVICE_INTR
;
...
...
@@ -1381,7 +1379,6 @@ void floppy_init(void)
timer_active
&=
~
(
1
<<
FLOPPY_TIMER
);
config_types
();
/* Try to determine the floppy controller type */
DEVICE_INTR
=
ignore_interrupt
;
/* don't ask ... */
output_byte
(
FD_VERSION
);
/* get FDC version code */
if
(
result
()
!=
1
)
{
printk
(
DEVICE_NAME
": FDC failed to return version byte
\n
"
);
...
...
@@ -1404,8 +1401,12 @@ void floppy_init(void)
}
}
static
int
usage_count
=
0
;
static
int
floppy_grab_irq_and_dma
(
void
)
{
if
(
usage_count
++
)
return
0
;
if
(
irqaction
(
FLOPPY_IRQ
,
&
floppy_sigaction
))
{
printk
(
"Unable to grab IRQ%d for the floppy driver
\n
"
,
FLOPPY_IRQ
);
return
-
1
;
...
...
@@ -1421,6 +1422,8 @@ static int floppy_grab_irq_and_dma(void)
static
void
floppy_release_irq_and_dma
(
void
)
{
if
(
--
usage_count
)
return
;
disable_dma
(
FLOPPY_DMA
);
free_dma
(
FLOPPY_DMA
);
disable_irq
(
FLOPPY_IRQ
);
...
...
drivers/block/sbpcd.c
View file @
5e4a8497
...
...
@@ -5,7 +5,7 @@
* and for "no-sound" interfaces like Lasermate and the
* 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
* and with the new CR-562-B V0.75 on a "naked" Panasonic
* CI-101P interface. And vice versa.
...
...
@@ -106,6 +106,21 @@
* reset the drive and do again. Needs lots of resets here and sometimes
* 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
* elaborated speed-up experiments (and the fabulous results!), for
* the "push" towards load-free wait loops, and for the extensive mail
...
...
@@ -172,7 +187,7 @@
#include "blk.h"
#define VERSION "2.
0
Eberhard Moenkeberg <emoenke@gwdg.de>"
#define VERSION "2.
1
Eberhard Moenkeberg <emoenke@gwdg.de>"
#define SBPCD_DEBUG
...
...
@@ -198,7 +213,6 @@
#define XA_TEST2
#define TEST_UPC 0
#define READ_AUDIO 1
#define SPEA_TEST 0
#define PRINTK_BUG 0
#define TEST_STI 0
...
...
@@ -289,10 +303,11 @@ static int autoprobe[] =
{
CDROM_PORT
,
SBPRO
,
/* probe with user's setup first */
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 */
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 */
0x360
,
0
,
/* Lasermate, CI-101P */
0x270
,
1
,
/* Soundblaster 16 */
...
...
@@ -304,11 +319,11 @@ static int autoprobe[] =
0x350
,
2
,
/* SPEA Media FX */
#if 0
/* some "hazardous" locations (ethernet cards) */
0x330, 0, /* Lasermate, CI-101P */
0x330, 0, /* Lasermate, CI-101P
, WDH-7001C
*/
0x350, 0, /* Lasermate, CI-101P */
0x370, 0, /* Lasermate, CI-101P */
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 */
0x630, 0, /* "sound card #9" (default) */
0x650, 0, /* "sound card #9" */
...
...
@@ -323,8 +338,9 @@ static int autoprobe[] =
* the forward references:
*/
static
void
sbp_read_cmd
(
void
);
static
int
sbp_data
(
void
);
static
int
sbp_data
(
void
);
static
int
cmd_out
(
void
);
static
int
DiskInfo
(
void
);
/*==========================================================================*/
...
...
@@ -370,12 +386,7 @@ static int sbpcd_debug = (1<<DBG_INF) |
#else
static
int
sbpcd_debug
=
(
1
<<
DBG_INF
)
|
(
1
<<
DBG_TOC
)
|
(
1
<<
DBG_UPC
)
|
(
1
<<
DBG_TIM
)
|
(
1
<<
DBG_LCK
)
|
(
1
<<
DBG_CHK
)
|
(
1
<<
DBG_AUD
)
|
(
1
<<
DBG_IOX
);
(
1
<<
DBG_UPC
);
#endif
#endif
static
int
sbpcd_ioaddr
=
CDROM_PORT
;
/* default I/O base address */
...
...
@@ -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];
static
u_char
xa_head_buf
[
CD_XA_HEAD
];
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_int
datarate
=
1000000
;
static
u_int
maxtim16
=
16000000
;
...
...
@@ -460,11 +473,8 @@ static struct {
int
sbp_current
;
/* Frame being currently read */
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,
space allocated during sbpcd_init() */
#endif READ_AUDIO
u_char
drv_type
;
u_char
drv_options
;
u_char
status_byte
;
...
...
@@ -671,22 +681,34 @@ static int msf2blk(int msfx)
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) */
static
int
sta2err
(
int
sta
)
{
if
(
sta
<=
2
)
return
(
sta
);
if
(
sta
==
0x05
)
return
(
-
4
);
if
(
sta
==
0x06
)
return
(
-
6
);
if
(
sta
==
0x0d
)
return
(
-
6
);
if
(
sta
==
0x0e
)
return
(
-
3
);
if
(
sta
==
0x14
)
return
(
-
3
);
if
(
sta
==
0x0c
)
return
(
-
11
);
if
(
sta
==
0x0f
)
return
(
-
11
);
if
(
sta
==
0x10
)
return
(
-
11
);
if
(
sta
>=
0x16
)
return
(
-
12
);
if
(
sta
==
0x05
)
return
(
-
4
);
/* CRC error */
if
(
sta
==
0x06
)
return
(
-
6
);
/* seek error */
if
(
sta
==
0x0d
)
return
(
-
6
);
/* seek error */
if
(
sta
==
0x0e
)
return
(
-
3
);
/* unknown command */
if
(
sta
==
0x14
)
return
(
-
3
);
/* unknown command */
if
(
sta
==
0x0c
)
return
(
-
11
);
/* read fault */
if
(
sta
==
0x0f
)
return
(
-
11
);
/* read fault */
if
(
sta
==
0x10
)
return
(
-
11
);
/* read fault */
if
(
sta
>=
0x16
)
return
(
-
12
);
/* general failure */
DriveStruct
[
d
].
CD_changed
=
0xFF
;
if
(
sta
==
0x11
)
return
(
-
15
);
return
(
-
2
);
if
(
sta
==
0x11
)
return
(
-
15
);
/* invalid disk change */
return
(
-
2
);
/* drive not ready */
}
/*==========================================================================*/
static
void
clr_cmdbuf
(
void
)
...
...
@@ -1208,6 +1230,7 @@ static int xy_DriveReset(void)
response_count
=
0
;
i
=
cmd_out
();
}
sbp_sleep
(
100
);
/* wait a second */
flush_status
();
i
=
GetStatus
();
if
(
i
>=
0
)
return
-
1
;
...
...
@@ -1244,7 +1267,7 @@ static int DriveReset(void)
}
while
(
!
st_diskok
);
DriveStruct
[
d
].
CD_changed
=
1
;
i
=
SetSpeed
();
i
=
DiskInfo
();
if
(
i
<
0
)
return
(
-
2
);
return
(
0
);
}
...
...
@@ -1730,13 +1753,13 @@ static int yy_CheckMultiSession(void)
/*==========================================================================*/
#if FUTURE
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
;
if
(
!
new_drive
)
return
(
-
3
);
if
(
!
new_drive
)
return
(
-
ENOSYS
);
/* drive firmware lacks it */
#if 0
if (DriveStruct[d].audio_state!=audio_playing) return (-
2
);
if (DriveStruct[d].audio_state!=audio_playing) return (-
ENODATA
);
#endif
clr_cmdbuf
();
drvcmd
[
0
]
=
0x11
;
...
...
@@ -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
;
cmd_type
=
READ_SC
;
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
);
}
#endif FUTURE
...
...
@@ -2076,7 +2099,7 @@ static int ReadToC(void)
/* fake entry for LeadOut Track */
DriveStruct
[
d
].
TocBuffer
[
j
].
nixbyte
=
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
].
address
=
DriveStruct
[
d
].
size_msf
;
...
...
@@ -2088,9 +2111,7 @@ static int DiskInfo(void)
{
int
i
,
j
;
#if READ_AUDIO
DriveStruct
[
d
].
mode
=
READ_M1
;
#endif READ_AUDIO
#undef LOOP_COUNT
#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,
DriveStruct
[
d
].
mode
=
READ_M2
;
return
(
0
);
#if READ_AUDIO
case
CDROMREADAUDIO
:
{
/* start of CDROMREADAUDIO */
int
i
=
0
,
j
=
0
,
frame
,
block
;
...
...
@@ -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
"
));
#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
));
if
(
i
)
return
(
i
);
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
(
read_audio
.
addr_format
==
CDROM_MSF
)
/* MSF-bin specification of where to start */
block
=
msf2
blk
(
read_audio
.
addr
.
lba
);
block
=
msf2
lba
(
&
read_audio
.
addr
.
msf
.
minute
);
else
if
(
read_audio
.
addr_format
==
CDROM_LBA
)
/* lba specification of where to start */
block
=
read_audio
.
addr
.
lba
;
else
return
(
-
EINVAL
);
if
(
read_audio
.
nframes
!=
1
)
return
(
-
EINVAL
);
DPRINTF
((
DBG_AUD
,
"SBPCD: read_audio: lba: %d, msf: %06X
\n
"
,
block
,
blk2msf
(
block
)));
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
--
)
{
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,
drvcmd
[
2
]
=
(
block
>>
8
)
&
0x000000ff
;
drvcmd
[
3
]
=
block
&
0x000000ff
;
drvcmd
[
4
]
=
0
;
drvcmd
[
5
]
=
1
;
/* # of frames */
drvcmd
[
5
]
=
read_audio
.
nframes
;
/* # of frames */
drvcmd
[
6
]
=
0
;
}
else
/* if new_drive */
...
...
@@ -2692,7 +2721,13 @@ static int SBPCD_IOCTL(struct inode *inode, struct file *file, u_int cmd,
error_flag
=
0
;
p
=
DriveStruct
[
d
].
aud_buf
;
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
);
data_retrying
=
0
;
}
...
...
@@ -2747,13 +2782,15 @@ static int SBPCD_IOCTL(struct inode *inode, struct file *file, u_int cmd,
continue
;
}
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
"
));
break
;
}
xx_ModeSelect
(
CD_FRAMESIZE
);
xx_ModeSense
();
DriveStruct
[
d
].
mode
=
READ_M1
;
busy_audio
=
0
;
if
(
data_tries
==
0
)
{
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,
DPRINTF
((
DBG_AUD
,
"SBPCD: read_audio: successful return.
\n
"
));
return
(
0
);
}
/* end of CDROMREADAUDIO */
#endif READ_AUDIO
case
BLKRASET
:
if
(
!
suser
())
return
-
EACCES
;
...
...
@@ -2811,14 +2847,14 @@ static void DO_SBPCD_REQUEST(void)
sti
();
if
((
CURRENT
==
NULL
)
||
(
CURRENT
->
dev
<
0
))
return
;
if
(
CURRENT
->
sector
==
-
1
)
return
;
if
((
CURRENT
==
NULL
)
||
(
CURRENT
->
dev
<
0
))
goto
done
;
if
(
CURRENT
->
sector
==
-
1
)
goto
done
;
dev
=
MINOR
(
CURRENT
->
dev
);
if
(
(
dev
<
0
)
||
(
dev
>=
NR_SBPCD
)
)
{
printk
(
"SBPCD: do_request: bad device: %d
\n
"
,
dev
);
return
;
goto
done
;
}
switch_drive
(
dev
);
...
...
@@ -2847,6 +2883,9 @@ static void DO_SBPCD_REQUEST(void)
if
(
i
!=
0
)
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
();
#ifdef XA_TEST1
...
...
@@ -2884,6 +2923,10 @@ static void DO_SBPCD_REQUEST(void)
end_request
(
0
);
sbp_sleep
(
10
);
/* wait a bit, try again */
goto
request_loop
;
done:
busy_data
=
0
;
return
;
}
/*==========================================================================*/
/*
...
...
@@ -2904,13 +2947,13 @@ static void sbp_read_cmd(void)
DPRINTF
((
DBG_MUL
,
"SBPCD: read MSF %08X
\n
"
,
blk2msf
(
block
)));
if
(
(
DriveStruct
[
d
].
f_multisession
)
&&
(
multisession_valid
)
)
{
DPRINTF
((
DBG_MUL
,
"SBPCD: M
ulti
Session: use %08X for %08X (msf)
\n
"
,
DPRINTF
((
DBG_MUL
,
"SBPCD: M
any
Session: use %08X for %08X (msf)
\n
"
,
blk2msf
(
DriveStruct
[
d
].
lba_multi
+
block
),
blk2msf
(
block
)));
block
=
DriveStruct
[
d
].
lba_multi
+
block
;
}
#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
"
,
blk2msf
(
DriveStruct
[
d
].
lba_multi
+
16
),
...
...
@@ -3418,6 +3461,9 @@ unsigned long SBPCD_INIT(u_long mem_start, u_long mem_end)
check_datarate
();
DPRINTF
((
DBG_INI
,
"SBPCD: check_datarate done.
\n
"
));
OUT
(
CDo_reset
,
0
);
sbp_sleep
(
100
);
for
(
j
=
0
;
j
<
NR_SBPCD
;
j
++
)
{
if
(
DriveStruct
[
j
].
drv_minor
==-
1
)
continue
;
...
...
@@ -3484,10 +3530,12 @@ unsigned long SBPCD_INIT(u_long mem_start, u_long mem_end)
*/
DriveStruct
[
j
].
sbp_buf
=
(
u_char
*
)
mem_start
;
mem_start
+=
SBP_BUFFER_FRAMES
*
CD_FRAMESIZE
;
#if READ_AUDIO
DriveStruct
[
j
].
aud_buf
=
(
u_char
*
)
mem_start
;
mem_start
+=
CD_FRAMESIZE_RAW
;
#endif READ_AUDIO
if
(
new_drive
)
{
DriveStruct
[
j
].
aud_buf
=
(
u_char
*
)
mem_start
;
mem_start
+=
SBP_BUFFER_AUDIO_FRAMES
*
CD_FRAMESIZE_RAW
;
}
else
DriveStruct
[
j
].
aud_buf
=
NULL
;
/*
* set the block size
*/
...
...
fs/buffer.c
View file @
5e4a8497
...
...
@@ -29,25 +29,6 @@
#include <asm/segment.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
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
};
...
...
@@ -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 hash(dev,block) hash_table[_hashfn(dev,block)]
...
...
fs/devices.c
View file @
5e4a8497
...
...
@@ -15,6 +15,29 @@
#include <linux/fcntl.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
{
const
char
*
name
;
struct
file_operations
*
fops
;
...
...
@@ -110,6 +133,88 @@ int unregister_blkdev(unsigned int major, const char * name)
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
*/
...
...
include/linux/cdrom.h
View file @
5e4a8497
...
...
@@ -14,7 +14,7 @@
/*
* some fix numbers
*/
#define CD_MINS 7
5
/* minutes per CD
*/
#define CD_MINS 7
4
/* max. minutes per CD
*/
#define CD_SECS 60
/* seconds per minute */
#define CD_FRAMES 75
/* frames per second */
#define CD_FRAMESIZE 2048
/* bytes per frame, cooked mode */
...
...
@@ -238,9 +238,8 @@ struct cdrom_tocentry
/*
* CD-ROM address types (cdrom_tocentry.cdte_format)
*/
#define CDROM_LBA 0x01
#define CDROM_MSF 0x02
#define CDROM_LBA 0x01
/* "logical block": first frame is #0 */
#define CDROM_MSF 0x02
/* "minute-second-frame": binary, not bcd here! */
/*
* bit to tell whether track is data or audio
...
...
@@ -328,7 +327,7 @@ struct cdrom_read_audio
int
lba
;
}
addr
;
/* frame address */
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) */
};
...
...
@@ -366,7 +365,7 @@ struct cdrom_read_audio
/* vlume control */
#define CDROMSUBCHNL 0x530b
/* (struct cdrom_subchnl) */
/* read sub-channel data */
/* read
Q
sub-channel data */
#define CDROMREADMODE2 0x530c
/* (struct cdrom_read) */
/* read type-2 data (not suppt) */
...
...
include/linux/fs.h
View file @
5e4a8497
...
...
@@ -292,6 +292,8 @@ struct file_operations {
void
(
*
release
)
(
struct
inode
*
,
struct
file
*
);
int
(
*
fsync
)
(
struct
inode
*
,
struct
file
*
);
int
(
*
fasync
)
(
struct
inode
*
,
struct
file
*
,
int
);
int
(
*
check_media_change
)
(
dev_t
dev
);
int
(
*
revalidate
)
(
dev_t
dev
);
};
struct
inode_operations
{
...
...
@@ -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
invalidate_inodes
(
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_dev
(
dev_t
dev
);
extern
int
fsync_dev
(
dev_t
dev
);
...
...
include/linux/mcd.h
View file @
5e4a8497
...
...
@@ -25,7 +25,7 @@
#define MCD_BASE_ADDR 0x300
/* *** change this to set the interrupt number */
#define MCD_INTR_NR 1
1
#define MCD_INTR_NR 1
0
/* Increase this if you get lots of timeouts */
#define MCD_STATUS_DELAY 100
...
...
include/linux/sbpcd.h
View file @
5e4a8497
...
...
@@ -23,7 +23,7 @@
* and specify the type of your interface in SBPRO.
*
* 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
* there are some soundcards on the market with 0x0630, 0x0650, ...
*
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment