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
Kirill Smelkov
linux
Commits
073c11c2
Commit
073c11c2
authored
Apr 12, 2004
by
Andrew Morton
Committed by
Linus Torvalds
Apr 12, 2004
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[PATCH] Feed floppy.c through Lindent
From: "Randy.Dunlap" <rddunlap@osdl.org>
parent
0079e33e
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
860 additions
and
858 deletions
+860
-858
drivers/block/floppy.c
drivers/block/floppy.c
+860
-858
No files found.
drivers/block/floppy.c
View file @
073c11c2
...
...
@@ -148,7 +148,7 @@
#define DCL_DEBUG
/* debug disk change line */
/* do print messages for unexpected interrupts */
static
int
print_unex
=
1
;
static
int
print_unex
=
1
;
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/fs.h>
...
...
@@ -163,7 +163,6 @@ static int print_unex=1;
* 1998/1/21 -- Richard Gooch <rgooch@atnf.csiro.au> -- devfs support
*/
#include <linux/fd.h>
#include <linux/hdreg.h>
...
...
@@ -195,9 +194,9 @@ static int slow_floppy;
#include <asm/io.h>
#include <asm/uaccess.h>
static
int
FLOPPY_IRQ
=
6
;
static
int
FLOPPY_DMA
=
2
;
static
int
can_use_virtual_dma
=
2
;
static
int
FLOPPY_IRQ
=
6
;
static
int
FLOPPY_DMA
=
2
;
static
int
can_use_virtual_dma
=
2
;
/* =======
* can use virtual DMA:
* 0 = use of virtual DMA disallowed by config
...
...
@@ -221,10 +220,10 @@ static int use_virtual_dma;
static
spinlock_t
floppy_lock
=
SPIN_LOCK_UNLOCKED
;
static
struct
completion
device_release
;
static
unsigned
short
virtual_dma_port
=
0x3f0
;
irqreturn_t
floppy_interrupt
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
);
static
unsigned
short
virtual_dma_port
=
0x3f0
;
irqreturn_t
floppy_interrupt
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
);
static
int
set_dor
(
int
fdc
,
char
mask
,
char
data
);
static
void
register_devfs_entries
(
int
drive
)
__init
;
static
void
register_devfs_entries
(
int
drive
)
__init
;
#define K_64 0x10000
/* 64KB */
...
...
@@ -277,8 +276,9 @@ static inline void fallback_on_nodma_alloc(char **addr, size_t l)
return
;
/* we have the memory */
if
(
can_use_virtual_dma
!=
2
)
return
;
/* no fallback allowed */
printk
(
"DMA memory shortage. Temporarily falling back on virtual DMA
\n
"
);
*
addr
=
(
char
*
)
nodma_mem_alloc
(
l
);
printk
(
"DMA memory shortage. Temporarily falling back on virtual DMA
\n
"
);
*
addr
=
(
char
*
)
nodma_mem_alloc
(
l
);
#else
return
;
#endif
...
...
@@ -287,7 +287,7 @@ static inline void fallback_on_nodma_alloc(char **addr, size_t l)
/* End dma memory related stuff */
static
unsigned
long
fake_change
;
static
int
initialising
=
1
;
static
int
initialising
=
1
;
#define ITYPE(x) (((x)>>2) & 0x1f)
#define TOMINOR(x) ((x & 3) | ((x & 4) << 5))
...
...
@@ -342,8 +342,7 @@ static int initialising=1;
* current disk size is unknown.
* [Now it is rather a minimum]
*/
#define MAX_DISK_SIZE 4
/* 3984*/
#define MAX_DISK_SIZE 4
/* 3984 */
/*
* globals used by 'result()'
...
...
@@ -368,7 +367,7 @@ static int inr; /* size of reply buffer, when called from interrupt */
static
struct
{
struct
floppy_drive_params
params
;
const
char
*
name
;
/* name printed while booting */
}
default_drive_params
[]
=
{
}
default_drive_params
[]
=
{
/* NOTE: the time values in jiffies should be in msec!
CMOS drive type
| Maximum data rate supported by drive type
...
...
@@ -541,12 +540,12 @@ static char *floppy_track_buffer;
static
int
max_buffer_sectors
;
static
int
*
errors
;
typedef
void
(
*
done_f
)(
int
);
typedef
void
(
*
done_f
)
(
int
);
static
struct
cont_t
{
void
(
*
interrupt
)
(
void
);
/* this is called after the interrupt of the
void
(
*
interrupt
)
(
void
);
/* this is called after the interrupt of the
* main command */
void
(
*
redo
)
(
void
);
/* this is called to retry the operation */
void
(
*
error
)
(
void
);
/* this is called to tally an error */
void
(
*
redo
)
(
void
);
/* this is called to retry the operation */
void
(
*
error
)
(
void
);
/* this is called to tally an error */
done_f
done
;
/* this is called to say if the operation has
* succeeded/failed */
}
*
cont
;
...
...
@@ -624,11 +623,11 @@ static inline void debugt(const char *message)
{
#ifdef DEBUGT
if
(
DP
->
flags
&
DEBUGT
)
printk
(
"%s dtime=%lu
\n
"
,
message
,
jiffies
-
debugtimer
);
printk
(
"%s dtime=%lu
\n
"
,
message
,
jiffies
-
debugtimer
);
#endif
}
typedef
void
(
*
timeout_fn
)(
unsigned
long
);
typedef
void
(
*
timeout_fn
)
(
unsigned
long
);
static
struct
timer_list
fd_timeout
=
TIMER_INITIALIZER
(
floppy_shutdown
,
0
,
0
);
static
const
char
*
timeout_message
;
...
...
@@ -639,18 +638,18 @@ static void is_alive(const char *message)
/* this routine checks whether the floppy driver is "alive" */
if
(
test_bit
(
0
,
&
fdc_busy
)
&&
command_status
<
2
&&
!
timer_pending
(
&
fd_timeout
))
{
DPRINT
(
"timeout handler died: %s
\n
"
,
message
);
DPRINT
(
"timeout handler died: %s
\n
"
,
message
);
}
}
#endif
static
void
(
*
do_floppy
)(
void
)
=
NULL
;
static
void
(
*
do_floppy
)
(
void
)
=
NULL
;
#ifdef FLOPPY_SANITY_CHECK
#define OLOGSIZE 20
static
void
(
*
lasthandler
)(
void
);
static
void
(
*
lasthandler
)
(
void
);
static
unsigned
long
interruptjiffies
;
static
unsigned
long
resultjiffies
;
static
int
resultsize
;
...
...
@@ -674,12 +673,12 @@ static void __reschedule_timeout(int drive, const char *message, int marg)
drive
=
current_drive
;
del_timer
(
&
fd_timeout
);
if
(
drive
<
0
||
drive
>
N_DRIVE
)
{
fd_timeout
.
expires
=
jiffies
+
20UL
*
HZ
;
drive
=
0
;
fd_timeout
.
expires
=
jiffies
+
20UL
*
HZ
;
drive
=
0
;
}
else
fd_timeout
.
expires
=
jiffies
+
UDP
->
timeout
;
add_timer
(
&
fd_timeout
);
if
(
UDP
->
flags
&
FD_DEBUG
){
if
(
UDP
->
flags
&
FD_DEBUG
)
{
DPRINT
(
"reschedule timeout "
);
printk
(
message
,
marg
);
printk
(
"
\n
"
);
...
...
@@ -700,7 +699,6 @@ static void reschedule_timeout(int drive, const char *message, int marg)
#define SUPBOUND(a,b) (a)=min_t(int, a, b)
/*
* Bottom half floppy driver.
* ==========================
...
...
@@ -736,32 +734,31 @@ static void reschedule_timeout(int drive, const char *message, int marg)
static
int
disk_change
(
int
drive
)
{
int
fdc
=
FDC
(
drive
);
int
fdc
=
FDC
(
drive
);
#ifdef FLOPPY_SANITY_CHECK
if
(
jiffies
-
UDRS
->
select_date
<
UDP
->
select_delay
)
DPRINT
(
"WARNING disk change called early
\n
"
);
if
(
!
(
FDCS
->
dor
&
(
0x10
<<
UNIT
(
drive
)))
||
(
FDCS
->
dor
&
3
)
!=
UNIT
(
drive
)
||
fdc
!=
FDC
(
drive
)){
(
FDCS
->
dor
&
3
)
!=
UNIT
(
drive
)
||
fdc
!=
FDC
(
drive
))
{
DPRINT
(
"probing disk change on unselected drive
\n
"
);
DPRINT
(
"drive=%d fdc=%d dor=%x
\n
"
,
drive
,
FDC
(
drive
),
DPRINT
(
"drive=%d fdc=%d dor=%x
\n
"
,
drive
,
FDC
(
drive
),
(
unsigned
int
)
FDCS
->
dor
);
}
#endif
#ifdef DCL_DEBUG
if
(
UDP
->
flags
&
FD_DEBUG
){
DPRINT
(
"checking disk change line for drive %d
\n
"
,
drive
);
if
(
UDP
->
flags
&
FD_DEBUG
)
{
DPRINT
(
"checking disk change line for drive %d
\n
"
,
drive
);
DPRINT
(
"jiffies=%lu
\n
"
,
jiffies
);
DPRINT
(
"disk change line=%x
\n
"
,
fd_inb
(
FD_DIR
)
&
0x80
);
DPRINT
(
"flags=%lx
\n
"
,
UDRS
->
flags
);
DPRINT
(
"disk change line=%x
\n
"
,
fd_inb
(
FD_DIR
)
&
0x80
);
DPRINT
(
"flags=%lx
\n
"
,
UDRS
->
flags
);
}
#endif
if
(
UDP
->
flags
&
FD_BROKEN_DCL
)
return
UTESTF
(
FD_DISK_CHANGED
);
if
((
fd_inb
(
FD_DIR
)
^
UDP
->
flags
)
&
0x80
){
if
((
fd_inb
(
FD_DIR
)
^
UDP
->
flags
)
&
0x80
)
{
USETF
(
FD_VERIFY
);
/* verify write protection */
if
(
UDRS
->
maxblock
){
if
(
UDRS
->
maxblock
)
{
/* mark it changed */
USETF
(
FD_DISK_CHANGED
);
}
...
...
@@ -776,10 +773,10 @@ static int disk_change(int drive)
floppy_sizes
[
TOMINOR
(
drive
)]
=
MAX_DISK_SIZE
<<
1
;
}
/*USETF(FD_DISK_NEWCHANGE);*/
/*USETF(FD_DISK_NEWCHANGE);
*/
return
1
;
}
else
{
UDRS
->
last_checked
=
jiffies
;
UDRS
->
last_checked
=
jiffies
;
UCLEARF
(
FD_DISK_NEWCHANGE
);
}
return
0
;
...
...
@@ -787,24 +784,24 @@ static int disk_change(int drive)
static
inline
int
is_selected
(
int
dor
,
int
unit
)
{
return
((
dor
&
(
0x10
<<
unit
))
&&
(
dor
&
3
)
==
unit
);
return
((
dor
&
(
0x10
<<
unit
))
&&
(
dor
&
3
)
==
unit
);
}
static
int
set_dor
(
int
fdc
,
char
mask
,
char
data
)
{
register
unsigned
char
drive
,
unit
,
newdor
,
olddor
;
register
unsigned
char
drive
,
unit
,
newdor
,
olddor
;
if
(
FDCS
->
address
==
-
1
)
return
-
1
;
olddor
=
FDCS
->
dor
;
newdor
=
(
olddor
&
mask
)
|
data
;
if
(
newdor
!=
olddor
){
if
(
newdor
!=
olddor
)
{
unit
=
olddor
&
0x3
;
if
(
is_selected
(
olddor
,
unit
)
&&
!
is_selected
(
newdor
,
unit
))
{
drive
=
REVDRIVE
(
fdc
,
unit
);
if
(
is_selected
(
olddor
,
unit
)
&&
!
is_selected
(
newdor
,
unit
))
{
drive
=
REVDRIVE
(
fdc
,
unit
);
#ifdef DCL_DEBUG
if
(
UDP
->
flags
&
FD_DEBUG
){
if
(
UDP
->
flags
&
FD_DEBUG
)
{
DPRINT
(
"calling disk change from set_dor
\n
"
);
}
#endif
...
...
@@ -814,8 +811,8 @@ static int set_dor(int fdc, char mask, char data)
fd_outb
(
newdor
,
FD_DOR
);
unit
=
newdor
&
0x3
;
if
(
!
is_selected
(
olddor
,
unit
)
&&
is_selected
(
newdor
,
unit
))
{
drive
=
REVDRIVE
(
fdc
,
unit
);
if
(
!
is_selected
(
olddor
,
unit
)
&&
is_selected
(
newdor
,
unit
))
{
drive
=
REVDRIVE
(
fdc
,
unit
);
UDRS
->
select_date
=
jiffies
;
}
}
...
...
@@ -835,7 +832,7 @@ static void twaddle(void)
{
if
(
DP
->
select_delay
)
return
;
fd_outb
(
FDCS
->
dor
&
~
(
0x10
<<
UNIT
(
current_drive
)),
FD_DOR
);
fd_outb
(
FDCS
->
dor
&
~
(
0x10
<<
UNIT
(
current_drive
)),
FD_DOR
);
fd_outb
(
FDCS
->
dor
,
FD_DOR
);
DRS
->
select_date
=
jiffies
;
}
...
...
@@ -851,15 +848,14 @@ static void reset_fdc_info(int mode)
FDCS
->
perp_mode
=
1
;
FDCS
->
rawcmd
=
0
;
for
(
drive
=
0
;
drive
<
N_DRIVE
;
drive
++
)
if
(
FDC
(
drive
)
==
fdc
&&
(
mode
||
UDRS
->
track
!=
NEED_1_RECAL
))
if
(
FDC
(
drive
)
==
fdc
&&
(
mode
||
UDRS
->
track
!=
NEED_1_RECAL
))
UDRS
->
track
=
NEED_2_RECAL
;
}
/* selects the fdc and drive, and enables the fdc's input/dma. */
static
void
set_fdc
(
int
drive
)
{
if
(
drive
>=
0
&&
drive
<
N_DRIVE
){
if
(
drive
>=
0
&&
drive
<
N_DRIVE
)
{
fdc
=
FDC
(
drive
);
current_drive
=
drive
;
}
...
...
@@ -867,9 +863,9 @@ static void set_fdc(int drive)
printk
(
"bad fdc value
\n
"
);
return
;
}
set_dor
(
fdc
,
~
0
,
8
);
set_dor
(
fdc
,
~
0
,
8
);
#if N_FDC > 1
set_dor
(
1
-
fdc
,
~
8
,
0
);
set_dor
(
1
-
fdc
,
~
8
,
0
);
#endif
if
(
FDCS
->
rawcmd
==
2
)
reset_fdc_info
(
1
);
...
...
@@ -880,11 +876,13 @@ static void set_fdc(int drive)
/* locks the driver */
static
int
_lock_fdc
(
int
drive
,
int
interruptible
,
int
line
)
{
if
(
!
usage_count
){
printk
(
KERN_ERR
"Trying to lock fdc while usage count=0 at line %d
\n
"
,
line
);
if
(
!
usage_count
)
{
printk
(
KERN_ERR
"Trying to lock fdc while usage count=0 at line %d
\n
"
,
line
);
return
-
1
;
}
if
(
floppy_grab_irq_and_dma
()
==
-
1
)
if
(
floppy_grab_irq_and_dma
()
==
-
1
)
return
-
EBUSY
;
if
(
test_and_set_bit
(
0
,
&
fdc_busy
))
{
...
...
@@ -920,7 +918,6 @@ static int _lock_fdc(int drive, int interruptible, int line)
#define LOCK_FDC(drive,interruptible) \
if (lock_fdc(drive,interruptible)) return -EINTR;
/* unlocks the driver */
static
inline
void
unlock_fdc
(
void
)
{
...
...
@@ -957,22 +954,23 @@ static void motor_off_callback(unsigned long nr)
static
void
floppy_off
(
unsigned
int
drive
)
{
unsigned
long
volatile
delta
;
register
int
fdc
=
FDC
(
drive
);
register
int
fdc
=
FDC
(
drive
);
if
(
!
(
FDCS
->
dor
&
(
0x10
<<
UNIT
(
drive
))))
return
;
del_timer
(
motor_off_timer
+
drive
);
del_timer
(
motor_off_timer
+
drive
);
/* make spindle stop in a position which minimizes spinup time
* next time */
if
(
UDP
->
rps
){
if
(
UDP
->
rps
)
{
delta
=
jiffies
-
UDRS
->
first_read_date
+
HZ
-
UDP
->
spindown_offset
;
delta
=
((
delta
*
UDP
->
rps
)
%
HZ
)
/
UDP
->
rps
;
motor_off_timer
[
drive
].
expires
=
jiffies
+
UDP
->
spindown
-
delta
;
motor_off_timer
[
drive
].
expires
=
jiffies
+
UDP
->
spindown
-
delta
;
}
add_timer
(
motor_off_timer
+
drive
);
add_timer
(
motor_off_timer
+
drive
);
}
/*
...
...
@@ -988,7 +986,7 @@ static void scandrives(void)
return
;
saved_drive
=
current_drive
;
for
(
i
=
0
;
i
<
N_DRIVE
;
i
++
)
{
for
(
i
=
0
;
i
<
N_DRIVE
;
i
++
)
{
drive
=
(
saved_drive
+
i
+
1
)
%
N_DRIVE
;
if
(
UDRS
->
fd_ref
==
0
||
UDP
->
select_delay
!=
0
)
continue
;
/* skip closed drives */
...
...
@@ -1022,7 +1020,7 @@ static void cancel_activity(void)
spin_lock_irqsave
(
&
floppy_lock
,
flags
);
do_floppy
=
NULL
;
PREPARE_WORK
(
&
floppy_work
,
(
void
*
)
empty
,
NULL
);
PREPARE_WORK
(
&
floppy_work
,
(
void
*
)
empty
,
NULL
);
del_timer
(
&
fd_timer
);
spin_unlock_irqrestore
(
&
floppy_lock
,
flags
);
}
...
...
@@ -1032,12 +1030,12 @@ static void cancel_activity(void)
static
void
fd_watchdog
(
void
)
{
#ifdef DCL_DEBUG
if
(
DP
->
flags
&
FD_DEBUG
){
if
(
DP
->
flags
&
FD_DEBUG
)
{
DPRINT
(
"calling disk change from watchdog
\n
"
);
}
#endif
if
(
disk_change
(
current_drive
)){
if
(
disk_change
(
current_drive
))
{
DPRINT
(
"disk removed during i/o
\n
"
);
cancel_activity
();
cont
->
done
(
0
);
...
...
@@ -1059,14 +1057,14 @@ static void main_command_interrupt(void)
/* waits for a delay (spinup or select) to pass */
static
int
fd_wait_for_completion
(
unsigned
long
delay
,
timeout_fn
function
)
{
if
(
FDCS
->
reset
){
if
(
FDCS
->
reset
)
{
reset_fdc
();
/* do the reset during sleep to win time
* if we don't need to sleep, it's a good
* occasion anyways */
return
1
;
}
if
((
signed
)
(
jiffies
-
delay
)
<
0
)
{
if
((
signed
)
(
jiffies
-
delay
)
<
0
)
{
del_timer
(
&
fd_timer
);
fd_timer
.
function
=
function
;
fd_timer
.
expires
=
delay
;
...
...
@@ -1084,7 +1082,7 @@ static void floppy_disable_hlt(void)
spin_lock_irqsave
(
&
floppy_hlt_lock
,
flags
);
if
(
!
hlt_disabled
)
{
hlt_disabled
=
1
;
hlt_disabled
=
1
;
#ifdef HAVE_DISABLE_HLT
disable_hlt
();
#endif
...
...
@@ -1097,8 +1095,8 @@ static void floppy_enable_hlt(void)
unsigned
long
flags
;
spin_lock_irqsave
(
&
floppy_hlt_lock
,
flags
);
if
(
hlt_disabled
){
hlt_disabled
=
0
;
if
(
hlt_disabled
)
{
hlt_disabled
=
0
;
#ifdef HAVE_DISABLE_HLT
enable_hlt
();
#endif
...
...
@@ -1106,47 +1104,45 @@ static void floppy_enable_hlt(void)
spin_unlock_irqrestore
(
&
floppy_hlt_lock
,
flags
);
}
static
void
setup_DMA
(
void
)
{
unsigned
long
f
;
#ifdef FLOPPY_SANITY_CHECK
if
(
raw_cmd
->
length
==
0
){
if
(
raw_cmd
->
length
==
0
)
{
int
i
;
printk
(
"zero dma transfer size:"
);
for
(
i
=
0
;
i
<
raw_cmd
->
cmd_count
;
i
++
)
for
(
i
=
0
;
i
<
raw_cmd
->
cmd_count
;
i
++
)
printk
(
"%x,"
,
raw_cmd
->
cmd
[
i
]);
printk
(
"
\n
"
);
cont
->
done
(
0
);
FDCS
->
reset
=
1
;
return
;
}
if
(((
unsigned
long
)
raw_cmd
->
kernel_data
)
%
512
)
{
if
(((
unsigned
long
)
raw_cmd
->
kernel_data
)
%
512
)
{
printk
(
"non aligned address: %p
\n
"
,
raw_cmd
->
kernel_data
);
cont
->
done
(
0
);
FDCS
->
reset
=
1
;
FDCS
->
reset
=
1
;
return
;
}
#endif
f
=
claim_dma_lock
();
f
=
claim_dma_lock
();
fd_disable_dma
();
#ifdef fd_dma_setup
if
(
fd_dma_setup
(
raw_cmd
->
kernel_data
,
raw_cmd
->
length
,
(
raw_cmd
->
flags
&
FD_RAW_READ
)
?
DMA_MODE_READ
:
DMA_MODE_WRITE
,
FDCS
->
address
)
<
0
)
{
(
raw_cmd
->
flags
&
FD_RAW_READ
)
?
DMA_MODE_READ
:
DMA_MODE_WRITE
,
FDCS
->
address
)
<
0
)
{
release_dma_lock
(
f
);
cont
->
done
(
0
);
FDCS
->
reset
=
1
;
FDCS
->
reset
=
1
;
return
;
}
release_dma_lock
(
f
);
#else
fd_clear_dma_ff
();
fd_cacheflush
(
raw_cmd
->
kernel_data
,
raw_cmd
->
length
);
fd_set_dma_mode
((
raw_cmd
->
flags
&
FD_RAW_READ
)
?
fd_set_dma_mode
((
raw_cmd
->
flags
&
FD_RAW_READ
)
?
DMA_MODE_READ
:
DMA_MODE_WRITE
);
fd_set_dma_addr
(
raw_cmd
->
kernel_data
);
fd_set_dma_count
(
raw_cmd
->
length
);
...
...
@@ -1171,8 +1167,7 @@ static int wait_til_ready(void)
return
status
;
}
if
(
!
initialising
)
{
DPRINT
(
"Getstatus times out (%x) on fdc %d
\n
"
,
status
,
fdc
);
DPRINT
(
"Getstatus times out (%x) on fdc %d
\n
"
,
status
,
fdc
);
show_floppy
();
}
FDCS
->
reset
=
1
;
...
...
@@ -1186,8 +1181,8 @@ static int output_byte(char byte)
if
((
status
=
wait_til_ready
())
<
0
)
return
-
1
;
if
((
status
&
(
STATUS_READY
|
STATUS_DIR
|
STATUS_DMA
))
==
STATUS_READY
)
{
fd_outb
(
byte
,
FD_DATA
);
if
((
status
&
(
STATUS_READY
|
STATUS_DIR
|
STATUS_DMA
))
==
STATUS_READY
)
{
fd_outb
(
byte
,
FD_DATA
);
#ifdef FLOPPY_SANITY_CHECK
output_log
[
output_log_pos
].
data
=
byte
;
output_log
[
output_log_pos
].
status
=
status
;
...
...
@@ -1204,31 +1199,33 @@ static int output_byte(char byte)
}
return
-
1
;
}
#define LAST_OUT(x) if (output_byte(x)<0){ reset_fdc();return;}
/* gets the response from the fdc */
static
int
result
(
void
)
{
int
i
,
status
=
0
;
int
i
,
status
=
0
;
for
(
i
=
0
;
i
<
MAX_REPLIES
;
i
++
)
{
for
(
i
=
0
;
i
<
MAX_REPLIES
;
i
++
)
{
if
((
status
=
wait_til_ready
())
<
0
)
break
;
status
&=
STATUS_DIR
|
STATUS_READY
|
STATUS_BUSY
|
STATUS_DMA
;
if
((
status
&
~
STATUS_BUSY
)
==
STATUS_READY
){
status
&=
STATUS_DIR
|
STATUS_READY
|
STATUS_BUSY
|
STATUS_DMA
;
if
((
status
&
~
STATUS_BUSY
)
==
STATUS_READY
)
{
#ifdef FLOPPY_SANITY_CHECK
resultjiffies
=
jiffies
;
resultsize
=
i
;
#endif
return
i
;
}
if
(
status
==
(
STATUS_DIR
|
STATUS_READY
|
STATUS_BUSY
))
if
(
status
==
(
STATUS_DIR
|
STATUS_READY
|
STATUS_BUSY
))
reply_buffer
[
i
]
=
fd_inb
(
FD_DATA
);
else
break
;
}
if
(
!
initialising
)
{
DPRINT
(
"get result error. Fdc=%d Last status=%x Read bytes=%d
\n
"
,
DPRINT
(
"get result error. Fdc=%d Last status=%x Read bytes=%d
\n
"
,
fdc
,
status
,
i
);
show_floppy
();
}
...
...
@@ -1243,7 +1240,7 @@ static int need_more_output(void)
int
status
;
if
((
status
=
wait_til_ready
())
<
0
)
return
-
1
;
if
((
status
&
(
STATUS_READY
|
STATUS_DIR
|
STATUS_DMA
))
==
STATUS_READY
)
if
((
status
&
(
STATUS_READY
|
STATUS_DIR
|
STATUS_DMA
))
==
STATUS_READY
)
return
MORE_OUTPUT
;
return
result
();
}
...
...
@@ -1255,13 +1252,13 @@ static inline void perpendicular_mode(void)
{
unsigned
char
perp_mode
;
if
(
raw_cmd
->
rate
&
0x40
){
switch
(
raw_cmd
->
rate
&
3
)
{
if
(
raw_cmd
->
rate
&
0x40
)
{
switch
(
raw_cmd
->
rate
&
3
)
{
case
0
:
perp_mode
=
2
;
perp_mode
=
2
;
break
;
case
3
:
perp_mode
=
3
;
perp_mode
=
3
;
break
;
default:
DPRINT
(
"Invalid data rate for perpendicular mode!
\n
"
);
...
...
@@ -1334,7 +1331,7 @@ static void fdc_specify(void)
if
(
FDCS
->
need_configure
&&
FDCS
->
version
>=
FDC_82072A
)
{
fdc_configure
();
FDCS
->
need_configure
=
0
;
/*DPRINT("FIFO enabled\n");*/
/*DPRINT("FIFO enabled\n");
*/
}
switch
(
raw_cmd
->
rate
&
0x03
)
{
...
...
@@ -1365,20 +1362,20 @@ static void fdc_specify(void)
}
/* Convert step rate from microseconds to milliseconds and 4 bits */
srt
=
16
-
(
DP
->
srt
*
scale_dtr
/
1000
+
NOMINAL_DTR
-
1
)
/
NOMINAL_DTR
;
if
(
slow_floppy
)
{
srt
=
16
-
(
DP
->
srt
*
scale_dtr
/
1000
+
NOMINAL_DTR
-
1
)
/
NOMINAL_DTR
;
if
(
slow_floppy
)
{
srt
=
srt
/
4
;
}
SUPBOUND
(
srt
,
0xf
);
INFBOUND
(
srt
,
0
);
hlt
=
(
DP
->
hlt
*
scale_dtr
/
2
+
NOMINAL_DTR
-
1
)
/
NOMINAL_DTR
;
hlt
=
(
DP
->
hlt
*
scale_dtr
/
2
+
NOMINAL_DTR
-
1
)
/
NOMINAL_DTR
;
if
(
hlt
<
0x01
)
hlt
=
0x01
;
else
if
(
hlt
>
0x7f
)
hlt
=
hlt_max_code
;
hut
=
(
DP
->
hut
*
scale_dtr
/
16
+
NOMINAL_DTR
-
1
)
/
NOMINAL_DTR
;
hut
=
(
DP
->
hut
*
scale_dtr
/
16
+
NOMINAL_DTR
-
1
)
/
NOMINAL_DTR
;
if
(
hut
<
0x1
)
hut
=
0x1
;
else
if
(
hut
>
0xf
)
...
...
@@ -1415,7 +1412,7 @@ static int fdc_dtr(void)
* Pause 5 msec to avoid trouble. (Needs to be 2 jiffies)
*/
FDCS
->
dtr
=
raw_cmd
->
rate
&
3
;
return
(
fd_wait_for_completion
(
jiffies
+
2UL
*
HZ
/
100
,
return
(
fd_wait_for_completion
(
jiffies
+
2UL
*
HZ
/
100
,
(
timeout_fn
)
floppy_ready
));
}
/* fdc_dtr */
...
...
@@ -1425,7 +1422,6 @@ static void tell_sector(void)
R_TRACK
,
R_HEAD
,
R_SECTOR
,
R_SIZECODE
);
}
/* tell_sector */
/*
* OK, this error interpreting routine is called after a
* DMA read/write has succeeded
...
...
@@ -1437,7 +1433,7 @@ static int interpret_errors(void)
{
char
bad
;
if
(
inr
!=
7
)
{
if
(
inr
!=
7
)
{
DPRINT
(
"-- FDC reply error"
);
FDCS
->
reset
=
1
;
return
1
;
...
...
@@ -1460,7 +1456,7 @@ static int interpret_errors(void)
if
(
DP
->
flags
&
FTD_MSG
)
DPRINT
(
"Over/Underrun - retrying
\n
"
);
bad
=
0
;
}
else
if
(
*
errors
>=
DP
->
max_errors
.
reporting
)
{
}
else
if
(
*
errors
>=
DP
->
max_errors
.
reporting
)
{
DPRINT
(
""
);
if
(
ST0
&
ST0_ECE
)
{
printk
(
"Recalibrate failed!"
);
...
...
@@ -1470,7 +1466,8 @@ static int interpret_errors(void)
}
else
if
(
ST1
&
ST1_CRC
)
{
printk
(
"CRC error"
);
tell_sector
();
}
else
if
((
ST1
&
(
ST1_MAM
|
ST1_ND
))
||
(
ST2
&
ST2_MAM
))
{
}
else
if
((
ST1
&
(
ST1_MAM
|
ST1_ND
))
||
(
ST2
&
ST2_MAM
))
{
if
(
!
probing
)
{
printk
(
"sector not found"
);
tell_sector
();
...
...
@@ -1481,7 +1478,9 @@ static int interpret_errors(void)
}
else
if
(
ST2
&
ST2_BC
)
{
/* cylinder marked as bad */
printk
(
"bad cylinder"
);
}
else
{
printk
(
"unknown error. ST[0..2] are: 0x%x 0x%x 0x%x"
,
ST0
,
ST1
,
ST2
);
printk
(
"unknown error. ST[0..2] are: 0x%x 0x%x 0x%x"
,
ST0
,
ST1
,
ST2
);
tell_sector
();
}
printk
(
"
\n
"
);
...
...
@@ -1511,7 +1510,7 @@ static int interpret_errors(void)
*/
static
void
setup_rw_floppy
(
void
)
{
int
i
,
r
,
flags
,
dflags
;
int
i
,
r
,
flags
,
dflags
;
unsigned
long
ready_date
;
timeout_fn
function
;
...
...
@@ -1519,20 +1518,20 @@ static void setup_rw_floppy(void)
if
(
flags
&
(
FD_RAW_READ
|
FD_RAW_WRITE
))
flags
|=
FD_RAW_INTR
;
if
((
flags
&
FD_RAW_SPIN
)
&&
!
(
flags
&
FD_RAW_NO_MOTOR
)){
if
((
flags
&
FD_RAW_SPIN
)
&&
!
(
flags
&
FD_RAW_NO_MOTOR
))
{
ready_date
=
DRS
->
spinup_date
+
DP
->
spinup
;
/* If spinup will take a long time, rerun scandrives
* again just before spinup completion. Beware that
* after scandrives, we must again wait for selection.
*/
if
((
signed
)
(
ready_date
-
jiffies
)
>
DP
->
select_delay
)
{
if
((
signed
)
(
ready_date
-
jiffies
)
>
DP
->
select_delay
)
{
ready_date
-=
DP
->
select_delay
;
function
=
(
timeout_fn
)
floppy_start
;
}
else
function
=
(
timeout_fn
)
setup_rw_floppy
;
/* wait until the floppy is spinning fast enough */
if
(
fd_wait_for_completion
(
ready_date
,
function
))
if
(
fd_wait_for_completion
(
ready_date
,
function
))
return
;
}
dflags
=
DRS
->
flags
;
...
...
@@ -1543,20 +1542,20 @@ static void setup_rw_floppy(void)
if
(
flags
&
FD_RAW_INTR
)
do_floppy
=
main_command_interrupt
;
r
=
0
;
for
(
i
=
0
;
i
<
raw_cmd
->
cmd_count
;
i
++
)
r
|=
output_byte
(
raw_cmd
->
cmd
[
i
]);
r
=
0
;
for
(
i
=
0
;
i
<
raw_cmd
->
cmd_count
;
i
++
)
r
|=
output_byte
(
raw_cmd
->
cmd
[
i
]);
#ifdef DEBUGT
debugt
(
"rw_command: "
);
#endif
if
(
r
){
if
(
r
)
{
cont
->
error
();
reset_fdc
();
return
;
}
if
(
!
(
flags
&
FD_RAW_INTR
)){
if
(
!
(
flags
&
FD_RAW_INTR
))
{
inr
=
result
();
cont
->
interrupt
();
}
else
if
(
flags
&
FD_RAW_NEED_DISK
)
...
...
@@ -1581,10 +1580,11 @@ static void seek_interrupt(void)
cont
->
redo
();
return
;
}
if
(
DRS
->
track
>=
0
&&
DRS
->
track
!=
ST1
&&
!
blind_seek
){
if
(
DRS
->
track
>=
0
&&
DRS
->
track
!=
ST1
&&
!
blind_seek
)
{
#ifdef DCL_DEBUG
if
(
DP
->
flags
&
FD_DEBUG
){
DPRINT
(
"clearing NEWCHANGE flag because of effective seek
\n
"
);
if
(
DP
->
flags
&
FD_DEBUG
)
{
DPRINT
(
"clearing NEWCHANGE flag because of effective seek
\n
"
);
DPRINT
(
"jiffies=%lu
\n
"
,
jiffies
);
}
#endif
...
...
@@ -1601,16 +1601,16 @@ static void check_wp(void)
/* check write protection */
output_byte
(
FD_GETSTATUS
);
output_byte
(
UNIT
(
current_drive
));
if
(
result
()
!=
1
){
if
(
result
()
!=
1
)
{
FDCS
->
reset
=
1
;
return
;
}
CLEARF
(
FD_VERIFY
);
CLEARF
(
FD_NEED_TWADDLE
);
#ifdef DCL_DEBUG
if
(
DP
->
flags
&
FD_DEBUG
){
if
(
DP
->
flags
&
FD_DEBUG
)
{
DPRINT
(
"checking whether disk is write protected
\n
"
);
DPRINT
(
"wp=%x
\n
"
,
ST3
&
0x40
);
DPRINT
(
"wp=%x
\n
"
,
ST3
&
0x40
);
}
#endif
if
(
!
(
ST3
&
0x40
))
...
...
@@ -1624,17 +1624,16 @@ static void seek_floppy(void)
{
int
track
;
blind_seek
=
0
;
blind_seek
=
0
;
#ifdef DCL_DEBUG
if
(
DP
->
flags
&
FD_DEBUG
){
if
(
DP
->
flags
&
FD_DEBUG
)
{
DPRINT
(
"calling disk change from seek
\n
"
);
}
#endif
if
(
!
TESTF
(
FD_DISK_NEWCHANGE
)
&&
disk_change
(
current_drive
)
&&
(
raw_cmd
->
flags
&
FD_RAW_NEED_DISK
)){
disk_change
(
current_drive
)
&&
(
raw_cmd
->
flags
&
FD_RAW_NEED_DISK
))
{
/* the media changed flag should be cleared after the seek.
* If it isn't, this means that there is really no disk in
* the drive.
...
...
@@ -1644,7 +1643,7 @@ static void seek_floppy(void)
cont
->
redo
();
return
;
}
if
(
DRS
->
track
<=
NEED_1_RECAL
){
if
(
DRS
->
track
<=
NEED_1_RECAL
)
{
recalibrate_floppy
();
return
;
}
else
if
(
TESTF
(
FD_DISK_NEWCHANGE
)
&&
...
...
@@ -1655,7 +1654,7 @@ static void seek_floppy(void)
if
(
raw_cmd
->
track
)
track
=
raw_cmd
->
track
-
1
;
else
{
if
(
DP
->
flags
&
FD_SILENT_DCL_CLEAR
){
if
(
DP
->
flags
&
FD_SILENT_DCL_CLEAR
)
{
set_dor
(
fdc
,
~
(
0x10
<<
UNIT
(
current_drive
)),
0
);
blind_seek
=
1
;
raw_cmd
->
flags
|=
FD_RAW_NEED_SEEK
;
...
...
@@ -1687,10 +1686,10 @@ static void recal_interrupt(void)
#ifdef DEBUGT
debugt
(
"recal interrupt:"
);
#endif
if
(
inr
!=
2
)
if
(
inr
!=
2
)
FDCS
->
reset
=
1
;
else
if
(
ST0
&
ST0_ECE
)
{
switch
(
DRS
->
track
)
{
switch
(
DRS
->
track
)
{
case
NEED_1_RECAL
:
#ifdef DEBUGT
debugt
(
"recal interrupt need 1 recal:"
);
...
...
@@ -1713,8 +1712,9 @@ static void recal_interrupt(void)
* be already at track 0.) Clear the
* new change flag */
#ifdef DCL_DEBUG
if
(
DP
->
flags
&
FD_DEBUG
){
DPRINT
(
"clearing NEWCHANGE flag because of second recalibrate
\n
"
);
if
(
DP
->
flags
&
FD_DEBUG
)
{
DPRINT
(
"clearing NEWCHANGE flag because of second recalibrate
\n
"
);
}
#endif
...
...
@@ -1745,31 +1745,31 @@ static void print_result(char *message, int inr)
DPRINT
(
"%s "
,
message
);
if
(
inr
>=
0
)
for
(
i
=
0
;
i
<
inr
;
i
++
)
for
(
i
=
0
;
i
<
inr
;
i
++
)
printk
(
"repl[%d]=%x "
,
i
,
reply_buffer
[
i
]);
printk
(
"
\n
"
);
}
/* interrupt handler. Note that this can be called externally on the Sparc */
irqreturn_t
floppy_interrupt
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
)
irqreturn_t
floppy_interrupt
(
int
irq
,
void
*
dev_id
,
struct
pt_regs
*
regs
)
{
void
(
*
handler
)(
void
)
=
do_floppy
;
void
(
*
handler
)
(
void
)
=
do_floppy
;
int
do_print
;
unsigned
long
f
;
lasthandler
=
handler
;
interruptjiffies
=
jiffies
;
f
=
claim_dma_lock
();
f
=
claim_dma_lock
();
fd_disable_dma
();
release_dma_lock
(
f
);
floppy_enable_hlt
();
do_floppy
=
NULL
;
if
(
fdc
>=
N_FDC
||
FDCS
->
address
==
-
1
){
if
(
fdc
>=
N_FDC
||
FDCS
->
address
==
-
1
)
{
/* we don't even know which FDC is the culprit */
printk
(
"DOR0=%x
\n
"
,
fdc_state
[
0
].
dor
);
printk
(
"floppy interrupt on bizarre fdc %d
\n
"
,
fdc
);
printk
(
"floppy interrupt on bizarre fdc %d
\n
"
,
fdc
);
printk
(
"handler=%p
\n
"
,
handler
);
is_alive
(
"bizarre fdc"
);
return
IRQ_NONE
;
...
...
@@ -1790,7 +1790,7 @@ irqreturn_t floppy_interrupt(int irq, void *dev_id, struct pt_regs * regs)
inr
=
result
();
if
(
do_print
)
print_result
(
"unexpected interrupt"
,
inr
);
if
(
inr
==
0
){
if
(
inr
==
0
)
{
int
max_sensei
=
4
;
do
{
output_byte
(
FD_SENSEI
);
...
...
@@ -1798,7 +1798,8 @@ irqreturn_t floppy_interrupt(int irq, void *dev_id, struct pt_regs * regs)
if
(
do_print
)
print_result
(
"sensei"
,
inr
);
max_sensei
--
;
}
while
((
ST0
&
0x83
)
!=
UNIT
(
current_drive
)
&&
inr
==
2
&&
max_sensei
);
}
while
((
ST0
&
0x83
)
!=
UNIT
(
current_drive
)
&&
inr
==
2
&&
max_sensei
);
}
if
(
handler
)
schedule_bh
(
handler
);
...
...
@@ -1851,12 +1852,12 @@ static void reset_fdc(void)
/* Pseudo-DMA may intercept 'reset finished' interrupt. */
/* Irrelevant for systems with true DMA (i386). */
flags
=
claim_dma_lock
();
flags
=
claim_dma_lock
();
fd_disable_dma
();
release_dma_lock
(
flags
);
if
(
FDCS
->
version
>=
FDC_82072A
)
fd_outb
(
0x80
|
(
FDCS
->
dtr
&
3
),
FD_STATUS
);
fd_outb
(
0x80
|
(
FDCS
->
dtr
&
3
),
FD_STATUS
);
else
{
fd_outb
(
FDCS
->
dor
&
~
0x04
,
FD_DOR
);
udelay
(
FD_RESET_DELAY
);
...
...
@@ -1872,20 +1873,20 @@ static void show_floppy(void)
printk
(
"floppy driver state
\n
"
);
printk
(
"-------------------
\n
"
);
printk
(
"now=%lu last interrupt=%lu diff=%lu last called handler=%p
\n
"
,
jiffies
,
interruptjiffies
,
jiffies
-
interruptjiffies
,
lasthandler
);
jiffies
,
interruptjiffies
,
jiffies
-
interruptjiffies
,
lasthandler
);
#ifdef FLOPPY_SANITY_CHECK
printk
(
"timeout_message=%s
\n
"
,
timeout_message
);
printk
(
"last output bytes:
\n
"
);
for
(
i
=
0
;
i
<
OLOGSIZE
;
i
++
)
for
(
i
=
0
;
i
<
OLOGSIZE
;
i
++
)
printk
(
"%2x %2x %lu
\n
"
,
output_log
[(
i
+
output_log_pos
)
%
OLOGSIZE
].
data
,
output_log
[(
i
+
output_log_pos
)
%
OLOGSIZE
].
status
,
output_log
[(
i
+
output_log_pos
)
%
OLOGSIZE
].
jiffies
);
output_log
[(
i
+
output_log_pos
)
%
OLOGSIZE
].
data
,
output_log
[(
i
+
output_log_pos
)
%
OLOGSIZE
].
status
,
output_log
[(
i
+
output_log_pos
)
%
OLOGSIZE
].
jiffies
);
printk
(
"last result at %lu
\n
"
,
resultjiffies
);
printk
(
"last redo_fd_request at %lu
\n
"
,
lastredo
);
for
(
i
=
0
;
i
<
resultsize
;
i
++
)
{
for
(
i
=
0
;
i
<
resultsize
;
i
++
)
{
printk
(
"%2x "
,
reply_buffer
[
i
]);
}
printk
(
"
\n
"
);
...
...
@@ -1899,10 +1900,10 @@ static void show_floppy(void)
printk
(
"floppy_work.func=%p
\n
"
,
floppy_work
.
func
);
if
(
timer_pending
(
&
fd_timer
))
printk
(
"fd_timer.function=%p
\n
"
,
fd_timer
.
function
);
if
(
timer_pending
(
&
fd_timeout
)){
printk
(
"timer_function=%p
\n
"
,
fd_timeout
.
function
);
printk
(
"expires=%lu
\n
"
,
fd_timeout
.
expires
-
jiffies
);
printk
(
"now=%lu
\n
"
,
jiffies
);
if
(
timer_pending
(
&
fd_timeout
))
{
printk
(
"timer_function=%p
\n
"
,
fd_timeout
.
function
);
printk
(
"expires=%lu
\n
"
,
fd_timeout
.
expires
-
jiffies
);
printk
(
"now=%lu
\n
"
,
jiffies
);
}
printk
(
"cont=%p
\n
"
,
cont
);
printk
(
"current_req=%p
\n
"
,
current_req
);
...
...
@@ -1920,7 +1921,7 @@ static void floppy_shutdown(unsigned long data)
floppy_enable_hlt
();
flags
=
claim_dma_lock
();
flags
=
claim_dma_lock
();
fd_disable_dma
();
release_dma_lock
(
flags
);
...
...
@@ -1929,7 +1930,7 @@ static void floppy_shutdown(unsigned long data)
if
(
!
initialising
)
DPRINT
(
"floppy timeout called
\n
"
);
FDCS
->
reset
=
1
;
if
(
cont
){
if
(
cont
)
{
cont
->
done
(
0
);
cont
->
redo
();
/* this will recall reset when needed */
}
else
{
...
...
@@ -1938,17 +1939,18 @@ static void floppy_shutdown(unsigned long data)
}
is_alive
(
"floppy shutdown"
);
}
/*typedef void (*timeout_fn)(unsigned long);*/
/* start motor, check media-changed condition and write protection */
static
int
start_motor
(
void
(
*
function
)
(
void
)
)
static
int
start_motor
(
void
(
*
function
)
(
void
)
)
{
int
mask
,
data
;
mask
=
0xfc
;
data
=
UNIT
(
current_drive
);
if
(
!
(
raw_cmd
->
flags
&
FD_RAW_NO_MOTOR
)){
if
(
!
(
FDCS
->
dor
&
(
0x10
<<
UNIT
(
current_drive
)))){
if
(
!
(
raw_cmd
->
flags
&
FD_RAW_NO_MOTOR
))
{
if
(
!
(
FDCS
->
dor
&
(
0x10
<<
UNIT
(
current_drive
))))
{
set_debugt
();
/* no read since this drive is running */
DRS
->
first_read_date
=
0
;
...
...
@@ -1956,8 +1958,7 @@ static int start_motor(void (*function)(void) )
DRS
->
spinup_date
=
jiffies
;
data
|=
(
0x10
<<
UNIT
(
current_drive
));
}
}
else
if
(
FDCS
->
dor
&
(
0x10
<<
UNIT
(
current_drive
)))
}
else
if
(
FDCS
->
dor
&
(
0x10
<<
UNIT
(
current_drive
)))
mask
&=
~
(
0x10
<<
UNIT
(
current_drive
));
/* starts motor and selects floppy */
...
...
@@ -1965,39 +1966,37 @@ static int start_motor(void (*function)(void) )
set_dor
(
fdc
,
mask
,
data
);
/* wait_for_completion also schedules reset if needed. */
return
(
fd_wait_for_completion
(
DRS
->
select_date
+
DP
->
select_delay
,
return
(
fd_wait_for_completion
(
DRS
->
select_date
+
DP
->
select_delay
,
(
timeout_fn
)
function
));
}
static
void
floppy_ready
(
void
)
{
CHECK_RESET
;
if
(
start_motor
(
floppy_ready
))
return
;
if
(
fdc_dtr
())
return
;
if
(
start_motor
(
floppy_ready
))
return
;
if
(
fdc_dtr
())
return
;
#ifdef DCL_DEBUG
if
(
DP
->
flags
&
FD_DEBUG
){
if
(
DP
->
flags
&
FD_DEBUG
)
{
DPRINT
(
"calling disk change from floppy_ready
\n
"
);
}
#endif
if
(
!
(
raw_cmd
->
flags
&
FD_RAW_NO_MOTOR
)
&&
disk_change
(
current_drive
)
&&
!
DP
->
select_delay
)
disk_change
(
current_drive
)
&&
!
DP
->
select_delay
)
twaddle
();
/* this clears the dcl on certain drive/controller
* combinations */
#ifdef fd_chose_dma_mode
if
((
raw_cmd
->
flags
&
FD_RAW_READ
)
||
(
raw_cmd
->
flags
&
FD_RAW_WRITE
))
{
if
((
raw_cmd
->
flags
&
FD_RAW_READ
)
||
(
raw_cmd
->
flags
&
FD_RAW_WRITE
))
{
unsigned
long
flags
=
claim_dma_lock
();
fd_chose_dma_mode
(
raw_cmd
->
kernel_data
,
raw_cmd
->
length
);
fd_chose_dma_mode
(
raw_cmd
->
kernel_data
,
raw_cmd
->
length
);
release_dma_lock
(
flags
);
}
#endif
if
(
raw_cmd
->
flags
&
(
FD_RAW_NEED_SEEK
|
FD_RAW_NEED_DISK
)){
if
(
raw_cmd
->
flags
&
(
FD_RAW_NEED_SEEK
|
FD_RAW_NEED_DISK
))
{
perpendicular_mode
();
fdc_specify
();
/* must be done here because of hut, hlt ... */
seek_floppy
();
...
...
@@ -2015,7 +2014,7 @@ static void floppy_start(void)
scandrives
();
#ifdef DCL_DEBUG
if
(
DP
->
flags
&
FD_DEBUG
){
if
(
DP
->
flags
&
FD_DEBUG
)
{
DPRINT
(
"setting NEWCHANGE in floppy_start
\n
"
);
}
#endif
...
...
@@ -2052,7 +2051,6 @@ static struct cont_t wakeup_cont = {
.
done
=
(
done_f
)
empty
};
static
struct
cont_t
intr_cont
=
{
.
interrupt
=
empty
,
.
redo
=
process_fd_request
,
...
...
@@ -2060,7 +2058,7 @@ static struct cont_t intr_cont = {
.
done
=
(
done_f
)
empty
};
static
int
wait_til_done
(
void
(
*
handler
)(
void
),
int
interruptible
)
static
int
wait_til_done
(
void
(
*
handler
)
(
void
),
int
interruptible
)
{
int
ret
;
...
...
@@ -2071,8 +2069,8 @@ static int wait_til_done(void (*handler)(void), int interruptible)
add_wait_queue
(
&
command_done
,
&
wait
);
for
(;;)
{
set_current_state
(
interruptible
?
TASK_INTERRUPTIBLE:
set_current_state
(
interruptible
?
TASK_INTERRUPTIBLE
:
TASK_UNINTERRUPTIBLE
);
if
(
command_status
>=
2
||
!
NO_SIGNAL
)
...
...
@@ -2087,7 +2085,7 @@ static int wait_til_done(void (*handler)(void), int interruptible)
remove_wait_queue
(
&
command_done
,
&
wait
);
}
if
(
command_status
<
2
){
if
(
command_status
<
2
)
{
cancel_activity
();
cont
=
&
intr_cont
;
reset_fdc
();
...
...
@@ -2097,9 +2095,9 @@ static int wait_til_done(void (*handler)(void), int interruptible)
if
(
FDCS
->
reset
)
command_status
=
FD_COMMAND_ERROR
;
if
(
command_status
==
FD_COMMAND_OKAY
)
ret
=
0
;
ret
=
0
;
else
ret
=
-
EIO
;
ret
=
-
EIO
;
command_status
=
FD_COMMAND_NONE
;
return
ret
;
}
...
...
@@ -2126,7 +2124,6 @@ static void success_and_wakeup(void)
cont
->
redo
();
}
/*
* formatting and rw support.
* ==========================
...
...
@@ -2137,13 +2134,12 @@ static int next_valid_format(void)
int
probed_format
;
probed_format
=
DRS
->
probed_format
;
while
(
1
){
if
(
probed_format
>=
8
||
!
DP
->
autodetect
[
probed_format
]){
while
(
1
)
{
if
(
probed_format
>=
8
||
!
DP
->
autodetect
[
probed_format
])
{
DRS
->
probed_format
=
0
;
return
1
;
}
if
(
floppy_type
[
DP
->
autodetect
[
probed_format
]].
sect
){
if
(
floppy_type
[
DP
->
autodetect
[
probed_format
]].
sect
)
{
DRS
->
probed_format
=
probed_format
;
return
0
;
}
...
...
@@ -2155,7 +2151,7 @@ static void bad_flp_intr(void)
{
int
err_count
;
if
(
probing
){
if
(
probing
)
{
DRS
->
probed_format
++
;
if
(
!
next_valid_format
())
return
;
...
...
@@ -2176,7 +2172,7 @@ static void set_floppy(int drive)
if
(
type
)
_floppy
=
floppy_type
+
type
;
else
_floppy
=
current_type
[
drive
];
_floppy
=
current_type
[
drive
];
}
/*
...
...
@@ -2185,7 +2181,7 @@ static void set_floppy(int drive)
*/
static
void
format_interrupt
(
void
)
{
switch
(
interpret_errors
()){
switch
(
interpret_errors
())
{
case
1
:
cont
->
error
();
case
2
:
...
...
@@ -2202,10 +2198,10 @@ static void format_interrupt(void)
static
void
setup_format_params
(
int
track
)
{
struct
fparm
{
unsigned
char
track
,
head
,
sect
,
size
;
unsigned
char
track
,
head
,
sect
,
size
;
}
*
here
=
(
struct
fparm
*
)
floppy_track_buffer
;
int
il
,
n
;
int
count
,
head_shift
,
track_shift
;
int
il
,
n
;
int
count
,
head_shift
,
track_shift
;
raw_cmd
=
&
default_raw_cmd
;
raw_cmd
->
track
=
track
;
...
...
@@ -2214,8 +2210,8 @@ static void setup_format_params(int track)
FD_RAW_NEED_DISK
|
FD_RAW_NEED_SEEK
;
raw_cmd
->
rate
=
_floppy
->
rate
&
0x43
;
raw_cmd
->
cmd_count
=
NR_F
;
COMMAND
=
FM_MODE
(
_floppy
,
FD_FORMAT
);
DR_SELECT
=
UNIT
(
current_drive
)
+
PH_HEAD
(
_floppy
,
format_req
.
head
);
COMMAND
=
FM_MODE
(
_floppy
,
FD_FORMAT
);
DR_SELECT
=
UNIT
(
current_drive
)
+
PH_HEAD
(
_floppy
,
format_req
.
head
);
F_SIZECODE
=
FD_SIZECODE
(
_floppy
);
F_SECT_PER_TRACK
=
_floppy
->
sect
<<
2
>>
F_SIZECODE
;
F_GAP
=
_floppy
->
fmt_gap
;
...
...
@@ -2249,17 +2245,18 @@ static void setup_format_params(int track)
/* place logical sectors */
for
(
count
=
1
;
count
<=
F_SECT_PER_TRACK
;
++
count
)
{
here
[
n
].
sect
=
count
;
n
=
(
n
+
il
)
%
F_SECT_PER_TRACK
;
n
=
(
n
+
il
)
%
F_SECT_PER_TRACK
;
if
(
here
[
n
].
sect
)
{
/* sector busy, find next free sector */
++
n
;
if
(
n
>=
F_SECT_PER_TRACK
)
{
n
-=
F_SECT_PER_TRACK
;
while
(
here
[
n
].
sect
)
++
n
;
if
(
n
>=
F_SECT_PER_TRACK
)
{
n
-=
F_SECT_PER_TRACK
;
while
(
here
[
n
].
sect
)
++
n
;
}
}
}
if
(
_floppy
->
stretch
&
FD_ZEROBASED
)
{
for
(
count
=
0
;
count
<
F_SECT_PER_TRACK
;
count
++
)
if
(
_floppy
->
stretch
&
FD_ZEROBASED
)
{
for
(
count
=
0
;
count
<
F_SECT_PER_TRACK
;
count
++
)
here
[
count
].
sect
--
;
}
}
...
...
@@ -2285,7 +2282,7 @@ static int do_format(int drive, struct format_descr *tmp_format_req)
{
int
ret
;
LOCK_FDC
(
drive
,
1
);
LOCK_FDC
(
drive
,
1
);
set_floppy
(
drive
);
if
(
!
_floppy
||
_floppy
->
track
>
DP
->
tracks
||
...
...
@@ -2328,7 +2325,6 @@ static void floppy_end_request(struct request *req, int uptodate)
current_req
=
NULL
;
}
/* new request_done. Can handle physical sectors which are smaller than a
* logical buffer */
static
void
request_done
(
int
uptodate
)
...
...
@@ -2346,7 +2342,7 @@ static void request_done(int uptodate)
return
;
}
if
(
uptodate
){
if
(
uptodate
)
{
/* maintain values for invalidation on geometry
* change */
block
=
current_count_sectors
+
req
->
sector
;
...
...
@@ -2403,9 +2399,9 @@ static void rw_interrupt(void)
else
heads
=
1
;
nr_sectors
=
(((
R_TRACK
-
TRACK
)
*
heads
+
R_HEAD
-
HEAD
)
*
SECT_PER_TRACK
+
R_SECTOR
-
SECTOR
+
eoc
)
<<
SIZECODE
>>
2
;
nr_sectors
=
(((
R_TRACK
-
TRACK
)
*
heads
+
R_HEAD
-
HEAD
)
*
SECT_PER_TRACK
+
R_SECTOR
-
SECTOR
+
eoc
)
<<
SIZECODE
>>
2
;
#ifdef FLOPPY_SANITY_CHECK
if
(
nr_sectors
/
ssize
>
...
...
@@ -2423,44 +2419,44 @@ static void rw_interrupt(void)
#endif
nr_sectors
-=
in_sector_offset
;
INFBOUND
(
nr_sectors
,
0
);
INFBOUND
(
nr_sectors
,
0
);
SUPBOUND
(
current_count_sectors
,
nr_sectors
);
switch
(
interpret_errors
()){
switch
(
interpret_errors
())
{
case
2
:
cont
->
redo
();
return
;
case
1
:
if
(
!
current_count_sectors
)
{
if
(
!
current_count_sectors
)
{
cont
->
error
();
cont
->
redo
();
return
;
}
break
;
case
0
:
if
(
!
current_count_sectors
)
{
if
(
!
current_count_sectors
)
{
cont
->
redo
();
return
;
}
current_type
[
current_drive
]
=
_floppy
;
floppy_sizes
[
TOMINOR
(
current_drive
)
]
=
_floppy
->
size
;
floppy_sizes
[
TOMINOR
(
current_drive
)]
=
_floppy
->
size
;
break
;
}
if
(
probing
)
{
if
(
DP
->
flags
&
FTD_MSG
)
DPRINT
(
"Auto-detected floppy type %s in fd%d
\n
"
,
_floppy
->
name
,
current_drive
);
_floppy
->
name
,
current_drive
);
current_type
[
current_drive
]
=
_floppy
;
floppy_sizes
[
TOMINOR
(
current_drive
)]
=
_floppy
->
size
;
probing
=
0
;
}
if
(
CT
(
COMMAND
)
!=
FD_READ
||
raw_cmd
->
kernel_data
==
current_req
->
buffer
)
{
raw_cmd
->
kernel_data
==
current_req
->
buffer
)
{
/* transfer directly from buffer */
cont
->
done
(
1
);
}
else
if
(
CT
(
COMMAND
)
==
FD_READ
){
}
else
if
(
CT
(
COMMAND
)
==
FD_READ
)
{
buffer_track
=
raw_cmd
->
track
;
buffer_drive
=
current_drive
;
INFBOUND
(
buffer_max
,
nr_sectors
+
fsector_t
);
...
...
@@ -2481,7 +2477,8 @@ static int buffer_chain_size(void)
rq_for_each_bio
(
bio
,
current_req
)
{
bio_for_each_segment
(
bv
,
bio
,
i
)
{
if
(
page_address
(
bv
->
bv_page
)
+
bv
->
bv_offset
!=
base
+
size
)
if
(
page_address
(
bv
->
bv_page
)
+
bv
->
bv_offset
!=
base
+
size
)
break
;
size
+=
bv
->
bv_len
;
...
...
@@ -2500,7 +2497,7 @@ static int transfer_size(int ssize, int max_sector, int max_size)
max_sector
-=
(
max_sector
%
_floppy
->
sect
)
%
ssize
;
/* transfer size, beginning not aligned */
current_count_sectors
=
max_sector
-
fsector_t
;
current_count_sectors
=
max_sector
-
fsector_t
;
return
max_sector
;
}
...
...
@@ -2528,11 +2525,12 @@ static void copy_buffer(int ssize, int max_sector, int max_sector_2)
remaining
=
current_count_sectors
<<
9
;
#ifdef FLOPPY_SANITY_CHECK
if
((
remaining
>>
9
)
>
current_req
->
nr_sectors
&&
CT
(
COMMAND
)
==
FD_WRITE
){
CT
(
COMMAND
)
==
FD_WRITE
)
{
DPRINT
(
"in copy buffer
\n
"
);
printk
(
"current_count_sectors=%ld
\n
"
,
current_count_sectors
);
printk
(
"remaining=%d
\n
"
,
remaining
>>
9
);
printk
(
"current_req->nr_sectors=%ld
\n
"
,
current_req
->
nr_sectors
);
printk
(
"current_req->nr_sectors=%ld
\n
"
,
current_req
->
nr_sectors
);
printk
(
"current_req->current_nr_sectors=%u
\n
"
,
current_req
->
current_nr_sectors
);
printk
(
"max_sector=%d
\n
"
,
max_sector
);
...
...
@@ -2558,9 +2556,10 @@ static void copy_buffer(int ssize, int max_sector, int max_sector_2)
#ifdef FLOPPY_SANITY_CHECK
if
(
dma_buffer
+
size
>
floppy_track_buffer
+
(
max_buffer_sectors
<<
10
)
||
dma_buffer
<
floppy_track_buffer
)
{
dma_buffer
<
floppy_track_buffer
)
{
DPRINT
(
"buffer overrun in copy buffer %d
\n
"
,
(
int
)
((
floppy_track_buffer
-
dma_buffer
)
>>
9
));
(
int
)((
floppy_track_buffer
-
dma_buffer
)
>>
9
));
printk
(
"fsector_t=%d buffer_min=%d
\n
"
,
fsector_t
,
buffer_min
);
printk
(
"current_count_sectors=%ld
\n
"
,
...
...
@@ -2584,10 +2583,10 @@ static void copy_buffer(int ssize, int max_sector, int max_sector_2)
}
}
#ifdef FLOPPY_SANITY_CHECK
if
(
remaining
){
if
(
remaining
)
{
if
(
remaining
>
0
)
max_sector
-=
remaining
>>
9
;
DPRINT
(
"weirdness: remaining %d
\n
"
,
remaining
>>
9
);
DPRINT
(
"weirdness: remaining %d
\n
"
,
remaining
>>
9
);
}
#endif
}
...
...
@@ -2598,7 +2597,7 @@ static inline int check_dma_crossing(char *start,
{
if (CROSS_64KB(start, length)) {
printk("DMA xfer crosses 64KB boundary in %s %p-%p\n",
message, start, start
+
length);
message, start, start
+
length);
return 1;
} else
return 0;
...
...
@@ -2616,13 +2615,13 @@ static void virtualdmabug_workaround(void)
{
int
hard_sectors
,
end_sector
;
if
(
CT
(
COMMAND
)
==
FD_WRITE
)
{
if
(
CT
(
COMMAND
)
==
FD_WRITE
)
{
COMMAND
&=
~
0x80
;
/* switch off multiple track mode */
hard_sectors
=
raw_cmd
->
length
>>
(
7
+
SIZECODE
);
end_sector
=
SECTOR
+
hard_sectors
-
1
;
#ifdef FLOPPY_SANITY_CHECK
if
(
end_sector
>
SECT_PER_TRACK
)
{
if
(
end_sector
>
SECT_PER_TRACK
)
{
printk
(
"too many sectors %d > %d
\n
"
,
end_sector
,
SECT_PER_TRACK
);
return
;
...
...
@@ -2648,7 +2647,7 @@ static int make_raw_rw_request(void)
int
aligned_sector_t
;
int
max_sector
,
max_size
,
tracksize
,
ssize
;
if
(
max_buffer_sectors
==
0
)
{
if
(
max_buffer_sectors
==
0
)
{
printk
(
"VFS: Block I/O scheduled on unopened device
\n
"
);
return
0
;
}
...
...
@@ -2661,10 +2660,10 @@ static int make_raw_rw_request(void)
raw_cmd
->
cmd_count
=
NR_RW
;
if
(
rq_data_dir
(
current_req
)
==
READ
)
{
raw_cmd
->
flags
|=
FD_RAW_READ
;
COMMAND
=
FM_MODE
(
_floppy
,
FD_READ
);
}
else
if
(
rq_data_dir
(
current_req
)
==
WRITE
){
COMMAND
=
FM_MODE
(
_floppy
,
FD_READ
);
}
else
if
(
rq_data_dir
(
current_req
)
==
WRITE
)
{
raw_cmd
->
flags
|=
FD_RAW_WRITE
;
COMMAND
=
FM_MODE
(
_floppy
,
FD_WRITE
);
COMMAND
=
FM_MODE
(
_floppy
,
FD_WRITE
);
}
else
{
DPRINT
(
"make_raw_rw_request: unknown command
\n
"
);
return
0
;
...
...
@@ -2684,15 +2683,15 @@ static int make_raw_rw_request(void)
HEAD
=
fsector_t
/
_floppy
->
sect
;
if
(((
_floppy
->
stretch
&
(
FD_SWAPSIDES
|
FD_ZEROBASED
))
||
TESTF
(
FD_NEED_TWADDLE
))
&&
fsector_t
<
_floppy
->
sect
)
TESTF
(
FD_NEED_TWADDLE
))
&&
fsector_t
<
_floppy
->
sect
)
max_sector
=
_floppy
->
sect
;
/* 2M disks have phantom sectors on the first track */
if
((
_floppy
->
rate
&
FD_2M
)
&&
(
!
TRACK
)
&&
(
!
HEAD
)){
if
((
_floppy
->
rate
&
FD_2M
)
&&
(
!
TRACK
)
&&
(
!
HEAD
))
{
max_sector
=
2
*
_floppy
->
sect
/
3
;
if
(
fsector_t
>=
max_sector
){
current_count_sectors
=
min_t
(
int
,
_floppy
->
sect
-
fsector_t
,
if
(
fsector_t
>=
max_sector
)
{
current_count_sectors
=
min_t
(
int
,
_floppy
->
sect
-
fsector_t
,
current_req
->
nr_sectors
);
return
1
;
}
...
...
@@ -2700,9 +2699,7 @@ static int make_raw_rw_request(void)
}
else
SIZECODE
=
FD_SIZECODE
(
_floppy
);
raw_cmd
->
rate
=
_floppy
->
rate
&
0x43
;
if
((
_floppy
->
rate
&
FD_2M
)
&&
(
TRACK
||
HEAD
)
&&
raw_cmd
->
rate
==
2
)
if
((
_floppy
->
rate
&
FD_2M
)
&&
(
TRACK
||
HEAD
)
&&
raw_cmd
->
rate
==
2
)
raw_cmd
->
rate
=
1
;
if
(
SIZECODE
)
...
...
@@ -2710,7 +2707,7 @@ static int make_raw_rw_request(void)
else
SIZECODE2
=
0x80
;
raw_cmd
->
track
=
TRACK
<<
STRETCH
(
_floppy
);
DR_SELECT
=
UNIT
(
current_drive
)
+
PH_HEAD
(
_floppy
,
HEAD
);
DR_SELECT
=
UNIT
(
current_drive
)
+
PH_HEAD
(
_floppy
,
HEAD
);
GAP
=
_floppy
->
gap
;
CODE2SIZE
;
SECT_PER_TRACK
=
_floppy
->
sect
<<
2
>>
SIZECODE
;
...
...
@@ -2721,18 +2718,19 @@ static int make_raw_rw_request(void)
* of size ssize.
*/
tracksize
=
_floppy
->
sect
-
_floppy
->
sect
%
ssize
;
if
(
tracksize
<
_floppy
->
sect
){
SECT_PER_TRACK
++
;
if
(
tracksize
<
_floppy
->
sect
)
{
SECT_PER_TRACK
++
;
if
(
tracksize
<=
fsector_t
%
_floppy
->
sect
)
SECTOR
--
;
/* if we are beyond tracksize, fill up using smaller sectors */
while
(
tracksize
<=
fsector_t
%
_floppy
->
sect
){
while
(
tracksize
+
ssize
>
_floppy
->
sect
)
{
while
(
tracksize
<=
fsector_t
%
_floppy
->
sect
)
{
while
(
tracksize
+
ssize
>
_floppy
->
sect
)
{
SIZECODE
--
;
ssize
>>=
1
;
}
SECTOR
++
;
SECT_PER_TRACK
++
;
SECTOR
++
;
SECT_PER_TRACK
++
;
tracksize
+=
ssize
;
}
max_sector
=
HEAD
*
_floppy
->
sect
+
tracksize
;
...
...
@@ -2754,8 +2752,8 @@ static int make_raw_rw_request(void)
copy_buffer
(
1
,
max_sector
,
buffer_max
);
return
1
;
}
}
else
if
(
in_sector_offset
||
current_req
->
nr_sectors
<
ssize
){
if
(
CT
(
COMMAND
)
==
FD_WRITE
){
}
else
if
(
in_sector_offset
||
current_req
->
nr_sectors
<
ssize
)
{
if
(
CT
(
COMMAND
)
==
FD_WRITE
)
{
if
(
fsector_t
+
current_req
->
nr_sectors
>
ssize
&&
fsector_t
+
current_req
->
nr_sectors
<
ssize
+
ssize
)
max_size
=
ssize
+
ssize
;
...
...
@@ -2764,28 +2762,32 @@ static int make_raw_rw_request(void)
}
raw_cmd
->
flags
&=
~
FD_RAW_WRITE
;
raw_cmd
->
flags
|=
FD_RAW_READ
;
COMMAND
=
FM_MODE
(
_floppy
,
FD_READ
);
COMMAND
=
FM_MODE
(
_floppy
,
FD_READ
);
}
else
if
((
unsigned
long
)
current_req
->
buffer
<
MAX_DMA_ADDRESS
)
{
unsigned
long
dma_limit
;
int
direct
,
indirect
;
indirect
=
transfer_size
(
ssize
,
max_sector
,
max_buffer_sectors
*
2
)
-
fsector_t
;
indirect
=
transfer_size
(
ssize
,
max_sector
,
max_buffer_sectors
*
2
)
-
fsector_t
;
/*
* Do NOT use minimum() here---MAX_DMA_ADDRESS is 64 bits wide
* on a 64 bit machine!
*/
max_size
=
buffer_chain_size
();
dma_limit
=
(
MAX_DMA_ADDRESS
-
((
unsigned
long
)
current_req
->
buffer
))
>>
9
;
if
((
unsigned
long
)
max_size
>
dma_limit
)
{
dma_limit
=
(
MAX_DMA_ADDRESS
-
((
unsigned
long
)
current_req
->
buffer
))
>>
9
;
if
((
unsigned
long
)
max_size
>
dma_limit
)
{
max_size
=
dma_limit
;
}
/* 64 kb boundaries */
if
(
CROSS_64KB
(
current_req
->
buffer
,
max_size
<<
9
))
max_size
=
(
K_64
-
((
unsigned
long
)
current_req
->
buffer
)
%
K_64
)
>>
9
;
direct
=
transfer_size
(
ssize
,
max_sector
,
max_size
)
-
fsector_t
;
((
unsigned
long
)
current_req
->
buffer
)
%
K_64
)
>>
9
;
direct
=
transfer_size
(
ssize
,
max_sector
,
max_size
)
-
fsector_t
;
/*
* We try to read tracks, but if we get too many errors, we
* go back to reading just one sector at a time.
...
...
@@ -2796,14 +2798,16 @@ static int make_raw_rw_request(void)
if
(
!
direct
||
(
indirect
*
2
>
direct
*
3
&&
*
errors
<
DP
->
max_errors
.
read_track
&&
/*!TESTF(FD_NEED_TWADDLE) &&*/
((
!
probing
||
(
DP
->
read_track
&
(
1
<<
DRS
->
probed_format
)))))){
/*!TESTF(FD_NEED_TWADDLE) && */
((
!
probing
||
(
DP
->
read_track
&
(
1
<<
DRS
->
probed_format
))))))
{
max_size
=
current_req
->
nr_sectors
;
}
else
{
raw_cmd
->
kernel_data
=
current_req
->
buffer
;
raw_cmd
->
length
=
current_count_sectors
<<
9
;
if
(
raw_cmd
->
length
==
0
){
DPRINT
(
"zero dma transfer attempted from make_raw_request
\n
"
);
if
(
raw_cmd
->
length
==
0
)
{
DPRINT
(
"zero dma transfer attempted from make_raw_request
\n
"
);
DPRINT
(
"indirect=%d direct=%d fsector_t=%d"
,
indirect
,
direct
,
fsector_t
);
return
0
;
...
...
@@ -2822,22 +2826,23 @@ static int make_raw_rw_request(void)
/* claim buffer track if needed */
if
(
buffer_track
!=
raw_cmd
->
track
||
/* bad track */
buffer_drive
!=
current_drive
||
/* bad drive */
buffer_drive
!=
current_drive
||
/* bad drive */
fsector_t
>
buffer_max
||
fsector_t
<
buffer_min
||
((
CT
(
COMMAND
)
==
FD_READ
||
(
!
in_sector_offset
&&
current_req
->
nr_sectors
>=
ssize
))
&&
(
!
in_sector_offset
&&
current_req
->
nr_sectors
>=
ssize
))
&&
max_sector
>
2
*
max_buffer_sectors
+
buffer_min
&&
max_size
+
fsector_t
>
2
*
max_buffer_sectors
+
buffer_min
)
/* not enough space */
){
/* not enough space */
)
{
buffer_track
=
-
1
;
buffer_drive
=
current_drive
;
buffer_max
=
buffer_min
=
aligned_sector_t
;
}
raw_cmd
->
kernel_data
=
floppy_track_buffer
+
((
aligned_sector_t
-
buffer_min
)
<<
9
);
((
aligned_sector_t
-
buffer_min
)
<<
9
);
if
(
CT
(
COMMAND
)
==
FD_WRITE
){
if
(
CT
(
COMMAND
)
==
FD_WRITE
)
{
/* copy write buffer to track buffer.
* if we get here, we know that the write
* is either aligned or the data already in the buffer
...
...
@@ -2848,30 +2853,32 @@ static int make_raw_rw_request(void)
#endif
buffer_track
=
raw_cmd
->
track
;
buffer_drive
=
current_drive
;
copy_buffer
(
ssize
,
max_sector
,
2
*
max_buffer_sectors
+
buffer_min
);
copy_buffer
(
ssize
,
max_sector
,
2
*
max_buffer_sectors
+
buffer_min
);
}
else
transfer_size
(
ssize
,
max_sector
,
2
*
max_buffer_sectors
+
buffer_min
-
aligned_sector_t
);
2
*
max_buffer_sectors
+
buffer_min
-
aligned_sector_t
);
/* round up current_count_sectors to get dma xfer size */
raw_cmd
->
length
=
in_sector_offset
+
current_count_sectors
;
raw_cmd
->
length
=
((
raw_cmd
->
length
-
1
)
|
(
ssize
-
1
))
+
1
;
raw_cmd
->
length
=
in_sector_offset
+
current_count_sectors
;
raw_cmd
->
length
=
((
raw_cmd
->
length
-
1
)
|
(
ssize
-
1
))
+
1
;
raw_cmd
->
length
<<=
9
;
#ifdef FLOPPY_SANITY_CHECK
/*check_dma_crossing(raw_cmd->kernel_data, raw_cmd->length,
"end of make_raw_request");
*/
"end of make_raw_request");
*/
if
((
raw_cmd
->
length
<
current_count_sectors
<<
9
)
||
(
raw_cmd
->
kernel_data
!=
current_req
->
buffer
&&
CT
(
COMMAND
)
==
FD_WRITE
&&
(
aligned_sector_t
+
(
raw_cmd
->
length
>>
9
)
>
buffer_max
||
aligned_sector_t
<
buffer_min
))
||
raw_cmd
->
length
%
(
128
<<
SIZECODE
)
||
raw_cmd
->
length
<=
0
||
current_count_sectors
<=
0
){
raw_cmd
->
length
<=
0
||
current_count_sectors
<=
0
)
{
DPRINT
(
"fractionary current count b=%lx s=%lx
\n
"
,
raw_cmd
->
length
,
current_count_sectors
);
if
(
raw_cmd
->
kernel_data
!=
current_req
->
buffer
)
printk
(
"addr=%d, length=%ld
\n
"
,
(
int
)
((
raw_cmd
->
kernel_data
-
(
int
)
((
raw_cmd
->
kernel_data
-
floppy_track_buffer
)
>>
9
),
current_count_sectors
);
printk
(
"st=%d ast=%d mse=%d msi=%d
\n
"
,
...
...
@@ -2886,16 +2893,15 @@ static int make_raw_rw_request(void)
return
0
;
}
if
(
raw_cmd
->
kernel_data
!=
current_req
->
buffer
){
if
(
raw_cmd
->
kernel_data
!=
current_req
->
buffer
)
{
if
(
raw_cmd
->
kernel_data
<
floppy_track_buffer
||
current_count_sectors
<
0
||
raw_cmd
->
length
<
0
||
raw_cmd
->
kernel_data
+
raw_cmd
->
length
>
floppy_track_buffer
+
(
max_buffer_sectors
<<
10
))
{
floppy_track_buffer
+
(
max_buffer_sectors
<<
10
))
{
DPRINT
(
"buffer overrun in schedule dma
\n
"
);
printk
(
"fsector_t=%d buffer_min=%d current_count=%ld
\n
"
,
fsector_t
,
buffer_min
,
raw_cmd
->
length
>>
9
);
fsector_t
,
buffer_min
,
raw_cmd
->
length
>>
9
);
printk
(
"current_count_sectors=%ld
\n
"
,
current_count_sectors
);
if
(
CT
(
COMMAND
)
==
FD_READ
)
...
...
@@ -2905,15 +2911,15 @@ static int make_raw_rw_request(void)
return
0
;
}
}
else
if
(
raw_cmd
->
length
>
current_req
->
nr_sectors
<<
9
||
current_count_sectors
>
current_req
->
nr_sectors
){
current_count_sectors
>
current_req
->
nr_sectors
)
{
DPRINT
(
"buffer overrun in direct transfer
\n
"
);
return
0
;
}
else
if
(
raw_cmd
->
length
<
current_count_sectors
<<
9
){
}
else
if
(
raw_cmd
->
length
<
current_count_sectors
<<
9
)
{
DPRINT
(
"more sectors than bytes
\n
"
);
printk
(
"bytes=%ld
\n
"
,
raw_cmd
->
length
>>
9
);
printk
(
"sectors=%ld
\n
"
,
current_count_sectors
);
}
if
(
raw_cmd
->
length
==
0
){
if
(
raw_cmd
->
length
==
0
)
{
DPRINT
(
"zero dma transfer attempted from make_raw_request
\n
"
);
return
0
;
}
...
...
@@ -2952,31 +2958,33 @@ static void redo_fd_request(void)
reschedule_timeout
(
current_reqD
,
"redo fd request"
,
0
);
set_floppy
(
drive
);
raw_cmd
=
&
default_raw_cmd
;
raw_cmd
=
&
default_raw_cmd
;
raw_cmd
->
flags
=
0
;
if
(
start_motor
(
redo_fd_request
))
return
;
if
(
start_motor
(
redo_fd_request
))
return
;
disk_change
(
current_drive
);
if
(
test_bit
(
current_drive
,
&
fake_change
)
||
TESTF
(
FD_DISK_CHANGED
))
{
TESTF
(
FD_DISK_CHANGED
))
{
DPRINT
(
"disk absent or changed during operation
\n
"
);
REPEAT
;
}
if
(
!
_floppy
)
{
/* Autodetection */
if
(
!
probing
){
if
(
!
probing
)
{
DRS
->
probed_format
=
0
;
if
(
next_valid_format
()){
if
(
next_valid_format
())
{
DPRINT
(
"no autodetectable formats
\n
"
);
_floppy
=
NULL
;
REPEAT
;
}
}
probing
=
1
;
_floppy
=
floppy_type
+
DP
->
autodetect
[
DRS
->
probed_format
];
_floppy
=
floppy_type
+
DP
->
autodetect
[
DRS
->
probed_format
];
}
else
probing
=
0
;
errors
=
&
(
current_req
->
errors
);
errors
=
&
(
current_req
->
errors
);
tmp
=
make_raw_rw_request
();
if
(
tmp
<
2
){
if
(
tmp
<
2
)
{
request_done
(
tmp
);
continue
;
}
...
...
@@ -3007,14 +3015,16 @@ static void process_fd_request(void)
static
void
do_fd_request
(
request_queue_t
*
q
)
{
if
(
max_buffer_sectors
==
0
)
{
if
(
max_buffer_sectors
==
0
)
{
printk
(
"VFS: do_fd_request called on non-open device
\n
"
);
return
;
}
if
(
usage_count
==
0
)
{
printk
(
"warning: usage count=0, current_req=%p exiting
\n
"
,
current_req
);
printk
(
"sect=%ld flags=%lx
\n
"
,
(
long
)
current_req
->
sector
,
current_req
->
flags
);
printk
(
"warning: usage count=0, current_req=%p exiting
\n
"
,
current_req
);
printk
(
"sect=%ld flags=%lx
\n
"
,
(
long
)
current_req
->
sector
,
current_req
->
flags
);
return
;
}
if
(
test_bit
(
0
,
&
fdc_busy
))
{
...
...
@@ -3023,7 +3033,7 @@ static void do_fd_request(request_queue_t * q)
is_alive
(
"do fd request, old request running"
);
return
;
}
lock_fdc
(
MAXTIMEOUT
,
0
);
lock_fdc
(
MAXTIMEOUT
,
0
);
process_fd_request
();
is_alive
(
"do fd request"
);
}
...
...
@@ -3040,12 +3050,12 @@ static int poll_drive(int interruptible, int flag)
int
ret
;
/* no auto-sense, just clear dcl */
raw_cmd
=
&
default_raw_cmd
;
raw_cmd
->
flags
=
flag
;
raw_cmd
->
track
=
0
;
raw_cmd
->
cmd_count
=
0
;
raw_cmd
->
flags
=
flag
;
raw_cmd
->
track
=
0
;
raw_cmd
->
cmd_count
=
0
;
cont
=
&
poll_cont
;
#ifdef DCL_DEBUG
if
(
DP
->
flags
&
FD_DEBUG
){
if
(
DP
->
flags
&
FD_DEBUG
)
{
DPRINT
(
"setting NEWCHANGE in poll_drive
\n
"
);
}
#endif
...
...
@@ -3075,11 +3085,11 @@ static int user_reset_fdc(int drive, int arg, int interruptible)
{
int
ret
;
ret
=
0
;
LOCK_FDC
(
drive
,
interruptible
);
ret
=
0
;
LOCK_FDC
(
drive
,
interruptible
);
if
(
arg
==
FD_RESET_ALWAYS
)
FDCS
->
reset
=
1
;
if
(
FDCS
->
reset
){
FDCS
->
reset
=
1
;
if
(
FDCS
->
reset
)
{
cont
=
&
reset_cont
;
WAIT
(
reset_fdc
);
}
...
...
@@ -3091,9 +3101,10 @@ static int user_reset_fdc(int drive, int arg, int interruptible)
* Misc Ioctl's and support
* ========================
*/
static
inline
int
fd_copyout
(
void
*
param
,
const
void
*
address
,
unsigned
long
size
)
static
inline
int
fd_copyout
(
void
*
param
,
const
void
*
address
,
unsigned
long
size
)
{
return
copy_to_user
(
param
,
address
,
size
)
?
-
EFAULT
:
0
;
return
copy_to_user
(
param
,
address
,
size
)
?
-
EFAULT
:
0
;
}
static
inline
int
fd_copyin
(
void
*
param
,
void
*
address
,
unsigned
long
size
)
...
...
@@ -3125,7 +3136,6 @@ static inline const char *drive_name(int type, int drive)
return
"(null)"
;
}
/* raw commands */
static
void
raw_cmd_done
(
int
flag
)
{
...
...
@@ -3137,14 +3147,13 @@ static void raw_cmd_done(int flag)
}
else
{
raw_cmd
->
reply_count
=
inr
;
if
(
raw_cmd
->
reply_count
>
MAX_REPLIES
)
raw_cmd
->
reply_count
=
0
;
for
(
i
=
0
;
i
<
raw_cmd
->
reply_count
;
i
++
)
raw_cmd
->
reply_count
=
0
;
for
(
i
=
0
;
i
<
raw_cmd
->
reply_count
;
i
++
)
raw_cmd
->
reply
[
i
]
=
reply_buffer
[
i
];
if
(
raw_cmd
->
flags
&
(
FD_RAW_READ
|
FD_RAW_WRITE
))
{
if
(
raw_cmd
->
flags
&
(
FD_RAW_READ
|
FD_RAW_WRITE
))
{
unsigned
long
flags
;
flags
=
claim_dma_lock
();
flags
=
claim_dma_lock
();
raw_cmd
->
length
=
fd_get_dma_residue
();
release_dma_lock
(
flags
);
}
...
...
@@ -3164,7 +3173,7 @@ static void raw_cmd_done(int flag)
(
!
(
raw_cmd
->
flags
&
FD_RAW_FAILURE
)
||
!
(
raw_cmd
->
flags
&
FD_RAW_STOP_IF_FAILURE
))
&&
((
raw_cmd
->
flags
&
FD_RAW_FAILURE
)
||
!
(
raw_cmd
->
flags
&
FD_RAW_STOP_IF_SUCCESS
)))
{
!
(
raw_cmd
->
flags
&
FD_RAW_STOP_IF_SUCCESS
)))
{
raw_cmd
=
raw_cmd
->
next
;
return
;
}
...
...
@@ -3172,7 +3181,6 @@ static void raw_cmd_done(int flag)
generic_done
(
flag
);
}
static
struct
cont_t
raw_cmd_cont
=
{
.
interrupt
=
success_and_wakeup
,
.
redo
=
floppy_start
,
...
...
@@ -3185,29 +3193,28 @@ static inline int raw_cmd_copyout(int cmd, char *param,
{
int
ret
;
while
(
ptr
)
{
while
(
ptr
)
{
COPYOUT
(
*
ptr
);
param
+=
sizeof
(
struct
floppy_raw_cmd
);
if
((
ptr
->
flags
&
FD_RAW_READ
)
&&
ptr
->
buffer_length
){
if
(
ptr
->
length
>=
0
&&
ptr
->
length
<=
ptr
->
buffer_length
)
ECALL
(
fd_copyout
(
ptr
->
data
,
ptr
->
kernel_data
,
ptr
->
buffer_length
-
ptr
->
length
));
if
((
ptr
->
flags
&
FD_RAW_READ
)
&&
ptr
->
buffer_length
)
{
if
(
ptr
->
length
>=
0
&&
ptr
->
length
<=
ptr
->
buffer_length
)
ECALL
(
fd_copyout
(
ptr
->
data
,
ptr
->
kernel_data
,
ptr
->
buffer_length
-
ptr
->
length
));
}
ptr
=
ptr
->
next
;
}
return
0
;
}
static
void
raw_cmd_free
(
struct
floppy_raw_cmd
**
ptr
)
{
struct
floppy_raw_cmd
*
next
,
*
this
;
struct
floppy_raw_cmd
*
next
,
*
this
;
this
=
*
ptr
;
*
ptr
=
0
;
while
(
this
)
{
while
(
this
)
{
if
(
this
->
buffer_length
)
{
fd_dma_mem_free
((
unsigned
long
)
this
->
kernel_data
,
this
->
buffer_length
);
...
...
@@ -3219,7 +3226,6 @@ static void raw_cmd_free(struct floppy_raw_cmd **ptr)
}
}
static
inline
int
raw_cmd_copyin
(
int
cmd
,
char
*
param
,
struct
floppy_raw_cmd
**
rcmd
)
{
...
...
@@ -3228,7 +3234,7 @@ static inline int raw_cmd_copyin(int cmd, char *param,
int
i
;
*
rcmd
=
0
;
while
(
1
)
{
while
(
1
)
{
ptr
=
(
struct
floppy_raw_cmd
*
)
kmalloc
(
sizeof
(
struct
floppy_raw_cmd
),
GFP_USER
);
if
(
!
ptr
)
...
...
@@ -3249,7 +3255,7 @@ static inline int raw_cmd_copyin(int cmd, char *param,
*/
return
-
EINVAL
;
for
(
i
=
0
;
i
<
16
;
i
++
)
for
(
i
=
0
;
i
<
16
;
i
++
)
ptr
->
reply
[
i
]
=
0
;
ptr
->
resultcode
=
0
;
ptr
->
kernel_data
=
0
;
...
...
@@ -3257,9 +3263,9 @@ static inline int raw_cmd_copyin(int cmd, char *param,
if
(
ptr
->
flags
&
(
FD_RAW_READ
|
FD_RAW_WRITE
))
{
if
(
ptr
->
length
<=
0
)
return
-
EINVAL
;
ptr
->
kernel_data
=
(
char
*
)
fd_dma_mem_alloc
(
ptr
->
length
);
fallback_on_nodma_alloc
(
&
ptr
->
kernel_data
,
ptr
->
length
);
ptr
->
kernel_data
=
(
char
*
)
fd_dma_mem_alloc
(
ptr
->
length
);
fallback_on_nodma_alloc
(
&
ptr
->
kernel_data
,
ptr
->
length
);
if
(
!
ptr
->
kernel_data
)
return
-
ENOMEM
;
ptr
->
buffer_length
=
ptr
->
length
;
...
...
@@ -3267,14 +3273,13 @@ static inline int raw_cmd_copyin(int cmd, char *param,
if
(
ptr
->
flags
&
FD_RAW_WRITE
)
ECALL
(
fd_copyin
(
ptr
->
data
,
ptr
->
kernel_data
,
ptr
->
length
));
rcmd
=
&
(
ptr
->
next
);
rcmd
=
&
(
ptr
->
next
);
if
(
!
(
ptr
->
flags
&
FD_RAW_MORE
))
return
0
;
ptr
->
rate
&=
0x43
;
}
}
static
int
raw_cmd_ioctl
(
int
cmd
,
void
*
param
)
{
int
drive
,
ret
,
ret2
;
...
...
@@ -3282,15 +3287,15 @@ static int raw_cmd_ioctl(int cmd, void *param)
if
(
FDCS
->
rawcmd
<=
1
)
FDCS
->
rawcmd
=
1
;
for
(
drive
=
0
;
drive
<
N_DRIVE
;
drive
++
)
{
for
(
drive
=
0
;
drive
<
N_DRIVE
;
drive
++
)
{
if
(
FDC
(
drive
)
!=
fdc
)
continue
;
if
(
drive
==
current_drive
){
if
(
UDRS
->
fd_ref
>
1
){
if
(
drive
==
current_drive
)
{
if
(
UDRS
->
fd_ref
>
1
)
{
FDCS
->
rawcmd
=
2
;
break
;
}
}
else
if
(
UDRS
->
fd_ref
){
}
else
if
(
UDRS
->
fd_ref
)
{
FDCS
->
rawcmd
=
2
;
break
;
}
...
...
@@ -3307,9 +3312,9 @@ static int raw_cmd_ioctl(int cmd, void *param)
raw_cmd
=
my_raw_cmd
;
cont
=
&
raw_cmd_cont
;
ret
=
wait_til_done
(
floppy_start
,
1
);
ret
=
wait_til_done
(
floppy_start
,
1
);
#ifdef DCL_DEBUG
if
(
DP
->
flags
&
FD_DEBUG
){
if
(
DP
->
flags
&
FD_DEBUG
)
{
DPRINT
(
"calling disk change from raw_cmd ioctl
\n
"
);
}
#endif
...
...
@@ -3335,7 +3340,6 @@ static int invalidate_drive(struct block_device *bdev)
return
0
;
}
static
inline
void
clear_write_error
(
int
drive
)
{
CLEARSTRUCT
(
UDRWE
);
...
...
@@ -3346,24 +3350,23 @@ static inline int set_geometry(unsigned int cmd, struct floppy_struct *g,
{
int
cnt
;
/* sanity checking for parameters.*/
/* sanity checking for parameters.
*/
if
(
g
->
sect
<=
0
||
g
->
head
<=
0
||
g
->
track
<=
0
||
g
->
track
>
UDP
->
tracks
>>
STRETCH
(
g
)
||
g
->
track
<=
0
||
g
->
track
>
UDP
->
tracks
>>
STRETCH
(
g
)
||
/* check if reserved bits are set */
(
g
->
stretch
&~
(
FD_STRETCH
|
FD_SWAPSIDES
|
FD_ZEROBASED
))
!=
0
)
(
g
->
stretch
&
~
(
FD_STRETCH
|
FD_SWAPSIDES
|
FD_ZEROBASED
))
!=
0
)
return
-
EINVAL
;
if
(
type
){
if
(
type
)
{
if
(
!
capable
(
CAP_SYS_ADMIN
))
return
-
EPERM
;
down
(
&
open_lock
);
LOCK_FDC
(
drive
,
1
);
LOCK_FDC
(
drive
,
1
);
floppy_type
[
type
]
=
*
g
;
floppy_type
[
type
].
name
=
"user format"
;
floppy_type
[
type
].
name
=
"user format"
;
for
(
cnt
=
type
<<
2
;
cnt
<
(
type
<<
2
)
+
4
;
cnt
++
)
floppy_sizes
[
cnt
]
=
floppy_sizes
[
cnt
+
0x80
]
=
floppy_type
[
type
].
size
+
1
;
floppy_sizes
[
cnt
]
=
floppy_sizes
[
cnt
+
0x80
]
=
floppy_type
[
type
].
size
+
1
;
process_fd_request
();
for
(
cnt
=
0
;
cnt
<
N_DRIVE
;
cnt
++
)
{
struct
block_device
*
bdev
=
opened_bdev
[
cnt
];
...
...
@@ -3374,7 +3377,7 @@ static inline int set_geometry(unsigned int cmd, struct floppy_struct *g,
up
(
&
open_lock
);
}
else
{
int
oldStretch
;
LOCK_FDC
(
drive
,
1
);
LOCK_FDC
(
drive
,
1
);
if
(
cmd
!=
FDDEFPRM
)
/* notice a disk change immediately, else
* we lose our settings immediately*/
...
...
@@ -3406,7 +3409,7 @@ static inline int set_geometry(unsigned int cmd, struct floppy_struct *g,
}
/* handle obsolete ioctl's */
static
int
ioctl_table
[]
=
{
static
int
ioctl_table
[]
=
{
FDCLRPRM
,
FDSETPRM
,
FDDEFPRM
,
...
...
@@ -3438,8 +3441,8 @@ static inline int normalize_ioctl(int *cmd, int *size)
{
int
i
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
ioctl_table
);
i
++
)
{
if
((
*
cmd
&
0xffff
)
==
(
ioctl_table
[
i
]
&
0xffff
)){
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
ioctl_table
);
i
++
)
{
if
((
*
cmd
&
0xffff
)
==
(
ioctl_table
[
i
]
&
0xffff
))
{
*
size
=
_IOC_SIZE
(
*
cmd
);
*
cmd
=
ioctl_table
[
i
];
if
(
*
size
>
_IOC_SIZE
(
*
cmd
))
{
...
...
@@ -3457,8 +3460,8 @@ static int get_floppy_geometry(int drive, int type, struct floppy_struct **g)
if
(
type
)
*
g
=
&
floppy_type
[
type
];
else
{
LOCK_FDC
(
drive
,
0
);
CALL
(
poll_drive
(
0
,
0
));
LOCK_FDC
(
drive
,
0
);
CALL
(
poll_drive
(
0
,
0
));
process_fd_request
();
*
g
=
current_type
[
drive
];
}
...
...
@@ -3486,19 +3489,18 @@ static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
}
inparam
;
/* parameters coming from user space */
const
char
*
outparam
;
/* parameters passed back to user space */
/* convert compatibility eject ioctls into floppy eject ioctl.
* We do this in order to provide a means to eject floppy disks before
* installing the new fdutils package */
if
(
cmd
==
CDROMEJECT
||
/* CD-ROM eject */
cmd
==
0x6470
/* SunOS floppy eject */
)
{
cmd
==
0x6470
/* SunOS floppy eject */
)
{
DPRINT
(
"obsolete eject ioctl
\n
"
);
DPRINT
(
"please use floppycontrol --eject
\n
"
);
cmd
=
FDEJECT
;
}
/* generic block device ioctls */
switch
(
cmd
)
{
switch
(
cmd
)
{
/* the following have been inspired by the corresponding
* code for other block devices. */
struct
floppy_struct
*
g
;
...
...
@@ -3535,29 +3537,29 @@ static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
if
(
UDRS
->
fd_ref
!=
1
)
/* somebody else has this drive open */
return
-
EBUSY
;
LOCK_FDC
(
drive
,
1
);
LOCK_FDC
(
drive
,
1
);
/* do the actual eject. Fails on
* non-Sparc architectures */
ret
=
fd_eject
(
UNIT
(
drive
));
ret
=
fd_eject
(
UNIT
(
drive
));
USETF
(
FD_DISK_CHANGED
);
USETF
(
FD_VERIFY
);
process_fd_request
();
return
ret
;
case
FDCLRPRM
:
LOCK_FDC
(
drive
,
1
);
LOCK_FDC
(
drive
,
1
);
current_type
[
drive
]
=
NULL
;
floppy_sizes
[
drive
]
=
MAX_DISK_SIZE
<<
1
;
UDRS
->
keep_data
=
0
;
return
invalidate_drive
(
inode
->
i_bdev
);
case
FDSETPRM
:
case
FDDEFPRM
:
return
set_geometry
(
cmd
,
&
inparam
.
g
,
return
set_geometry
(
cmd
,
&
inparam
.
g
,
drive
,
type
,
inode
->
i_bdev
);
case
FDGETPRM
:
ECALL
(
get_floppy_geometry
(
drive
,
type
,
(
struct
floppy_struct
**
)
(
struct
floppy_struct
**
)
&
outparam
));
break
;
...
...
@@ -3569,7 +3571,7 @@ static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
return
0
;
case
FDFMTBEG
:
LOCK_FDC
(
drive
,
1
);
LOCK_FDC
(
drive
,
1
);
CALL
(
poll_drive
(
1
,
FD_RAW_NEED_DISK
));
ret
=
UDRS
->
flags
;
process_fd_request
();
...
...
@@ -3584,26 +3586,26 @@ static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
return
do_format
(
drive
,
&
inparam
.
f
);
case
FDFMTEND
:
case
FDFLUSH
:
LOCK_FDC
(
drive
,
1
);
LOCK_FDC
(
drive
,
1
);
return
invalidate_drive
(
inode
->
i_bdev
);
case
FDSETEMSGTRESH
:
UDP
->
max_errors
.
reporting
=
(
unsigned
short
)
(
param
&
0x0f
);
(
unsigned
short
)
(
param
&
0x0f
);
return
0
;
OUT
(
FDGETMAXERRS
,
&
UDP
->
max_errors
);
IN
(
FDSETMAXERRS
,
&
UDP
->
max_errors
,
max_errors
);
case
FDGETDRVTYP
:
outparam
=
drive_name
(
type
,
drive
);
SUPBOUND
(
size
,
strlen
(
outparam
)
+
1
);
outparam
=
drive_name
(
type
,
drive
);
SUPBOUND
(
size
,
strlen
(
outparam
)
+
1
);
break
;
IN
(
FDSETDRVPRM
,
UDP
,
dp
);
OUT
(
FDGETDRVPRM
,
UDP
);
case
FDPOLLDRVSTAT
:
LOCK_FDC
(
drive
,
1
);
LOCK_FDC
(
drive
,
1
);
CALL
(
poll_drive
(
1
,
FD_RAW_NEED_DISK
));
process_fd_request
();
/* fall through */
...
...
@@ -3612,24 +3614,24 @@ static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
case
FDRESET
:
return
user_reset_fdc
(
drive
,
(
int
)
param
,
1
);
OUT
(
FDGETFDCSTAT
,
UFDCS
);
OUT
(
FDGETFDCSTAT
,
UFDCS
);
case
FDWERRORCLR
:
CLEARSTRUCT
(
UDRWE
);
return
0
;
OUT
(
FDWERRORGET
,
UDRWE
);
OUT
(
FDWERRORGET
,
UDRWE
);
case
FDRAWCMD
:
if
(
type
)
return
-
EINVAL
;
LOCK_FDC
(
drive
,
1
);
LOCK_FDC
(
drive
,
1
);
set_floppy
(
drive
);
CALL
(
i
=
raw_cmd_ioctl
(
cmd
,
(
void
*
)
param
));
CALL
(
i
=
raw_cmd_ioctl
(
cmd
,
(
void
*
)
param
));
process_fd_request
();
return
i
;
case
FDTWADDLE
:
LOCK_FDC
(
drive
,
1
);
LOCK_FDC
(
drive
,
1
);
twaddle
();
process_fd_request
();
return
0
;
...
...
@@ -3648,21 +3650,21 @@ static int fd_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
static
void
__init
config_types
(
void
)
{
int
first
=
1
;
int
first
=
1
;
int
drive
;
/* read drive info out of physical CMOS */
drive
=
0
;
drive
=
0
;
if
(
!
UDP
->
cmos
)
UDP
->
cmos
=
FLOPPY0_TYPE
;
drive
=
1
;
drive
=
1
;
if
(
!
UDP
->
cmos
&&
FLOPPY1_TYPE
)
UDP
->
cmos
=
FLOPPY1_TYPE
;
/* XXX */
/* additional physical CMOS drive detection should go here */
for
(
drive
=
0
;
drive
<
N_DRIVE
;
drive
++
)
{
for
(
drive
=
0
;
drive
<
N_DRIVE
;
drive
++
)
{
unsigned
int
type
=
UDP
->
cmos
;
struct
floppy_drive_params
*
params
;
const
char
*
name
=
NULL
;
...
...
@@ -3673,8 +3675,7 @@ static void __init config_types(void)
if
(
type
)
{
name
=
default_drive_params
[
type
].
name
;
allowed_drive_mask
|=
1
<<
drive
;
}
else
}
else
allowed_drive_mask
&=
~
(
1
<<
drive
);
}
else
{
params
=
&
default_drive_params
[
0
].
params
;
...
...
@@ -3682,13 +3683,13 @@ static void __init config_types(void)
name
=
temparea
;
}
if
(
name
)
{
const
char
*
prepend
=
","
;
const
char
*
prepend
=
","
;
if
(
first
)
{
prepend
=
KERN_INFO
"Floppy drive(s):"
;
first
=
0
;
}
printk
(
"%s fd%d is %s"
,
prepend
,
drive
,
name
);
register_devfs_entries
(
drive
);
register_devfs_entries
(
drive
);
}
*
UDP
=
*
params
;
}
...
...
@@ -3696,13 +3697,13 @@ static void __init config_types(void)
printk
(
"
\n
"
);
}
static
int
floppy_release
(
struct
inode
*
inode
,
struct
file
*
filp
)
static
int
floppy_release
(
struct
inode
*
inode
,
struct
file
*
filp
)
{
int
drive
=
(
long
)
inode
->
i_bdev
->
bd_disk
->
private_data
;
down
(
&
open_lock
);
if
(
UDRS
->
fd_ref
<
0
)
UDRS
->
fd_ref
=
0
;
UDRS
->
fd_ref
=
0
;
else
if
(
!
UDRS
->
fd_ref
--
)
{
DPRINT
(
"floppy_release with fd_ref == 0"
);
UDRS
->
fd_ref
=
0
;
...
...
@@ -3719,7 +3720,7 @@ static int floppy_release(struct inode * inode, struct file * filp)
* /dev/PS0 etc), and disallows simultaneous access to the same
* drive with different device numbers.
*/
static
int
floppy_open
(
struct
inode
*
inode
,
struct
file
*
filp
)
static
int
floppy_open
(
struct
inode
*
inode
,
struct
file
*
filp
)
{
int
drive
=
(
long
)
inode
->
i_bdev
->
bd_disk
->
private_data
;
int
old_dev
;
...
...
@@ -3727,19 +3728,18 @@ static int floppy_open(struct inode * inode, struct file * filp)
int
res
=
-
EBUSY
;
char
*
tmp
;
filp
->
private_data
=
(
void
*
)
0
;
filp
->
private_data
=
(
void
*
)
0
;
down
(
&
open_lock
);
old_dev
=
UDRS
->
fd_device
;
if
(
opened_bdev
[
drive
]
&&
opened_bdev
[
drive
]
!=
inode
->
i_bdev
)
goto
out2
;
if
(
!
UDRS
->
fd_ref
&&
(
UDP
->
flags
&
FD_BROKEN_DCL
)){
if
(
!
UDRS
->
fd_ref
&&
(
UDP
->
flags
&
FD_BROKEN_DCL
))
{
USETF
(
FD_DISK_CHANGED
);
USETF
(
FD_VERIFY
);
}
if
(
UDRS
->
fd_ref
==
-
1
||
(
UDRS
->
fd_ref
&&
(
filp
->
f_flags
&
O_EXCL
)))
if
(
UDRS
->
fd_ref
==
-
1
||
(
UDRS
->
fd_ref
&&
(
filp
->
f_flags
&
O_EXCL
)))
goto
out2
;
if
(
floppy_grab_irq_and_dma
())
...
...
@@ -3754,7 +3754,7 @@ static int floppy_open(struct inode * inode, struct file * filp)
res
=
-
ENXIO
;
if
(
!
floppy_track_buffer
){
if
(
!
floppy_track_buffer
)
{
/* if opening an ED drive, reserve a big buffer,
* else reserve a small one */
if
((
UDP
->
cmos
==
6
)
||
(
UDP
->
cmos
==
5
))
...
...
@@ -3762,11 +3762,11 @@ static int floppy_open(struct inode * inode, struct file * filp)
else
try
=
32
;
/* Only 24 actually useful */
tmp
=
(
char
*
)
fd_dma_mem_alloc
(
1024
*
try
);
tmp
=
(
char
*
)
fd_dma_mem_alloc
(
1024
*
try
);
if
(
!
tmp
&&
!
floppy_track_buffer
)
{
try
>>=
1
;
/* buffer only one side */
INFBOUND
(
try
,
16
);
tmp
=
(
char
*
)
fd_dma_mem_alloc
(
1024
*
try
);
tmp
=
(
char
*
)
fd_dma_mem_alloc
(
1024
*
try
);
}
if
(
!
tmp
&&
!
floppy_track_buffer
)
{
fallback_on_nodma_alloc
(
&
tmp
,
2048
*
try
);
...
...
@@ -3777,7 +3777,7 @@ static int floppy_open(struct inode * inode, struct file * filp)
}
if
(
floppy_track_buffer
)
{
if
(
tmp
)
fd_dma_mem_free
((
unsigned
long
)
tmp
,
try
*
1024
);
fd_dma_mem_free
((
unsigned
long
)
tmp
,
try
*
1024
);
}
else
{
buffer_min
=
buffer_max
=
-
1
;
floppy_track_buffer
=
tmp
;
...
...
@@ -3795,8 +3795,9 @@ static int floppy_open(struct inode * inode, struct file * filp)
/* Allow ioctls if we have write-permissions even if read-only open.
* Needed so that programs such as fdrawcmd still can work on write
* protected disks */
if
(
filp
->
f_mode
&
2
||
permission
(
filp
->
f_dentry
->
d_inode
,
2
,
NULL
)
==
0
)
filp
->
private_data
=
(
void
*
)
8
;
if
(
filp
->
f_mode
&
2
||
permission
(
filp
->
f_dentry
->
d_inode
,
2
,
NULL
)
==
0
)
filp
->
private_data
=
(
void
*
)
8
;
if
(
UFDCS
->
rawcmd
==
1
)
UFDCS
->
rawcmd
=
2
;
...
...
@@ -3816,7 +3817,7 @@ static int floppy_open(struct inode * inode, struct file * filp)
return
0
;
out:
if
(
UDRS
->
fd_ref
<
0
)
UDRS
->
fd_ref
=
0
;
UDRS
->
fd_ref
=
0
;
else
UDRS
->
fd_ref
--
;
if
(
!
UDRS
->
fd_ref
)
...
...
@@ -3838,12 +3839,12 @@ static int check_floppy_change(struct gendisk *disk)
return
1
;
if
(
UDP
->
checkfreq
<
(
int
)(
jiffies
-
UDRS
->
last_checked
))
{
if
(
floppy_grab_irq_and_dma
())
{
if
(
floppy_grab_irq_and_dma
())
{
return
1
;
}
lock_fdc
(
drive
,
0
);
poll_drive
(
0
,
0
);
lock_fdc
(
drive
,
0
);
poll_drive
(
0
,
0
);
process_fd_request
();
floppy_release_irq_and_dma
();
}
...
...
@@ -3862,12 +3863,13 @@ static int check_floppy_change(struct gendisk *disk)
* a disk in the drive, and whether that disk is writable.
*/
static
int
floppy_rb0_complete
(
struct
bio
*
bio
,
unsigned
int
bytes_done
,
int
err
)
static
int
floppy_rb0_complete
(
struct
bio
*
bio
,
unsigned
int
bytes_done
,
int
err
)
{
if
(
bio
->
bi_size
)
return
1
;
complete
((
struct
completion
*
)
bio
->
bi_private
);
complete
((
struct
completion
*
)
bio
->
bi_private
);
return
0
;
}
...
...
@@ -3919,23 +3921,21 @@ static int __floppy_read_block_0(struct block_device *bdev)
* geometry formats */
static
int
floppy_revalidate
(
struct
gendisk
*
disk
)
{
int
drive
=
(
long
)
disk
->
private_data
;
int
drive
=
(
long
)
disk
->
private_data
;
#define NO_GEOM (!current_type[drive] && !ITYPE(UDRS->fd_device))
int
cf
;
int
res
=
0
;
if
(
UTESTF
(
FD_DISK_CHANGED
)
||
UTESTF
(
FD_VERIFY
)
||
test_bit
(
drive
,
&
fake_change
)
||
NO_GEOM
){
if
(
usage_count
==
0
)
{
UTESTF
(
FD_VERIFY
)
||
test_bit
(
drive
,
&
fake_change
)
||
NO_GEOM
)
{
if
(
usage_count
==
0
)
{
printk
(
"VFS: revalidate called on non-open device.
\n
"
);
return
-
EFAULT
;
}
lock_fdc
(
drive
,
0
);
lock_fdc
(
drive
,
0
);
cf
=
UTESTF
(
FD_DISK_CHANGED
)
||
UTESTF
(
FD_VERIFY
);
if
(
!
(
cf
||
test_bit
(
drive
,
&
fake_change
)
||
NO_GEOM
)){
process_fd_request
();
/*already done by another thread
*/
if
(
!
(
cf
||
test_bit
(
drive
,
&
fake_change
)
||
NO_GEOM
))
{
process_fd_request
();
/*already done by another thread
*/
return
0
;
}
UDRS
->
maxblock
=
0
;
...
...
@@ -3946,7 +3946,7 @@ static int floppy_revalidate(struct gendisk *disk)
UCLEARF
(
FD_DISK_CHANGED
);
if
(
cf
)
UDRS
->
generation
++
;
if
(
NO_GEOM
){
if
(
NO_GEOM
)
{
/* auto-sensing */
res
=
__floppy_read_block_0
(
opened_bdev
[
drive
]);
}
else
{
...
...
@@ -3965,22 +3965,24 @@ static struct block_device_operations floppy_fops = {
.
release
=
floppy_release
,
.
ioctl
=
fd_ioctl
,
.
media_changed
=
check_floppy_change
,
.
revalidate_disk
=
floppy_revalidate
,
.
revalidate_disk
=
floppy_revalidate
,
};
static
char
*
table
[]
=
{
""
,
"d360"
,
"h1200"
,
"u360"
,
"u720"
,
"h360"
,
"h720"
,
"u1440"
,
"u2880"
,
"CompaQ"
,
"h1440"
,
"u1680"
,
"h410"
,
"u820"
,
"h1476"
,
"u1722"
,
"h420"
,
"u830"
,
"h1494"
,
"u1743"
,
"h880"
,
"u1040"
,
"u1120"
,
"h1600"
,
"u1760"
,
"u1920"
,
"u3200"
,
"u3520"
,
"u3840"
,
"u1840"
,
"u800"
,
"u1600"
,
NULL
static
char
*
table
[]
=
{
""
,
"d360"
,
"h1200"
,
"u360"
,
"u720"
,
"h360"
,
"h720"
,
"u1440"
,
"u2880"
,
"CompaQ"
,
"h1440"
,
"u1680"
,
"h410"
,
"u820"
,
"h1476"
,
"u1722"
,
"h420"
,
"u830"
,
"h1494"
,
"u1743"
,
"h880"
,
"u1040"
,
"u1120"
,
"h1600"
,
"u1760"
,
"u1920"
,
"u3200"
,
"u3520"
,
"u3840"
,
"u1840"
,
"u800"
,
"u1600"
,
NULL
};
static
int
t360
[]
=
{
1
,
0
},
t1200
[]
=
{
2
,
5
,
6
,
10
,
12
,
14
,
16
,
18
,
20
,
23
,
0
},
t3in
[]
=
{
8
,
9
,
26
,
27
,
28
,
7
,
11
,
15
,
19
,
24
,
25
,
29
,
31
,
3
,
4
,
13
,
17
,
21
,
22
,
30
,
0
};
static
int
t360
[]
=
{
1
,
0
},
t1200
[]
=
{
2
,
5
,
6
,
10
,
12
,
14
,
16
,
18
,
20
,
23
,
0
},
t3in
[]
=
{
8
,
9
,
26
,
27
,
28
,
7
,
11
,
15
,
19
,
24
,
25
,
29
,
31
,
3
,
4
,
13
,
17
,
21
,
22
,
30
,
0
};
static
int
*
table_sup
[]
=
{
NULL
,
t360
,
t1200
,
t3in
+
5
+
8
,
t3in
+
5
,
t3in
,
t3in
};
{
NULL
,
t360
,
t1200
,
t3in
+
5
+
8
,
t3in
+
5
,
t3in
,
t3in
};
static
void
__init
register_devfs_entries
(
int
drive
)
static
void
__init
register_devfs_entries
(
int
drive
)
{
int
base_minor
=
(
drive
<
4
)
?
drive
:
(
124
+
drive
);
...
...
@@ -3990,9 +3992,9 @@ static void __init register_devfs_entries (int drive)
int
minor
=
base_minor
+
(
table_sup
[
UDP
->
cmos
][
i
]
<<
2
);
devfs_mk_bdev
(
MKDEV
(
FLOPPY_MAJOR
,
minor
),
S_IFBLK
|
S_IRUSR
|
S_IWUSR
|
S_IRGRP
|
S_IWGRP
,
"floppy/%d%s"
,
drive
,
table
[
table_sup
[
UDP
->
cmos
][
i
]]);
S_IFBLK
|
S_IRUSR
|
S_IWUSR
|
S_IRGRP
|
S_IWGRP
,
"floppy/%d%s"
,
drive
,
table
[
table_sup
[
UDP
->
cmos
][
i
]]);
}
while
(
table_sup
[
UDP
->
cmos
][
i
++
]);
}
}
...
...
@@ -4013,18 +4015,19 @@ static char __init get_fdc_version(void)
return
FDC_NONE
;
if
((
r
=
result
())
<=
0x00
)
return
FDC_NONE
;
/* No FDC present ??? */
if
((
r
==
1
)
&&
(
reply_buffer
[
0
]
==
0x80
))
{
printk
(
KERN_INFO
"FDC %d is an 8272A
\n
"
,
fdc
);
if
((
r
==
1
)
&&
(
reply_buffer
[
0
]
==
0x80
))
{
printk
(
KERN_INFO
"FDC %d is an 8272A
\n
"
,
fdc
);
return
FDC_8272A
;
/* 8272a/765 don't know DUMPREGS */
}
if
(
r
!=
10
)
{
printk
(
"FDC %d init: DUMPREGS: unexpected return of %d bytes.
\n
"
,
printk
(
"FDC %d init: DUMPREGS: unexpected return of %d bytes.
\n
"
,
fdc
,
r
);
return
FDC_UNKNOWN
;
}
if
(
!
fdc_configure
())
{
printk
(
KERN_INFO
"FDC %d is an 82072
\n
"
,
fdc
);
printk
(
KERN_INFO
"FDC %d is an 82072
\n
"
,
fdc
);
return
FDC_82072
;
/* 82072 doesn't know CONFIGURE */
}
...
...
@@ -4038,7 +4041,7 @@ static char __init get_fdc_version(void)
output_byte
(
FD_UNLOCK
);
r
=
result
();
if
((
r
==
1
)
&&
(
reply_buffer
[
0
]
==
0x80
)){
if
((
r
==
1
)
&&
(
reply_buffer
[
0
]
==
0x80
))
{
printk
(
KERN_INFO
"FDC %d is a pre-1991 82077
\n
"
,
fdc
);
return
FDC_82077_ORIG
;
/* Pre-1991 82077, doesn't know
* LOCK/UNLOCK */
...
...
@@ -4056,25 +4059,27 @@ static char __init get_fdc_version(void)
return
FDC_UNKNOWN
;
}
if
(
reply_buffer
[
0
]
==
0x80
)
{
printk
(
KERN_INFO
"FDC %d is a post-1991 82077
\n
"
,
fdc
);
printk
(
KERN_INFO
"FDC %d is a post-1991 82077
\n
"
,
fdc
);
return
FDC_82077
;
/* Revised 82077AA passes all the tests */
}
switch
(
reply_buffer
[
0
]
>>
5
)
{
case
0x0
:
/* Either a 82078-1 or a 82078SL running at 5Volt */
printk
(
KERN_INFO
"FDC %d is an 82078.
\n
"
,
fdc
);
printk
(
KERN_INFO
"FDC %d is an 82078.
\n
"
,
fdc
);
return
FDC_82078
;
case
0x1
:
printk
(
KERN_INFO
"FDC %d is a 44pin 82078
\n
"
,
fdc
);
printk
(
KERN_INFO
"FDC %d is a 44pin 82078
\n
"
,
fdc
);
return
FDC_82078
;
case
0x2
:
printk
(
KERN_INFO
"FDC %d is a S82078B
\n
"
,
fdc
);
return
FDC_S82078B
;
case
0x3
:
printk
(
KERN_INFO
"FDC %d is a National Semiconductor PC87306
\n
"
,
fdc
);
printk
(
KERN_INFO
"FDC %d is a National Semiconductor PC87306
\n
"
,
fdc
);
return
FDC_87306
;
default:
printk
(
KERN_INFO
"FDC %d init: 82078 variant with unknown PARTID=%d.
\n
"
,
printk
(
KERN_INFO
"FDC %d init: 82078 variant with unknown PARTID=%d.
\n
"
,
fdc
,
reply_buffer
[
0
]
>>
5
);
return
FDC_82078_UNKN
;
}
...
...
@@ -4082,11 +4087,11 @@ static char __init get_fdc_version(void)
/* lilo configuration */
static
void
__init
floppy_set_flags
(
int
*
ints
,
int
param
,
int
param2
)
static
void
__init
floppy_set_flags
(
int
*
ints
,
int
param
,
int
param2
)
{
int
i
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
default_drive_params
);
i
++
)
{
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
default_drive_params
);
i
++
)
{
if
(
param
)
default_drive_params
[
i
].
params
.
flags
|=
param2
;
else
...
...
@@ -4095,17 +4100,20 @@ static void __init floppy_set_flags(int *ints,int param, int param2)
DPRINT
(
"%s flag 0x%x
\n
"
,
param2
?
"Setting"
:
"Clearing"
,
param
);
}
static
void
__init
daring
(
int
*
ints
,
int
param
,
int
param2
)
static
void
__init
daring
(
int
*
ints
,
int
param
,
int
param2
)
{
int
i
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
default_drive_params
);
i
++
)
{
if
(
param
){
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
default_drive_params
);
i
++
)
{
if
(
param
)
{
default_drive_params
[
i
].
params
.
select_delay
=
0
;
default_drive_params
[
i
].
params
.
flags
|=
FD_SILENT_DCL_CLEAR
;
default_drive_params
[
i
].
params
.
flags
|=
FD_SILENT_DCL_CLEAR
;
}
else
{
default_drive_params
[
i
].
params
.
select_delay
=
2
*
HZ
/
100
;
default_drive_params
[
i
].
params
.
flags
&=
~
FD_SILENT_DCL_CLEAR
;
default_drive_params
[
i
].
params
.
select_delay
=
2
*
HZ
/
100
;
default_drive_params
[
i
].
params
.
flags
&=
~
FD_SILENT_DCL_CLEAR
;
}
}
DPRINT
(
"Assuming %s floppy hardware
\n
"
,
param
?
"standard"
:
"broken"
);
...
...
@@ -4113,14 +4121,14 @@ static void __init daring(int *ints,int param, int param2)
static
void
__init
set_cmos
(
int
*
ints
,
int
dummy
,
int
dummy2
)
{
int
current_drive
=
0
;
int
current_drive
=
0
;
if
(
ints
[
0
]
!=
2
){
if
(
ints
[
0
]
!=
2
)
{
DPRINT
(
"wrong number of parameters for CMOS
\n
"
);
return
;
}
current_drive
=
ints
[
1
];
if
(
current_drive
<
0
||
current_drive
>=
8
){
if
(
current_drive
<
0
||
current_drive
>=
8
)
{
DPRINT
(
"bad drive for set_cmos
\n
"
);
return
;
}
...
...
@@ -4134,43 +4142,37 @@ static void __init set_cmos(int *ints, int dummy, int dummy2)
static
struct
param_table
{
const
char
*
name
;
void
(
*
fn
)(
int
*
ints
,
int
param
,
int
param2
);
void
(
*
fn
)
(
int
*
ints
,
int
param
,
int
param2
);
int
*
var
;
int
def_param
;
int
param2
;
}
config_params
[]
=
{
{
"allowed_drive_mask"
,
0
,
&
allowed_drive_mask
,
0xff
,
0
},
/* obsolete */
{
"all_drives"
,
0
,
&
allowed_drive_mask
,
0xff
,
0
},
/* obsolete */
{
"asus_pci"
,
0
,
&
allowed_drive_mask
,
0x33
,
0
},
{
"irq"
,
0
,
&
FLOPPY_IRQ
,
6
,
0
},
{
"dma"
,
0
,
&
FLOPPY_DMA
,
2
,
0
},
{
"daring"
,
daring
,
0
,
1
,
0
},
}
config_params
[]
=
{
{
"allowed_drive_mask"
,
0
,
&
allowed_drive_mask
,
0xff
,
0
},
/* obsolete */
{
"all_drives"
,
0
,
&
allowed_drive_mask
,
0xff
,
0
},
/* obsolete */
{
"asus_pci"
,
0
,
&
allowed_drive_mask
,
0x33
,
0
},
{
"irq"
,
0
,
&
FLOPPY_IRQ
,
6
,
0
},
{
"dma"
,
0
,
&
FLOPPY_DMA
,
2
,
0
},
{
"daring"
,
daring
,
0
,
1
,
0
},
#if N_FDC > 1
{
"two_fdc"
,
0
,
&
FDC2
,
0x370
,
0
},
{
"one_fdc"
,
0
,
&
FDC2
,
0
,
0
},
{
"two_fdc"
,
0
,
&
FDC2
,
0x370
,
0
},
{
"one_fdc"
,
0
,
&
FDC2
,
0
,
0
},
#endif
{
"thinkpad"
,
floppy_set_flags
,
0
,
1
,
FD_INVERTED_DCL
},
{
"broken_dcl"
,
floppy_set_flags
,
0
,
1
,
FD_BROKEN_DCL
},
{
"messages"
,
floppy_set_flags
,
0
,
1
,
FTD_MSG
},
{
"silent_dcl_clear"
,
floppy_set_flags
,
0
,
1
,
FD_SILENT_DCL_CLEAR
},
{
"debug"
,
floppy_set_flags
,
0
,
1
,
FD_DEBUG
},
{
"nodma"
,
0
,
&
can_use_virtual_dma
,
1
,
0
},
{
"omnibook"
,
0
,
&
can_use_virtual_dma
,
1
,
0
},
{
"yesdma"
,
0
,
&
can_use_virtual_dma
,
0
,
0
},
{
"fifo_depth"
,
0
,
&
fifo_depth
,
0xa
,
0
},
{
"nofifo"
,
0
,
&
no_fifo
,
0x20
,
0
},
{
"usefifo"
,
0
,
&
no_fifo
,
0
,
0
},
{
"cmos"
,
set_cmos
,
0
,
0
,
0
},
{
"slow"
,
0
,
&
slow_floppy
,
1
,
0
},
{
"unexpected_interrupts"
,
0
,
&
print_unex
,
1
,
0
},
{
"no_unexpected_interrupts"
,
0
,
&
print_unex
,
0
,
0
},
{
"L40SX"
,
0
,
&
print_unex
,
0
,
0
}
{
"thinkpad"
,
floppy_set_flags
,
0
,
1
,
FD_INVERTED_DCL
},
{
"broken_dcl"
,
floppy_set_flags
,
0
,
1
,
FD_BROKEN_DCL
},
{
"messages"
,
floppy_set_flags
,
0
,
1
,
FTD_MSG
},
{
"silent_dcl_clear"
,
floppy_set_flags
,
0
,
1
,
FD_SILENT_DCL_CLEAR
},
{
"debug"
,
floppy_set_flags
,
0
,
1
,
FD_DEBUG
},
{
"nodma"
,
0
,
&
can_use_virtual_dma
,
1
,
0
},
{
"omnibook"
,
0
,
&
can_use_virtual_dma
,
1
,
0
},
{
"yesdma"
,
0
,
&
can_use_virtual_dma
,
0
,
0
},
{
"fifo_depth"
,
0
,
&
fifo_depth
,
0xa
,
0
},
{
"nofifo"
,
0
,
&
no_fifo
,
0x20
,
0
},
{
"usefifo"
,
0
,
&
no_fifo
,
0
,
0
},
{
"cmos"
,
set_cmos
,
0
,
0
,
0
},
{
"slow"
,
0
,
&
slow_floppy
,
1
,
0
},
{
"unexpected_interrupts"
,
0
,
&
print_unex
,
1
,
0
},
{
"no_unexpected_interrupts"
,
0
,
&
print_unex
,
0
,
0
},
{
"L40SX"
,
0
,
&
print_unex
,
0
,
0
}
EXTRA_FLOPPY_PARAMS
};
...
...
@@ -4181,17 +4183,17 @@ static int __init floppy_setup(char *str)
int
param
;
int
ints
[
11
];
str
=
get_options
(
str
,
ARRAY_SIZE
(
ints
),
ints
);
str
=
get_options
(
str
,
ARRAY_SIZE
(
ints
),
ints
);
if
(
str
)
{
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
config_params
);
i
++
)
{
if
(
strcmp
(
str
,
config_params
[
i
].
name
)
==
0
)
{
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
config_params
);
i
++
)
{
if
(
strcmp
(
str
,
config_params
[
i
].
name
)
==
0
)
{
if
(
ints
[
0
])
param
=
ints
[
1
];
else
param
=
config_params
[
i
].
def_param
;
if
(
config_params
[
i
].
fn
)
config_params
[
i
].
fn
(
ints
,
param
,
fn
(
ints
,
param
,
config_params
[
i
].
param2
);
if
(
config_params
[
i
].
var
)
{
DPRINT
(
"%s=%d
\n
"
,
str
,
param
);
...
...
@@ -4205,8 +4207,8 @@ static int __init floppy_setup(char *str)
DPRINT
(
"unknown floppy option [%s]
\n
"
,
str
);
DPRINT
(
"allowed options are:"
);
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
config_params
);
i
++
)
printk
(
" %s"
,
config_params
[
i
].
name
);
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
config_params
);
i
++
)
printk
(
" %s"
,
config_params
[
i
].
name
);
printk
(
"
\n
"
);
}
else
DPRINT
(
"botched floppy option
\n
"
);
...
...
@@ -4214,7 +4216,7 @@ static int __init floppy_setup(char *str)
return
0
;
}
static
int
have_no_fdc
=
-
ENODEV
;
static
int
have_no_fdc
=
-
ENODEV
;
static
void
floppy_device_release
(
struct
device
*
dev
)
{
...
...
@@ -4231,7 +4233,7 @@ static struct platform_device floppy_device = {
static
struct
kobject
*
floppy_find
(
dev_t
dev
,
int
*
part
,
void
*
data
)
{
int
drive
=
(
*
part
&
3
)
|
((
*
part
&
0x80
)
>>
5
);
int
drive
=
(
*
part
&
3
)
|
((
*
part
&
0x80
)
>>
5
);
if
(
drive
>=
N_DRIVE
||
!
(
allowed_drive_mask
&
(
1
<<
drive
))
||
fdc_state
[
FDC
(
drive
)].
version
==
FDC_NONE
)
...
...
@@ -4244,12 +4246,12 @@ static struct kobject *floppy_find(dev_t dev, int *part, void *data)
int
__init
floppy_init
(
void
)
{
int
i
,
unit
,
drive
;
int
i
,
unit
,
drive
;
int
err
;
raw_cmd
=
NULL
;
for
(
i
=
0
;
i
<
N_DRIVE
;
i
++
)
{
for
(
i
=
0
;
i
<
N_DRIVE
;
i
++
)
{
disks
[
i
]
=
alloc_disk
(
1
);
if
(
!
disks
[
i
])
goto
Enomem
;
...
...
@@ -4264,8 +4266,8 @@ int __init floppy_init(void)
motor_off_timer
[
i
].
function
=
motor_off_callback
;
}
devfs_mk_dir
(
"floppy"
);
if
((
err
=
register_blkdev
(
FLOPPY_MAJOR
,
"fd"
)))
devfs_mk_dir
(
"floppy"
);
if
((
err
=
register_blkdev
(
FLOPPY_MAJOR
,
"fd"
)))
goto
out
;
floppy_queue
=
blk_init_queue
(
do_fd_request
,
&
floppy_lock
);
...
...
@@ -4278,7 +4280,7 @@ int __init floppy_init(void)
blk_register_region
(
MKDEV
(
FLOPPY_MAJOR
,
0
),
256
,
THIS_MODULE
,
floppy_find
,
NULL
,
NULL
);
for
(
i
=
0
;
i
<
256
;
i
++
)
for
(
i
=
0
;
i
<
256
;
i
++
)
if
(
ITYPE
(
i
))
floppy_sizes
[
i
]
=
floppy_type
[
ITYPE
(
i
)].
size
;
else
...
...
@@ -4293,7 +4295,7 @@ int __init floppy_init(void)
FDCS
->
dtr
=
-
1
;
FDCS
->
dor
=
0x4
;
#if defined(__sparc__) || defined(__mc68000__)
/*sparcs/sun3x don't have a DOR reset which we can fall back on to*/
/*sparcs/sun3x don't have a DOR reset which we can fall back on to
*/
#ifdef __mc68000__
if
(
MACH_IS_SUN3X
)
#endif
...
...
@@ -4312,7 +4314,7 @@ int __init floppy_init(void)
#endif
fdc
=
0
;
/* reset fdc in case of unexpected interrupt */
if
(
floppy_grab_irq_and_dma
()){
if
(
floppy_grab_irq_and_dma
())
{
err
=
-
EBUSY
;
goto
out1
;
}
...
...
@@ -4332,25 +4334,25 @@ int __init floppy_init(void)
for
(
i
=
0
;
i
<
N_FDC
;
i
++
)
{
fdc
=
i
;
FDCS
->
driver_version
=
FD_DRIVER_VERSION
;
for
(
unit
=
0
;
unit
<
4
;
unit
++
)
for
(
unit
=
0
;
unit
<
4
;
unit
++
)
FDCS
->
track
[
unit
]
=
0
;
if
(
FDCS
->
address
==
-
1
)
continue
;
FDCS
->
rawcmd
=
2
;
if
(
user_reset_fdc
(
-
1
,
FD_RESET_ALWAYS
,
0
))
{
if
(
user_reset_fdc
(
-
1
,
FD_RESET_ALWAYS
,
0
))
{
/* free ioports reserved by floppy_grab_irq_and_dma() */
release_region
(
FDCS
->
address
+
2
,
4
);
release_region
(
FDCS
->
address
+
7
,
1
);
release_region
(
FDCS
->
address
+
2
,
4
);
release_region
(
FDCS
->
address
+
7
,
1
);
FDCS
->
address
=
-
1
;
FDCS
->
version
=
FDC_NONE
;
continue
;
}
/* Try to determine the floppy controller type */
FDCS
->
version
=
get_fdc_version
();
if
(
FDCS
->
version
==
FDC_NONE
){
if
(
FDCS
->
version
==
FDC_NONE
)
{
/* free ioports reserved by floppy_grab_irq_and_dma() */
release_region
(
FDCS
->
address
+
2
,
4
);
release_region
(
FDCS
->
address
+
7
,
1
);
release_region
(
FDCS
->
address
+
2
,
4
);
release_region
(
FDCS
->
address
+
7
,
1
);
FDCS
->
address
=
-
1
;
continue
;
}
...
...
@@ -4362,13 +4364,13 @@ int __init floppy_init(void)
* properly, so force a reset for the standard FDC clones,
* to avoid interrupt garbage.
*/
user_reset_fdc
(
-
1
,
FD_RESET_ALWAYS
,
0
);
user_reset_fdc
(
-
1
,
FD_RESET_ALWAYS
,
0
);
}
fdc
=
0
;
fdc
=
0
;
del_timer
(
&
fd_timeout
);
current_drive
=
0
;
floppy_release_irq_and_dma
();
initialising
=
0
;
initialising
=
0
;
if
(
have_no_fdc
)
{
DPRINT
(
"no floppy controllers found
\n
"
);
flush_scheduled_work
();
...
...
@@ -4384,7 +4386,7 @@ int __init floppy_init(void)
if
(
fdc_state
[
FDC
(
drive
)].
version
==
FDC_NONE
)
continue
;
/* to be cleaned up... */
disks
[
drive
]
->
private_data
=
(
void
*
)(
long
)
drive
;
disks
[
drive
]
->
private_data
=
(
void
*
)(
long
)
drive
;
disks
[
drive
]
->
queue
=
floppy_queue
;
disks
[
drive
]
->
flags
|=
GENHD_FL_REMOVABLE
;
add_disk
(
disks
[
drive
]);
...
...
@@ -4399,9 +4401,9 @@ int __init floppy_init(void)
blk_unregister_region
(
MKDEV
(
FLOPPY_MAJOR
,
0
),
256
);
blk_cleanup_queue
(
floppy_queue
);
fail_queue:
unregister_blkdev
(
FLOPPY_MAJOR
,
"fd"
);
unregister_blkdev
(
FLOPPY_MAJOR
,
"fd"
);
out:
for
(
i
=
0
;
i
<
N_DRIVE
;
i
++
)
for
(
i
=
0
;
i
<
N_DRIVE
;
i
++
)
put_disk
(
disks
[
i
]);
devfs_remove
(
"floppy"
);
return
err
;
...
...
@@ -4419,7 +4421,7 @@ static int floppy_grab_irq_and_dma(void)
unsigned
long
flags
;
spin_lock_irqsave
(
&
floppy_usage_lock
,
flags
);
if
(
usage_count
++
){
if
(
usage_count
++
)
{
spin_unlock_irqrestore
(
&
floppy_usage_lock
,
flags
);
return
0
;
}
...
...
@@ -4442,22 +4444,24 @@ static int floppy_grab_irq_and_dma(void)
return
-
1
;
}
for
(
fdc
=
0
;
fdc
<
N_FDC
;
fdc
++
){
if
(
FDCS
->
address
!=
-
1
){
if
(
!
request_region
(
FDCS
->
address
+
2
,
4
,
"floppy"
))
{
DPRINT
(
"Floppy io-port 0x%04lx in use
\n
"
,
FDCS
->
address
+
2
);
for
(
fdc
=
0
;
fdc
<
N_FDC
;
fdc
++
)
{
if
(
FDCS
->
address
!=
-
1
)
{
if
(
!
request_region
(
FDCS
->
address
+
2
,
4
,
"floppy"
))
{
DPRINT
(
"Floppy io-port 0x%04lx in use
\n
"
,
FDCS
->
address
+
2
);
goto
cleanup1
;
}
if
(
!
request_region
(
FDCS
->
address
+
7
,
1
,
"floppy DIR"
))
{
DPRINT
(
"Floppy io-port 0x%04lx in use
\n
"
,
FDCS
->
address
+
7
);
if
(
!
request_region
(
FDCS
->
address
+
7
,
1
,
"floppy DIR"
))
{
DPRINT
(
"Floppy io-port 0x%04lx in use
\n
"
,
FDCS
->
address
+
7
);
goto
cleanup2
;
}
/* address + 6 is reserved, and may be taken by IDE.
* Unfortunately, Adaptec doesn't know this :-(, */
}
}
for
(
fdc
=
0
;
fdc
<
N_FDC
;
fdc
++
)
{
if
(
FDCS
->
address
!=
-
1
){
for
(
fdc
=
0
;
fdc
<
N_FDC
;
fdc
++
)
{
if
(
FDCS
->
address
!=
-
1
)
{
reset_fdc_info
(
1
);
fd_outb
(
FDCS
->
dor
,
FD_DOR
);
}
...
...
@@ -4480,7 +4484,7 @@ static int floppy_grab_irq_and_dma(void)
cleanup1:
fd_free_irq
();
fd_free_dma
();
while
(
--
fdc
>=
0
)
{
while
(
--
fdc
>=
0
)
{
release_region
(
FDCS
->
address
+
2
,
4
);
release_region
(
FDCS
->
address
+
7
,
1
);
}
...
...
@@ -4503,17 +4507,16 @@ static void floppy_release_irq_and_dma(void)
unsigned
long
flags
;
spin_lock_irqsave
(
&
floppy_usage_lock
,
flags
);
if
(
--
usage_count
){
if
(
--
usage_count
)
{
spin_unlock_irqrestore
(
&
floppy_usage_lock
,
flags
);
return
;
}
spin_unlock_irqrestore
(
&
floppy_usage_lock
,
flags
);
if
(
irqdma_allocated
)
{
if
(
irqdma_allocated
)
{
fd_disable_dma
();
fd_free_dma
();
fd_free_irq
();
irqdma_allocated
=
0
;
irqdma_allocated
=
0
;
}
set_dor
(
0
,
~
0
,
8
);
#if N_FDC > 1
...
...
@@ -4522,17 +4525,16 @@ static void floppy_release_irq_and_dma(void)
floppy_enable_hlt
();
if
(
floppy_track_buffer
&&
max_buffer_sectors
)
{
tmpsize
=
max_buffer_sectors
*
1024
;
tmpsize
=
max_buffer_sectors
*
1024
;
tmpaddr
=
(
unsigned
long
)
floppy_track_buffer
;
floppy_track_buffer
=
NULL
;
max_buffer_sectors
=
0
;
buffer_min
=
buffer_max
=
-
1
;
fd_dma_mem_free
(
tmpaddr
,
tmpsize
);
}
#ifdef FLOPPY_SANITY_CHECK
#ifndef __sparc__
for
(
drive
=
0
;
drive
<
N_FDC
*
4
;
drive
++
)
for
(
drive
=
0
;
drive
<
N_FDC
*
4
;
drive
++
)
if
(
timer_pending
(
motor_off_timer
+
drive
))
printk
(
"motor off timer %d still active
\n
"
,
drive
);
#endif
...
...
@@ -4547,25 +4549,25 @@ static void floppy_release_irq_and_dma(void)
old_fdc
=
fdc
;
for
(
fdc
=
0
;
fdc
<
N_FDC
;
fdc
++
)
if
(
FDCS
->
address
!=
-
1
)
{
release_region
(
FDCS
->
address
+
2
,
4
);
release_region
(
FDCS
->
address
+
7
,
1
);
release_region
(
FDCS
->
address
+
2
,
4
);
release_region
(
FDCS
->
address
+
7
,
1
);
}
fdc
=
old_fdc
;
}
#ifdef MODULE
char
*
floppy
;
static
void
unregister_devfs_entries
(
int
drive
)
static
void
unregister_devfs_entries
(
int
drive
)
{
int
i
;
if
(
UDP
->
cmos
<
NUMBER
(
default_drive_params
))
{
i
=
0
;
do
{
devfs_remove
(
"floppy/%d%s"
,
drive
,
table
[
table_sup
[
UDP
->
cmos
][
i
]]);
devfs_remove
(
"floppy/%d%s"
,
drive
,
table
[
table_sup
[
UDP
->
cmos
][
i
]]);
}
while
(
table_sup
[
UDP
->
cmos
][
i
++
]);
}
}
...
...
@@ -4574,8 +4576,8 @@ static void __init parse_floppy_cfg_string(char *cfg)
{
char
*
ptr
;
while
(
*
cfg
)
{
for
(
ptr
=
cfg
;
*
cfg
&&
*
cfg
!=
' '
&&
*
cfg
!=
'\t'
;
cfg
++
)
;
while
(
*
cfg
)
{
for
(
ptr
=
cfg
;
*
cfg
&&
*
cfg
!=
' '
&&
*
cfg
!=
'\t'
;
cfg
++
)
;
if
(
*
cfg
)
{
*
cfg
=
'\0'
;
cfg
++
;
...
...
@@ -4628,16 +4630,16 @@ void cleanup_module(void)
wait_for_completion
(
&
device_release
);
}
MODULE_PARM
(
floppy
,
"s"
);
MODULE_PARM
(
FLOPPY_IRQ
,
"i"
);
MODULE_PARM
(
FLOPPY_DMA
,
"i"
);
MODULE_PARM
(
floppy
,
"s"
);
MODULE_PARM
(
FLOPPY_IRQ
,
"i"
);
MODULE_PARM
(
FLOPPY_DMA
,
"i"
);
MODULE_AUTHOR
(
"Alain L. Knaff"
);
MODULE_SUPPORTED_DEVICE
(
"fd"
);
MODULE_LICENSE
(
"GPL"
);
#else
__setup
(
"floppy="
,
floppy_setup
);
__setup
(
"floppy="
,
floppy_setup
);
module_init
(
floppy_init
)
#endif
...
...
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