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