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
91c42c4d
Commit
91c42c4d
authored
Sep 21, 2002
by
Alexander Viro
Committed by
Linus Torvalds
Sep 21, 2002
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[PATCH] Lindent pd.c
pd.c fed through Lindent
parent
f299adc6
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
466 additions
and
432 deletions
+466
-432
drivers/block/paride/pd.c
drivers/block/paride/pd.c
+466
-432
No files found.
drivers/block/paride/pd.c
View file @
91c42c4d
...
...
@@ -132,12 +132,13 @@ static int cluster = 64;
static
int
nice
=
0
;
static
int
disable
=
0
;
static
int
drive0
[
8
]
=
{
0
,
0
,
0
,
-
1
,
0
,
1
,
-
1
,
-
1
};
static
int
drive1
[
8
]
=
{
0
,
0
,
0
,
-
1
,
0
,
1
,
-
1
,
-
1
};
static
int
drive2
[
8
]
=
{
0
,
0
,
0
,
-
1
,
0
,
1
,
-
1
,
-
1
};
static
int
drive3
[
8
]
=
{
0
,
0
,
0
,
-
1
,
0
,
1
,
-
1
,
-
1
};
static
int
drive0
[
8
]
=
{
0
,
0
,
0
,
-
1
,
0
,
1
,
-
1
,
-
1
};
static
int
drive1
[
8
]
=
{
0
,
0
,
0
,
-
1
,
0
,
1
,
-
1
,
-
1
};
static
int
drive2
[
8
]
=
{
0
,
0
,
0
,
-
1
,
0
,
1
,
-
1
,
-
1
};
static
int
drive3
[
8
]
=
{
0
,
0
,
0
,
-
1
,
0
,
1
,
-
1
,
-
1
};
static
int
(
*
drives
[
4
])[
8
]
=
{
&
drive0
,
&
drive1
,
&
drive2
,
&
drive3
};
static
int
(
*
drives
[
4
])[
8
]
=
{
&
drive0
,
&
drive1
,
&
drive2
,
&
drive3
};
static
int
pd_drive_count
;
#define D_PRT 0
...
...
@@ -168,30 +169,31 @@ static spinlock_t pd_lock = SPIN_LOCK_UNLOCKED;
#include "setup.h"
static
STT
pd_stt
[
7
]
=
{{
"drive0"
,
8
,
drive0
},
{
"drive1"
,
8
,
drive1
},
{
"drive2"
,
8
,
drive2
},
{
"drive3"
,
8
,
drive3
},
{
"disable"
,
1
,
&
disable
},
{
"cluster"
,
1
,
&
cluster
},
{
"nice"
,
1
,
&
nice
}};
static
STT
pd_stt
[
7
]
=
{
{
"drive0"
,
8
,
drive0
},
{
"drive1"
,
8
,
drive1
},
{
"drive2"
,
8
,
drive2
},
{
"drive3"
,
8
,
drive3
},
{
"disable"
,
1
,
&
disable
},
{
"cluster"
,
1
,
&
cluster
},
{
"nice"
,
1
,
&
nice
}
};
void
pd_setup
(
char
*
str
,
int
*
ints
)
void
pd_setup
(
char
*
str
,
int
*
ints
)
{
generic_setup
(
pd_stt
,
7
,
str
);
generic_setup
(
pd_stt
,
7
,
str
);
}
#endif
MODULE_PARM
(
verbose
,
"i"
);
MODULE_PARM
(
major
,
"i"
);
MODULE_PARM
(
name
,
"s"
);
MODULE_PARM
(
cluster
,
"i"
);
MODULE_PARM
(
nice
,
"i"
);
MODULE_PARM
(
drive0
,
"1-8i"
);
MODULE_PARM
(
drive1
,
"1-8i"
);
MODULE_PARM
(
drive2
,
"1-8i"
);
MODULE_PARM
(
drive3
,
"1-8i"
);
MODULE_PARM
(
verbose
,
"i"
);
MODULE_PARM
(
major
,
"i"
);
MODULE_PARM
(
name
,
"s"
);
MODULE_PARM
(
cluster
,
"i"
);
MODULE_PARM
(
nice
,
"i"
);
MODULE_PARM
(
drive0
,
"1-8i"
);
MODULE_PARM
(
drive1
,
"1-8i"
);
MODULE_PARM
(
drive2
,
"1-8i"
);
MODULE_PARM
(
drive3
,
"1-8i"
);
#include "paride.h"
...
...
@@ -250,26 +252,26 @@ MODULE_PARM(drive3,"1-8i");
#define IDE_IDENTIFY 0xec
#define IDE_EJECT 0xed
void
pd_setup
(
char
*
str
,
int
*
ints
);
void
pd_setup
(
char
*
str
,
int
*
ints
);
static
int
pd_open
(
struct
inode
*
inode
,
struct
file
*
file
);
static
void
do_pd_request
(
request_queue_t
*
q
);
static
int
pd_ioctl
(
struct
inode
*
inode
,
struct
file
*
file
,
static
int
pd_ioctl
(
struct
inode
*
inode
,
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
);
static
int
pd_release
(
struct
inode
*
inode
,
struct
file
*
file
);
static
int
pd_release
(
struct
inode
*
inode
,
struct
file
*
file
);
static
int
pd_revalidate
(
kdev_t
dev
);
static
int
pd_detect
(
void
);
static
void
do_pd_read
(
void
);
static
void
do_pd_read_start
(
void
);
static
void
do_pd_write
(
void
);
static
void
do_pd_write_start
(
void
);
static
void
do_pd_read_drq
(
void
);
static
void
do_pd_write_done
(
void
);
static
void
do_pd_read_drq
(
void
);
static
void
do_pd_write_done
(
void
);
static
int
pd_identify
(
int
unit
);
static
int
pd_identify
(
int
unit
);
static
void
pd_media_check
(
int
unit
);
static
void
pd_doorlock
(
int
unit
,
int
func
);
static
int
pd_check_media
(
kdev_t
dev
);
static
void
pd_eject
(
int
unit
);
static
void
pd_eject
(
int
unit
);
#define PD_NAMELEN 8
...
...
@@ -313,50 +315,53 @@ static int pd_run; /* sectors in current cluster */
static
int
pd_cmd
;
/* current command READ/WRITE */
static
int
pd_unit
;
/* unit of current request */
static
int
pd_dev
;
/* minor of current request */
static
char
*
pd_buf
;
/* buffer for request in progress */
static
char
*
pd_buf
;
/* buffer for request in progress */
static
DECLARE_WAIT_QUEUE_HEAD
(
pd_wait_open
);
static
char
*
pd_errs
[
17
]
=
{
"ERR"
,
"INDEX"
,
"ECC"
,
"DRQ"
,
"SEEK"
,
"WRERR"
,
"READY"
,
"BUSY"
,
"AMNF"
,
"TK0NF"
,
"ABRT"
,
"MCR"
,
"IDNF"
,
"MC"
,
"UNC"
,
"???"
,
"TMO"
};
static
char
*
pd_errs
[
17
]
=
{
"ERR"
,
"INDEX"
,
"ECC"
,
"DRQ"
,
"SEEK"
,
"WRERR"
,
"READY"
,
"BUSY"
,
"AMNF"
,
"TK0NF"
,
"ABRT"
,
"MCR"
,
"IDNF"
,
"MC"
,
"UNC"
,
"???"
,
"TMO"
};
/* kernel glue structures */
extern
struct
block_device_operations
pd_fops
;
static
struct
block_device_operations
pd_fops
=
{
owner:
THIS_MODULE
,
open:
pd_open
,
release:
pd_release
,
ioctl:
pd_ioctl
,
check_media_change:
pd_check_media
,
revalidate:
pd_revalidate
.
owner
=
THIS_MODULE
,
.
open
=
pd_open
,
.
release
=
pd_release
,
.
ioctl
=
pd_ioctl
,
.
check_media_change
=
pd_check_media
,
.
revalidate
=
pd_revalidate
};
void
pd_init_units
(
void
)
{
int
unit
,
j
;
static
void
pd_init_units
(
void
)
{
int
unit
,
j
;
pd_drive_count
=
0
;
for
(
unit
=
0
;
unit
<
PD_UNITS
;
unit
++
)
{
PD
.
pi
=
&
PD
.
pia
;
for
(
unit
=
0
;
unit
<
PD_UNITS
;
unit
++
)
{
PD
.
pi
=
&
PD
.
pia
;
PD
.
access
=
0
;
PD
.
changed
=
1
;
PD
.
capacity
=
0
;
PD
.
drive
=
DU
[
D_SLV
];
PD
.
present
=
0
;
j
=
0
;
while
((
j
<
PD_NAMELEN
-
2
)
&&
(
PD
.
name
[
j
]
=
name
[
j
]))
j
++
;
while
((
j
<
PD_NAMELEN
-
2
)
&&
(
PD
.
name
[
j
]
=
name
[
j
]))
j
++
;
PD
.
name
[
j
++
]
=
'a'
+
unit
;
PD
.
name
[
j
]
=
0
;
PD
.
alt_geom
=
DU
[
D_GEO
];
PD
.
standby
=
DU
[
D_SBY
];
if
(
DU
[
D_PRT
])
pd_drive_count
++
;
if
(
DU
[
D_PRT
])
pd_drive_count
++
;
}
}
static
int
pd_open
(
struct
inode
*
inode
,
struct
file
*
file
)
static
int
pd_open
(
struct
inode
*
inode
,
struct
file
*
file
)
{
int
unit
=
DEVICE_NR
(
inode
->
i_rdev
);
...
...
@@ -367,12 +372,12 @@ static int pd_open (struct inode *inode, struct file *file)
if
(
PD
.
removable
)
{
pd_media_check
(
unit
);
pd_doorlock
(
unit
,
IDE_DOORLOCK
);
pd_doorlock
(
unit
,
IDE_DOORLOCK
);
}
return
0
;
}
static
int
pd_ioctl
(
struct
inode
*
inode
,
struct
file
*
file
,
static
int
pd_ioctl
(
struct
inode
*
inode
,
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
struct
hd_geometry
*
geo
=
(
struct
hd_geometry
*
)
arg
;
...
...
@@ -383,15 +388,18 @@ static int pd_ioctl(struct inode *inode,struct file *file,
switch
(
cmd
)
{
case
CDROMEJECT
:
if
(
PD
.
access
==
1
)
pd_eject
(
unit
);
if
(
PD
.
access
==
1
)
pd_eject
(
unit
);
return
0
;
case
HDIO_GETGEO
:
if
(
!
geo
)
return
-
EINVAL
;
err
=
verify_area
(
VERIFY_WRITE
,
geo
,
sizeof
(
*
geo
));
if
(
err
)
return
err
;
if
(
!
geo
)
return
-
EINVAL
;
err
=
verify_area
(
VERIFY_WRITE
,
geo
,
sizeof
(
*
geo
));
if
(
err
)
return
err
;
if
(
PD
.
alt_geom
)
{
put_user
(
PD
.
capacity
/
(
PD_LOG_HEADS
*
PD_LOG_SECTS
),
put_user
(
PD
.
capacity
/
(
PD_LOG_HEADS
*
PD_LOG_SECTS
),
(
short
*
)
&
geo
->
cylinders
);
put_user
(
PD_LOG_HEADS
,
(
char
*
)
&
geo
->
heads
);
put_user
(
PD_LOG_SECTS
,
(
char
*
)
&
geo
->
sectors
);
...
...
@@ -400,24 +408,24 @@ static int pd_ioctl(struct inode *inode,struct file *file,
put_user
(
PD
.
heads
,
(
char
*
)
&
geo
->
heads
);
put_user
(
PD
.
sectors
,
(
char
*
)
&
geo
->
sectors
);
}
put_user
(
get_start_sect
(
inode
->
i_bdev
),
(
long
*
)
&
geo
->
start
);
put_user
(
get_start_sect
(
inode
->
i_bdev
),
(
long
*
)
&
geo
->
start
);
return
0
;
default:
return
-
EINVAL
;
}
}
static
int
pd_release
(
struct
inode
*
inode
,
struct
file
*
file
)
static
int
pd_release
(
struct
inode
*
inode
,
struct
file
*
file
)
{
int
unit
=
DEVICE_NR
(
inode
->
i_rdev
);
if
(
!--
PD
.
access
&&
PD
.
removable
)
pd_doorlock
(
unit
,
IDE_DOORUNLOCK
);
pd_doorlock
(
unit
,
IDE_DOORUNLOCK
);
return
0
;
}
static
int
pd_check_media
(
kdev_t
dev
)
static
int
pd_check_media
(
kdev_t
dev
)
{
int
r
,
unit
=
DEVICE_NR
(
dev
);
if
((
unit
>=
PD_UNITS
)
||
(
!
PD
.
present
))
...
...
@@ -449,60 +457,63 @@ static int pd_revalidate(kdev_t dev)
/* ide command interface */
static
void
pd_print_error
(
int
unit
,
char
*
msg
,
int
status
)
{
int
i
;
static
void
pd_print_error
(
int
unit
,
char
*
msg
,
int
status
)
{
int
i
;
printk
(
"%s: %s: status = 0x%x ="
,
PD
.
name
,
msg
,
status
);
for
(
i
=
0
;
i
<
18
;
i
++
)
if
(
status
&
(
1
<<
i
))
printk
(
" %s"
,
pd_errs
[
i
]);
printk
(
"%s: %s: status = 0x%x ="
,
PD
.
name
,
msg
,
status
);
for
(
i
=
0
;
i
<
18
;
i
++
)
if
(
status
&
(
1
<<
i
))
printk
(
" %s"
,
pd_errs
[
i
]);
printk
(
"
\n
"
);
}
static
void
pd_reset
(
int
unit
)
/* called only for MASTER drive */
{
pi_connect
(
PI
);
WR
(
1
,
6
,
4
);
static
void
pd_reset
(
int
unit
)
{
/* called only for MASTER drive */
pi_connect
(
PI
);
WR
(
1
,
6
,
4
);
udelay
(
50
);
WR
(
1
,
6
,
0
);
WR
(
1
,
6
,
0
);
pi_disconnect
(
PI
);
udelay
(
250
);
}
#define DBMSG(msg) ((verbose>1)?(msg):NULL)
static
int
pd_wait_for
(
int
unit
,
int
w
,
char
*
msg
)
/* polled wait */
{
int
k
,
r
,
e
;
static
int
pd_wait_for
(
int
unit
,
int
w
,
char
*
msg
)
{
/* polled wait */
int
k
,
r
,
e
;
k
=
0
;
while
(
k
<
PD_SPIN
)
{
r
=
RR
(
1
,
6
);
k
=
0
;
while
(
k
<
PD_SPIN
)
{
r
=
RR
(
1
,
6
);
k
++
;
if
(((
r
&
w
)
==
w
)
&&
!
(
r
&
STAT_BUSY
))
break
;
if
(((
r
&
w
)
==
w
)
&&
!
(
r
&
STAT_BUSY
))
break
;
udelay
(
PD_SPIN_DEL
);
}
e
=
(
RR
(
0
,
1
)
<<
8
)
+
RR
(
0
,
7
);
if
(
k
>=
PD_SPIN
)
e
|=
ERR_TMO
;
if
((
e
&
(
STAT_ERR
|
ERR_TMO
))
&&
(
msg
!=
NULL
))
pd_print_error
(
unit
,
msg
,
e
);
e
=
(
RR
(
0
,
1
)
<<
8
)
+
RR
(
0
,
7
);
if
(
k
>=
PD_SPIN
)
e
|=
ERR_TMO
;
if
((
e
&
(
STAT_ERR
|
ERR_TMO
))
&&
(
msg
!=
NULL
))
pd_print_error
(
unit
,
msg
,
e
);
return
e
;
}
static
void
pd_send_command
(
int
unit
,
int
n
,
int
s
,
int
h
,
int
c0
,
int
c1
,
int
func
)
static
void
pd_send_command
(
int
unit
,
int
n
,
int
s
,
int
h
,
int
c0
,
int
c1
,
int
func
)
{
WR
(
0
,
6
,
DRIVE
+
h
);
WR
(
0
,
1
,
0
);
/* the IDE task file */
WR
(
0
,
2
,
n
);
WR
(
0
,
3
,
s
);
WR
(
0
,
4
,
c0
);
WR
(
0
,
5
,
c1
);
WR
(
0
,
7
,
func
);
WR
(
0
,
6
,
DRIVE
+
h
);
WR
(
0
,
1
,
0
);
/* the IDE task file */
WR
(
0
,
2
,
n
);
WR
(
0
,
3
,
s
);
WR
(
0
,
4
,
c0
);
WR
(
0
,
5
,
c1
);
WR
(
0
,
7
,
func
);
udelay
(
1
);
}
static
void
pd_ide_command
(
int
unit
,
int
func
,
int
block
,
int
count
)
static
void
pd_ide_command
(
int
unit
,
int
func
,
int
block
,
int
count
)
{
int
c1
,
c0
,
h
,
s
;
...
...
@@ -512,12 +523,12 @@ static void pd_ide_command( int unit, int func, int block, int count )
c1
=
(
block
>>=
8
)
&
255
;
h
=
((
block
>>=
8
)
&
15
)
+
0x40
;
}
else
{
s
=
(
block
%
PD
.
sectors
)
+
1
;
h
=
(
block
/=
PD
.
sectors
)
%
PD
.
heads
;
c0
=
(
block
/=
PD
.
heads
)
%
256
;
s
=
(
block
%
PD
.
sectors
)
+
1
;
h
=
(
block
/=
PD
.
sectors
)
%
PD
.
heads
;
c0
=
(
block
/=
PD
.
heads
)
%
256
;
c1
=
(
block
>>=
8
);
}
pd_send_command
(
unit
,
count
,
s
,
h
,
c0
,
c1
,
func
);
pd_send_command
(
unit
,
count
,
s
,
h
,
c0
,
c1
,
func
);
}
/* According to the ATA standard, the default CHS geometry should be
...
...
@@ -526,76 +537,78 @@ static void pd_ide_command( int unit, int func, int block, int count )
parameters are initialised.
*/
static
void
pd_init_dev_parms
(
int
unit
)
{
pi_connect
(
PI
);
pd_wait_for
(
unit
,
0
,
DBMSG
(
"before init_dev_parms"
));
pd_send_command
(
unit
,
PD
.
sectors
,
0
,
PD
.
heads
-
1
,
0
,
0
,
IDE_INIT_DEV_PARMS
);
static
void
pd_init_dev_parms
(
int
unit
)
{
pi_connect
(
PI
);
pd_wait_for
(
unit
,
0
,
DBMSG
(
"before init_dev_parms"
));
pd_send_command
(
unit
,
PD
.
sectors
,
0
,
PD
.
heads
-
1
,
0
,
0
,
IDE_INIT_DEV_PARMS
);
udelay
(
300
);
pd_wait_for
(
unit
,
0
,
"Initialise device parameters"
);
pd_wait_for
(
unit
,
0
,
"Initialise device parameters"
);
pi_disconnect
(
PI
);
}
static
void
pd_doorlock
(
int
unit
,
int
func
)
{
pi_connect
(
PI
);
if
(
pd_wait_for
(
unit
,
STAT_READY
,
"Lock"
)
&
STAT_ERR
)
{
static
void
pd_doorlock
(
int
unit
,
int
func
)
{
pi_connect
(
PI
);
if
(
pd_wait_for
(
unit
,
STAT_READY
,
"Lock"
)
&
STAT_ERR
)
{
pi_disconnect
(
PI
);
return
;
}
pd_send_command
(
unit
,
1
,
0
,
0
,
0
,
0
,
func
);
pd_wait_for
(
unit
,
STAT_READY
,
"Lock done"
);
pd_send_command
(
unit
,
1
,
0
,
0
,
0
,
0
,
func
);
pd_wait_for
(
unit
,
STAT_READY
,
"Lock done"
);
pi_disconnect
(
PI
);
}
static
void
pd_eject
(
int
unit
)
{
pi_connect
(
PI
);
pd_wait_for
(
unit
,
0
,
DBMSG
(
"before unlock on eject"
));
pd_send_command
(
unit
,
1
,
0
,
0
,
0
,
0
,
IDE_DOORUNLOCK
);
pd_wait_for
(
unit
,
0
,
DBMSG
(
"after unlock on eject"
));
pd_wait_for
(
unit
,
0
,
DBMSG
(
"before eject"
));
pd_send_command
(
unit
,
0
,
0
,
0
,
0
,
0
,
IDE_EJECT
);
pd_wait_for
(
unit
,
0
,
DBMSG
(
"after eject"
));
static
void
pd_eject
(
int
unit
)
{
pi_connect
(
PI
);
pd_wait_for
(
unit
,
0
,
DBMSG
(
"before unlock on eject"
));
pd_send_command
(
unit
,
1
,
0
,
0
,
0
,
0
,
IDE_DOORUNLOCK
);
pd_wait_for
(
unit
,
0
,
DBMSG
(
"after unlock on eject"
));
pd_wait_for
(
unit
,
0
,
DBMSG
(
"before eject"
));
pd_send_command
(
unit
,
0
,
0
,
0
,
0
,
0
,
IDE_EJECT
);
pd_wait_for
(
unit
,
0
,
DBMSG
(
"after eject"
));
pi_disconnect
(
PI
);
}
static
void
pd_media_check
(
int
unit
)
{
int
r
;
static
void
pd_media_check
(
int
unit
)
{
int
r
;
pi_connect
(
PI
);
r
=
pd_wait_for
(
unit
,
STAT_READY
,
DBMSG
(
"before media_check"
));
r
=
pd_wait_for
(
unit
,
STAT_READY
,
DBMSG
(
"before media_check"
));
if
(
!
(
r
&
STAT_ERR
))
{
pd_send_command
(
unit
,
1
,
1
,
0
,
0
,
0
,
IDE_READ_VRFY
);
r
=
pd_wait_for
(
unit
,
STAT_READY
,
DBMSG
(
"RDY after READ_VRFY"
));
}
else
PD
.
changed
=
1
;
/* say changed if other error */
pd_send_command
(
unit
,
1
,
1
,
0
,
0
,
0
,
IDE_READ_VRFY
);
r
=
pd_wait_for
(
unit
,
STAT_READY
,
DBMSG
(
"RDY after READ_VRFY"
));
}
else
PD
.
changed
=
1
;
/* say changed if other error */
if
(
r
&
ERR_MC
)
{
PD
.
changed
=
1
;
pd_send_command
(
unit
,
1
,
0
,
0
,
0
,
0
,
IDE_ACKCHANGE
);
pd_wait_for
(
unit
,
STAT_READY
,
DBMSG
(
"RDY after ACKCHANGE"
));
pd_send_command
(
unit
,
1
,
1
,
0
,
0
,
0
,
IDE_READ_VRFY
);
r
=
pd_wait_for
(
unit
,
STAT_READY
,
DBMSG
(
"RDY after VRFY"
));
pd_send_command
(
unit
,
1
,
0
,
0
,
0
,
0
,
IDE_ACKCHANGE
);
pd_wait_for
(
unit
,
STAT_READY
,
DBMSG
(
"RDY after ACKCHANGE"
));
pd_send_command
(
unit
,
1
,
1
,
0
,
0
,
0
,
IDE_READ_VRFY
);
r
=
pd_wait_for
(
unit
,
STAT_READY
,
DBMSG
(
"RDY after VRFY"
));
}
pi_disconnect
(
PI
);
}
static
void
pd_standby_off
(
int
unit
)
{
pi_connect
(
PI
);
pd_wait_for
(
unit
,
0
,
DBMSG
(
"before STANDBY"
));
pd_send_command
(
unit
,
0
,
0
,
0
,
0
,
0
,
IDE_STANDBY
);
pd_wait_for
(
unit
,
0
,
DBMSG
(
"after STANDBY"
));
static
void
pd_standby_off
(
int
unit
)
{
pi_connect
(
PI
);
pd_wait_for
(
unit
,
0
,
DBMSG
(
"before STANDBY"
));
pd_send_command
(
unit
,
0
,
0
,
0
,
0
,
0
,
IDE_STANDBY
);
pd_wait_for
(
unit
,
0
,
DBMSG
(
"after STANDBY"
));
pi_disconnect
(
PI
);
}
#define word_val(n) ((pd_scratch[2*n]&0xff)+256*(pd_scratch[2*n+1]&0xff))
static
int
pd_identify
(
int
unit
)
{
int
j
;
char
id
[
PD_ID_LEN
+
1
];
static
int
pd_identify
(
int
unit
)
{
int
j
;
char
id
[
PD_ID_LEN
+
1
];
/* WARNING: here there may be dragons. reset() applies to both drives,
but we call it only on probing the MASTER. This should allow most
...
...
@@ -603,52 +616,58 @@ static int pd_identify( int unit )
settings on the SLAVE drive.
*/
if
(
PD
.
drive
==
0
)
pd_reset
(
unit
);
if
(
PD
.
drive
==
0
)
pd_reset
(
unit
);
pi_connect
(
PI
);
WR
(
0
,
6
,
DRIVE
);
pd_wait_for
(
unit
,
0
,
DBMSG
(
"before IDENT"
));
pd_send_command
(
unit
,
1
,
0
,
0
,
0
,
0
,
IDE_IDENTIFY
);
WR
(
0
,
6
,
DRIVE
);
pd_wait_for
(
unit
,
0
,
DBMSG
(
"before IDENT"
));
pd_send_command
(
unit
,
1
,
0
,
0
,
0
,
0
,
IDE_IDENTIFY
);
if
(
pd_wait_for
(
unit
,
STAT_DRQ
,
DBMSG
(
"IDENT DRQ"
))
&
STAT_ERR
)
{
if
(
pd_wait_for
(
unit
,
STAT_DRQ
,
DBMSG
(
"IDENT DRQ"
))
&
STAT_ERR
)
{
pi_disconnect
(
PI
);
return
0
;
}
pi_read_block
(
PI
,
pd_scratch
,
512
);
pi_read_block
(
PI
,
pd_scratch
,
512
);
pi_disconnect
(
PI
);
PD
.
can_lba
=
pd_scratch
[
99
]
&
2
;
PD
.
sectors
=
le16_to_cpu
(
*
(
u16
*
)(
pd_scratch
+
12
));
PD
.
heads
=
le16_to_cpu
(
*
(
u16
*
)(
pd_scratch
+
6
));
PD
.
cylinders
=
le16_to_cpu
(
*
(
u16
*
)(
pd_scratch
+
2
));
PD
.
sectors
=
le16_to_cpu
(
*
(
u16
*
)
(
pd_scratch
+
12
));
PD
.
heads
=
le16_to_cpu
(
*
(
u16
*
)
(
pd_scratch
+
6
));
PD
.
cylinders
=
le16_to_cpu
(
*
(
u16
*
)
(
pd_scratch
+
2
));
if
(
PD
.
can_lba
)
PD
.
capacity
=
le32_to_cpu
(
*
(
u32
*
)
(
pd_scratch
+
120
));
PD
.
capacity
=
le32_to_cpu
(
*
(
u32
*
)
(
pd_scratch
+
120
));
else
PD
.
capacity
=
PD
.
sectors
*
PD
.
heads
*
PD
.
cylinders
;
PD
.
capacity
=
PD
.
sectors
*
PD
.
heads
*
PD
.
cylinders
;
for
(
j
=
0
;
j
<
PD_ID_LEN
;
j
++
)
id
[
j
^
1
]
=
pd_scratch
[
j
+
PD_ID_OFF
];
j
=
PD_ID_LEN
-
1
;
while
((
j
>=
0
)
&&
(
id
[
j
]
<=
0x20
))
j
--
;
j
++
;
id
[
j
]
=
0
;
for
(
j
=
0
;
j
<
PD_ID_LEN
;
j
++
)
id
[
j
^
1
]
=
pd_scratch
[
j
+
PD_ID_OFF
];
j
=
PD_ID_LEN
-
1
;
while
((
j
>=
0
)
&&
(
id
[
j
]
<=
0x20
))
j
--
;
j
++
;
id
[
j
]
=
0
;
PD
.
removable
=
(
word_val
(
0
)
&
0x80
);
printk
(
"%s: %s, %s, %d blocks [%dM], (%d/%d/%d), %s media
\n
"
,
PD
.
name
,
id
,
PD
.
drive
?
"slave"
:
"master"
,
PD
.
capacity
,
PD
.
capacity
/
2048
,
PD
.
cylinders
,
PD
.
heads
,
PD
.
sectors
,
PD
.
removable
?
"removable"
:
"fixed"
);
PD
.
name
,
id
,
PD
.
drive
?
"slave"
:
"master"
,
PD
.
capacity
,
PD
.
capacity
/
2048
,
PD
.
cylinders
,
PD
.
heads
,
PD
.
sectors
,
PD
.
removable
?
"removable"
:
"fixed"
);
if
(
PD
.
capacity
)
pd_init_dev_parms
(
unit
);
if
(
!
PD
.
standby
)
pd_standby_off
(
unit
);
if
(
PD
.
capacity
)
pd_init_dev_parms
(
unit
);
if
(
!
PD
.
standby
)
pd_standby_off
(
unit
);
return
1
;
}
static
int
pd_probe_drive
(
int
unit
)
static
int
pd_probe_drive
(
int
unit
)
{
if
(
PD
.
drive
==
-
1
)
{
for
(
PD
.
drive
=
0
;
PD
.
drive
<=
1
;
PD
.
drive
++
)
for
(
PD
.
drive
=
0
;
PD
.
drive
<=
1
;
PD
.
drive
++
)
if
(
pd_identify
(
unit
))
return
1
;
return
0
;
...
...
@@ -656,31 +675,36 @@ static int pd_probe_drive( int unit )
return
pd_identify
(
unit
);
}
static
int
pd_detect
(
void
)
static
int
pd_detect
(
void
)
{
int
k
,
unit
;
k
=
0
;
if
(
pd_drive_count
==
0
)
{
/* nothing spec'd - so autoprobe for 1 */
unit
=
0
;
if
(
pi_init
(
PI
,
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
pd_scratch
,
PI_PD
,
verbose
,
PD
.
name
))
{
if
(
pi_init
(
PI
,
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
pd_scratch
,
PI_PD
,
verbose
,
PD
.
name
))
{
if
(
pd_probe_drive
(
unit
))
{
PD
.
present
=
1
;
k
=
1
;
}
else
pi_release
(
PI
);
}
else
pi_release
(
PI
);
}
}
else
for
(
unit
=
0
;
unit
<
PD_UNITS
;
unit
++
)
if
(
DU
[
D_PRT
])
if
(
pi_init
(
PI
,
0
,
DU
[
D_PRT
],
DU
[
D_MOD
],
DU
[
D_UNI
],
DU
[
D_PRO
],
DU
[
D_DLY
],
pd_scratch
,
PI_PD
,
verbose
,
PD
.
name
))
{
}
else
for
(
unit
=
0
;
unit
<
PD_UNITS
;
unit
++
)
if
(
DU
[
D_PRT
])
if
(
pi_init
(
PI
,
0
,
DU
[
D_PRT
],
DU
[
D_MOD
],
DU
[
D_UNI
],
DU
[
D_PRO
],
DU
[
D_DLY
],
pd_scratch
,
PI_PD
,
verbose
,
PD
.
name
))
{
if
(
pd_probe_drive
(
unit
))
{
PD
.
present
=
1
;
k
=
unit
+
1
;
}
else
pi_release
(
PI
);
k
=
unit
+
1
;
}
else
pi_release
(
PI
);
}
for
(
unit
=
0
;
unit
<
PD_UNITS
;
unit
++
)
{
for
(
unit
=
0
;
unit
<
PD_UNITS
;
unit
++
)
{
if
(
PD
.
present
)
{
PD
.
gd
.
major_name
=
PD
.
name
;
PD
.
gd
.
minor_shift
=
PD_BITS
;
...
...
@@ -693,24 +717,25 @@ static int pd_detect( void )
}
if
(
k
)
return
1
;
printk
(
"%s: no valid drive found
\n
"
,
name
);
printk
(
"%s: no valid drive found
\n
"
,
name
);
return
0
;
}
/* The i/o request engine */
static
int
pd_ready
(
void
)
{
int
unit
=
pd_unit
;
static
int
pd_ready
(
void
)
{
int
unit
=
pd_unit
;
return
(
!
(
RR
(
1
,
6
)
&
STAT_BUSY
))
;
return
(
!
(
RR
(
1
,
6
)
&
STAT_BUSY
))
;
}
static
void
do_pd_request
(
request_queue_t
*
q
)
static
void
do_pd_request
(
request_queue_t
*
q
)
{
int
unit
;
if
(
pd_busy
)
return
;
if
(
pd_busy
)
return
;
repeat:
if
(
blk_queue_empty
(
QUEUE
))
return
;
...
...
@@ -722,7 +747,7 @@ static void do_pd_request (request_queue_t * q)
pd_count
=
CURRENT
->
current_nr_sectors
;
if
((
pd_dev
>=
PD_DEVS
)
||
((
pd_block
+
pd_count
)
>
get_capacity
(
&
pd
[
unit
].
gd
)))
{
((
pd_block
+
pd_count
)
>
get_capacity
(
&
pd
[
unit
].
gd
)))
{
end_request
(
CURRENT
,
0
);
goto
repeat
;
}
...
...
@@ -732,21 +757,25 @@ static void do_pd_request (request_queue_t * q)
pd_retries
=
0
;
pd_busy
=
1
;
if
(
pd_cmd
==
READ
)
pi_do_claimed
(
PI
,
do_pd_read
);
else
if
(
pd_cmd
==
WRITE
)
pi_do_claimed
(
PI
,
do_pd_write
);
else
{
pd_busy
=
0
;
if
(
pd_cmd
==
READ
)
pi_do_claimed
(
PI
,
do_pd_read
);
else
if
(
pd_cmd
==
WRITE
)
pi_do_claimed
(
PI
,
do_pd_write
);
else
{
pd_busy
=
0
;
end_request
(
CURRENT
,
0
);
goto
repeat
;
}
}
static
void
pd_next_buf
(
int
unit
)
{
long
saved_flags
;
static
void
pd_next_buf
(
int
unit
)
{
long
saved_flags
;
spin_lock_irqsave
(
&
pd_lock
,
saved_flags
);
spin_lock_irqsave
(
&
pd_lock
,
saved_flags
);
end_request
(
CURRENT
,
1
);
if
(
!
pd_run
)
{
spin_unlock_irqrestore
(
&
pd_lock
,
saved_flags
);
if
(
!
pd_run
)
{
spin_unlock_irqrestore
(
&
pd_lock
,
saved_flags
);
return
;
}
...
...
@@ -754,169 +783,174 @@ static void pd_next_buf( int unit )
if
(
blk_queue_empty
(
QUEUE
)
||
(
rq_data_dir
(
CURRENT
)
!=
pd_cmd
)
||
(
minor
(
CURRENT
->
rq_dev
)
!=
pd_dev
)
||
(
CURRENT
->
sector
!=
pd_block
))
(
minor
(
CURRENT
->
rq_dev
)
!=
pd_dev
)
||
(
CURRENT
->
sector
!=
pd_block
))
printk
(
"%s: OUCH: request list changed unexpectedly
\n
"
,
PD
.
name
);
pd_count
=
CURRENT
->
current_nr_sectors
;
pd_buf
=
CURRENT
->
buffer
;
spin_unlock_irqrestore
(
&
pd_lock
,
saved_flags
);
spin_unlock_irqrestore
(
&
pd_lock
,
saved_flags
);
}
static
void
do_pd_read
(
void
)
{
ps_set_intr
(
do_pd_read_start
,
0
,
0
,
nice
);
static
void
do_pd_read
(
void
)
{
ps_set_intr
(
do_pd_read_start
,
0
,
0
,
nice
);
}
static
void
do_pd_read_start
(
void
)
{
int
unit
=
pd_unit
;
static
void
do_pd_read_start
(
void
)
{
int
unit
=
pd_unit
;
long
saved_flags
;
pd_busy
=
1
;
pi_connect
(
PI
);
if
(
pd_wait_for
(
unit
,
STAT_READY
,
"do_pd_read"
)
&
STAT_ERR
)
{
if
(
pd_wait_for
(
unit
,
STAT_READY
,
"do_pd_read"
)
&
STAT_ERR
)
{
pi_disconnect
(
PI
);
if
(
pd_retries
<
PD_MAX_RETRIES
)
{
pd_retries
++
;
pi_do_claimed
(
PI
,
do_pd_read_start
);
pi_do_claimed
(
PI
,
do_pd_read_start
);
return
;
}
spin_lock_irqsave
(
&
pd_lock
,
saved_flags
);
spin_lock_irqsave
(
&
pd_lock
,
saved_flags
);
end_request
(
CURRENT
,
0
);
pd_busy
=
0
;
do_pd_request
(
NULL
);
spin_unlock_irqrestore
(
&
pd_lock
,
saved_flags
);
spin_unlock_irqrestore
(
&
pd_lock
,
saved_flags
);
return
;
}
pd_ide_command
(
unit
,
IDE_READ
,
pd_block
,
pd_run
);
ps_set_intr
(
do_pd_read_drq
,
pd_ready
,
PD_TMO
,
nice
);
pd_ide_command
(
unit
,
IDE_READ
,
pd_block
,
pd_run
);
ps_set_intr
(
do_pd_read_drq
,
pd_ready
,
PD_TMO
,
nice
);
}
static
void
do_pd_read_drq
(
void
)
{
int
unit
=
pd_unit
;
static
void
do_pd_read_drq
(
void
)
{
int
unit
=
pd_unit
;
long
saved_flags
;
while
(
1
)
{
if
(
pd_wait_for
(
unit
,
STAT_DRQ
,
"do_pd_read_drq"
)
&
STAT_ERR
)
{
if
(
pd_wait_for
(
unit
,
STAT_DRQ
,
"do_pd_read_drq"
)
&
STAT_ERR
)
{
pi_disconnect
(
PI
);
if
(
pd_retries
<
PD_MAX_RETRIES
)
{
pd_retries
++
;
pi_do_claimed
(
PI
,
do_pd_read_start
);
pi_do_claimed
(
PI
,
do_pd_read_start
);
return
;
}
spin_lock_irqsave
(
&
pd_lock
,
saved_flags
);
spin_lock_irqsave
(
&
pd_lock
,
saved_flags
);
end_request
(
CURRENT
,
0
);
pd_busy
=
0
;
do_pd_request
(
NULL
);
spin_unlock_irqrestore
(
&
pd_lock
,
saved_flags
);
spin_unlock_irqrestore
(
&
pd_lock
,
saved_flags
);
return
;
}
pi_read_block
(
PI
,
pd_buf
,
512
);
pd_count
--
;
pd_run
--
;
pi_read_block
(
PI
,
pd_buf
,
512
);
pd_count
--
;
pd_run
--
;
pd_buf
+=
512
;
pd_block
++
;
if
(
!
pd_run
)
break
;
if
(
!
pd_count
)
pd_next_buf
(
unit
);
if
(
!
pd_run
)
break
;
if
(
!
pd_count
)
pd_next_buf
(
unit
);
}
pi_disconnect
(
PI
);
spin_lock_irqsave
(
&
pd_lock
,
saved_flags
);
spin_lock_irqsave
(
&
pd_lock
,
saved_flags
);
end_request
(
CURRENT
,
1
);
pd_busy
=
0
;
do_pd_request
(
NULL
);
spin_unlock_irqrestore
(
&
pd_lock
,
saved_flags
);
spin_unlock_irqrestore
(
&
pd_lock
,
saved_flags
);
}
static
void
do_pd_write
(
void
)
{
ps_set_intr
(
do_pd_write_start
,
0
,
0
,
nice
);
static
void
do_pd_write
(
void
)
{
ps_set_intr
(
do_pd_write_start
,
0
,
0
,
nice
);
}
static
void
do_pd_write_start
(
void
)
{
int
unit
=
pd_unit
;
static
void
do_pd_write_start
(
void
)
{
int
unit
=
pd_unit
;
long
saved_flags
;
pd_busy
=
1
;
pi_connect
(
PI
);
if
(
pd_wait_for
(
unit
,
STAT_READY
,
"do_pd_write"
)
&
STAT_ERR
)
{
if
(
pd_wait_for
(
unit
,
STAT_READY
,
"do_pd_write"
)
&
STAT_ERR
)
{
pi_disconnect
(
PI
);
if
(
pd_retries
<
PD_MAX_RETRIES
)
{
pd_retries
++
;
pi_do_claimed
(
PI
,
do_pd_write_start
);
pi_do_claimed
(
PI
,
do_pd_write_start
);
return
;
}
spin_lock_irqsave
(
&
pd_lock
,
saved_flags
);
spin_lock_irqsave
(
&
pd_lock
,
saved_flags
);
end_request
(
CURRENT
,
0
);
pd_busy
=
0
;
do_pd_request
(
NULL
);
spin_unlock_irqrestore
(
&
pd_lock
,
saved_flags
);
spin_unlock_irqrestore
(
&
pd_lock
,
saved_flags
);
return
;
}
pd_ide_command
(
unit
,
IDE_WRITE
,
pd_block
,
pd_run
);
pd_ide_command
(
unit
,
IDE_WRITE
,
pd_block
,
pd_run
);
while
(
1
)
{
if
(
pd_wait_for
(
unit
,
STAT_DRQ
,
"do_pd_write_drq"
)
&
STAT_ERR
)
{
if
(
pd_wait_for
(
unit
,
STAT_DRQ
,
"do_pd_write_drq"
)
&
STAT_ERR
)
{
pi_disconnect
(
PI
);
if
(
pd_retries
<
PD_MAX_RETRIES
)
{
pd_retries
++
;
pi_do_claimed
(
PI
,
do_pd_write_start
);
pi_do_claimed
(
PI
,
do_pd_write_start
);
return
;
}
spin_lock_irqsave
(
&
pd_lock
,
saved_flags
);
spin_lock_irqsave
(
&
pd_lock
,
saved_flags
);
end_request
(
CURRENT
,
0
);
pd_busy
=
0
;
do_pd_request
(
NULL
);
spin_unlock_irqrestore
(
&
pd_lock
,
saved_flags
);
spin_unlock_irqrestore
(
&
pd_lock
,
saved_flags
);
return
;
}
pi_write_block
(
PI
,
pd_buf
,
512
);
pd_count
--
;
pd_run
--
;
pi_write_block
(
PI
,
pd_buf
,
512
);
pd_count
--
;
pd_run
--
;
pd_buf
+=
512
;
pd_block
++
;
if
(
!
pd_run
)
break
;
if
(
!
pd_count
)
pd_next_buf
(
unit
);
if
(
!
pd_run
)
break
;
if
(
!
pd_count
)
pd_next_buf
(
unit
);
}
ps_set_intr
(
do_pd_write_done
,
pd_ready
,
PD_TMO
,
nice
);
ps_set_intr
(
do_pd_write_done
,
pd_ready
,
PD_TMO
,
nice
);
}
static
void
do_pd_write_done
(
void
)
{
int
unit
=
pd_unit
;
static
void
do_pd_write_done
(
void
)
{
int
unit
=
pd_unit
;
long
saved_flags
;
if
(
pd_wait_for
(
unit
,
STAT_READY
,
"do_pd_write_done"
)
&
STAT_ERR
)
{
if
(
pd_wait_for
(
unit
,
STAT_READY
,
"do_pd_write_done"
)
&
STAT_ERR
)
{
pi_disconnect
(
PI
);
if
(
pd_retries
<
PD_MAX_RETRIES
)
{
pd_retries
++
;
pi_do_claimed
(
PI
,
do_pd_write_start
);
pi_do_claimed
(
PI
,
do_pd_write_start
);
return
;
}
spin_lock_irqsave
(
&
pd_lock
,
saved_flags
);
spin_lock_irqsave
(
&
pd_lock
,
saved_flags
);
end_request
(
CURRENT
,
0
);
pd_busy
=
0
;
do_pd_request
(
NULL
);
spin_unlock_irqrestore
(
&
pd_lock
,
saved_flags
);
spin_unlock_irqrestore
(
&
pd_lock
,
saved_flags
);
return
;
}
pi_disconnect
(
PI
);
spin_lock_irqsave
(
&
pd_lock
,
saved_flags
);
spin_lock_irqsave
(
&
pd_lock
,
saved_flags
);
end_request
(
CURRENT
,
1
);
pd_busy
=
0
;
do_pd_request
(
NULL
);
spin_unlock_irqrestore
(
&
pd_lock
,
saved_flags
);
spin_unlock_irqrestore
(
&
pd_lock
,
saved_flags
);
}
static
int
__init
pd_init
(
void
)
{
request_queue_t
*
q
;
if
(
disable
)
return
-
1
;
if
(
register_blkdev
(
MAJOR_NR
,
name
,
&
pd_fops
))
{
printk
(
"%s: unable to get major number %d
\n
"
,
name
,
major
);
request_queue_t
*
q
;
if
(
disable
)
return
-
1
;
if
(
register_blkdev
(
MAJOR_NR
,
name
,
&
pd_fops
))
{
printk
(
"%s: unable to get major number %d
\n
"
,
name
,
major
);
return
-
1
;
}
q
=
BLK_DEFAULT_QUEUE
(
MAJOR_NR
);
...
...
@@ -924,7 +958,7 @@ static int __init pd_init(void)
blk_queue_max_sectors
(
q
,
cluster
);
printk
(
"%s: %s version %s, major %d, cluster %d, nice %d
\n
"
,
name
,
name
,
PD_VERSION
,
major
,
cluster
,
nice
);
name
,
name
,
PD_VERSION
,
major
,
cluster
,
nice
);
pd_init_units
();
if
(
!
pd_detect
())
{
unregister_blkdev
(
MAJOR_NR
,
name
);
...
...
@@ -937,7 +971,7 @@ static void __exit pd_exit(void)
{
int
unit
;
unregister_blkdev
(
MAJOR_NR
,
name
);
for
(
unit
=
0
;
unit
<
PD_UNITS
;
unit
++
)
for
(
unit
=
0
;
unit
<
PD_UNITS
;
unit
++
)
if
(
PD
.
present
)
{
del_gendisk
(
&
PD
.
gd
);
pi_release
(
PI
);
...
...
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