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
Hide 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
...
...
@@ -125,19 +125,20 @@
*/
static
int
verbose
=
0
;
static
int
major
=
PD_MAJOR
;
static
char
*
name
=
PD_NAME
;
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
(
*
drives
[
4
])[
8
]
=
{
&
drive0
,
&
drive1
,
&
drive2
,
&
drive3
};
static
int
verbose
=
0
;
static
int
major
=
PD_MAJOR
;
static
char
*
name
=
PD_NAME
;
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
(
*
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"
...
...
@@ -216,10 +218,10 @@ MODULE_PARM(drive3,"1-8i");
#define PD_ID_LEN 14
#define PD_MAX_RETRIES 5
#define PD_TMO 800
/* interrupt timeout in jiffies */
#define PD_SPIN_DEL 50
/* spin delay in micro-seconds */
#define PD_TMO 800
/* interrupt timeout in jiffies */
#define PD_SPIN_DEL 50
/* spin delay in micro-seconds */
#define PD_SPIN (1000000*PD_TMO)/(HZ*PD_SPIN_DEL)
#define PD_SPIN (1000000*PD_TMO)/(HZ*PD_SPIN_DEL)
#define STAT_ERR 0x00001
#define STAT_INDEX 0x00002
...
...
@@ -250,45 +252,45 @@ 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
,
unsigned
int
cmd
,
unsigned
long
arg
);
static
int
pd_release
(
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_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
struct
pd_unit
{
struct
pi_adapter
pia
;
/* interface to paride layer */
struct
pi_adapter
pia
;
/* interface to paride layer */
struct
pi_adapter
*
pi
;
int
access
;
/* count of active opens ... */
int
capacity
;
/* Size of this volume in sectors */
int
heads
;
/* physical geometry */
int
access
;
/* count of active opens ... */
int
capacity
;
/* Size of this volume in sectors */
int
heads
;
/* physical geometry */
int
sectors
;
int
cylinders
;
int
can_lba
;
int
drive
;
/* master=0 slave=1 */
int
changed
;
/* Have we seen a disk change ? */
int
removable
;
/* removable media device ? */
int
drive
;
/* master=0 slave=1 */
int
changed
;
/* Have we seen a disk change ? */
int
removable
;
/* removable media device ? */
int
standby
;
int
alt_geom
;
int
present
;
char
name
[
PD_NAMELEN
];
/* pda, pdb, etc ... */
char
name
[
PD_NAMELEN
];
/* pda, pdb, etc ... */
struct
gendisk
gd
;
};
...
...
@@ -299,81 +301,84 @@ struct pd_unit pd[PD_UNITS];
#define PD pd[unit]
#define PI PD.pi
static
char
pd_scratch
[
512
];
/* scratch block buffer */
static
char
pd_scratch
[
512
];
/* scratch block buffer */
/* the variables below are used mainly in the I/O request engine, which
processes only one request at a time.
*/
static
int
pd_retries
=
0
;
/* i/o error retry count */
static
int
pd_busy
=
0
;
/* request being processed ? */
static
int
pd_block
;
/* address of next requested block */
static
int
pd_count
;
/* number of blocks still to do */
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
int
pd_retries
=
0
;
/* i/o error retry count */
static
int
pd_busy
=
0
;
/* request being processed ? */
static
int
pd_block
;
/* address of next requested block */
static
int
pd_count
;
/* number of blocks still to do */
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
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
);
if
((
unit
>=
PD_UNITS
)
||
(
!
PD
.
present
))
if
((
unit
>=
PD_UNITS
)
||
(
!
PD
.
present
))
return
-
ENODEV
;
PD
.
access
++
;
PD
.
access
++
;
if
(
PD
.
removable
)
{
if
(
PD
.
removable
)
{
pd_media_check
(
unit
);
pd_doorlock
(
unit
,
IDE_DOORLOCK
);
pd_doorlock
(
unit
,
IDE_DOORLOCK
);
}
return
0
;
return
0
;
}
static
int
pd_ioctl
(
struct
inode
*
inode
,
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
static
int
pd_ioctl
(
struct
inode
*
inode
,
struct
file
*
file
,
unsigned
int
cmd
,
unsigned
long
arg
)
{
struct
hd_geometry
*
geo
=
(
struct
hd_geometry
*
)
arg
;
int
err
,
unit
=
DEVICE_NR
(
inode
->
i_rdev
);
...
...
@@ -382,47 +387,50 @@ static int pd_ioctl(struct inode *inode,struct file *file,
return
-
ENODEV
;
switch
(
cmd
)
{
case
CDROMEJECT
:
if
(
PD
.
access
==
1
)
pd_eject
(
unit
);
case
CDROMEJECT
:
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
;
case
HDIO_GETGEO
:
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
),
(
short
*
)
&
geo
->
cylinders
);
put_user
(
PD_LOG_HEADS
,
(
char
*
)
&
geo
->
heads
);
put_user
(
PD_LOG_SECTS
,
(
char
*
)
&
geo
->
sectors
);
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
);
}
else
{
put_user
(
PD
.
cylinders
,
(
short
*
)
&
geo
->
cylinders
);
put_user
(
PD
.
heads
,
(
char
*
)
&
geo
->
heads
);
put_user
(
PD
.
sectors
,
(
char
*
)
&
geo
->
sectors
);
put_user
(
PD
.
cylinders
,
(
short
*
)
&
geo
->
cylinders
);
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:
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
);
int
unit
=
DEVICE_NR
(
inode
->
i_rdev
);
if
(
!--
PD
.
access
&&
PD
.
removable
)
pd_doorlock
(
unit
,
IDE_DOORUNLOCK
);
if
(
!--
PD
.
access
&&
PD
.
removable
)
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
))
return
-
ENODEV
;
if
(
!
PD
.
removable
)
if
(
!
PD
.
removable
)
return
0
;
pd_media_check
(
unit
);
r
=
PD
.
changed
;
...
...
@@ -439,7 +447,7 @@ static int pd_revalidate(kdev_t dev)
set_capacity
(
&
PD
.
gd
,
PD
.
capacity
);
else
set_capacity
(
&
PD
.
gd
,
0
);
return
0
;
return
0
;
}
#define WR(c,r,v) pi_write_regr(PI,c,r,v)
...
...
@@ -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
);
udelay
(
50
);
WR
(
1
,
6
,
0
);
static
void
pd_reset
(
int
unit
)
{
/* called only for MASTER drive */
pi_connect
(
PI
);
WR
(
1
,
6
,
4
);
udelay
(
50
);
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
;
k
=
0
;
while
(
k
<
PD_SPIN
)
{
r
=
RR
(
1
,
6
);
k
++
;
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
);
return
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
++
;
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
);
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
);
udelay
(
1
);
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,129 +537,137 @@ 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
);
udelay
(
300
);
pd_wait_for
(
unit
,
0
,
"Initialise device parameters"
);
pi_disconnect
(
PI
);
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"
);
pi_disconnect
(
PI
);
}
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"
);
pi_disconnect
(
PI
);
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"
);
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"
));
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"
));
pi_disconnect
(
PI
);
}
static
void
pd_media_check
(
int
unit
)
{
int
r
;
pi_connect
(
PI
);
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 */
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"
));
}
pi_disconnect
(
PI
);
static
void
pd_media_check
(
int
unit
)
{
int
r
;
pi_connect
(
PI
);
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 */
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"
));
}
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"
));
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"
));
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
common configurations to work, but be warned that a reset can clear
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
);
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
);
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_disconnect
(
PI
);
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_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
;
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"
);
if
(
PD
.
capacity
)
pd_init_dev_parms
(
unit
);
if
(
!
PD
.
standby
)
pd_standby_off
(
unit
);
return
1
;
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
;
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"
);
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
;
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
(
pd_probe_drive
(
unit
))
{
PD
.
present
=
1
;
k
=
1
;
}
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
))
{
if
(
pd_probe_drive
(
unit
))
{
PD
.
present
=
1
;
k
=
unit
+
1
;
}
else
pi_release
(
PI
);
}
for
(
unit
=
0
;
unit
<
PD_UNITS
;
unit
++
)
{
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
(
pd_probe_drive
(
unit
))
{
PD
.
present
=
1
;
k
=
1
;
}
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
))
{
if
(
pd_probe_drive
(
unit
))
{
PD
.
present
=
1
;
k
=
unit
+
1
;
}
else
pi_release
(
PI
);
}
for
(
unit
=
0
;
unit
<
PD_UNITS
;
unit
++
)
{
if
(
PD
.
present
)
{
PD
.
gd
.
major_name
=
PD
.
name
;
PD
.
gd
.
minor_shift
=
PD_BITS
;
...
...
@@ -692,252 +716,262 @@ static int pd_detect( void )
}
}
if
(
k
)
return
1
;
printk
(
"%s: no valid drive found
\n
"
,
name
);
return
0
;
return
1
;
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
;
int
unit
;
if
(
pd_busy
)
return
;
if
(
pd_busy
)
return
;
repeat:
if
(
blk_queue_empty
(
QUEUE
))
return
;
pd_dev
=
minor
(
CURRENT
->
rq_dev
);
pd_dev
=
minor
(
CURRENT
->
rq_dev
);
pd_unit
=
unit
=
DEVICE_NR
(
CURRENT
->
rq_dev
);
pd_block
=
CURRENT
->
sector
;
pd_run
=
CURRENT
->
nr_sectors
;
pd_count
=
CURRENT
->
current_nr_sectors
;
pd_block
=
CURRENT
->
sector
;
pd_run
=
CURRENT
->
nr_sectors
;
pd_count
=
CURRENT
->
current_nr_sectors
;
if
((
pd_dev
>=
PD_DEVS
)
||
((
pd_block
+
pd_count
)
>
get_capacity
(
&
pd
[
unit
].
gd
)))
{
end_request
(
CURRENT
,
0
);
goto
repeat
;
}
if
((
pd_dev
>=
PD_DEVS
)
||
((
pd_block
+
pd_count
)
>
get_capacity
(
&
pd
[
unit
].
gd
)))
{
end_request
(
CURRENT
,
0
);
goto
repeat
;
}
pd_cmd
=
rq_data_dir
(
CURRENT
);
pd_buf
=
CURRENT
->
buffer
;
pd_retries
=
0
;
pd_buf
=
CURRENT
->
buffer
;
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
;
}
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
);
return
;
if
(
!
pd_run
)
{
spin_unlock_irqrestore
(
&
pd_lock
,
saved_flags
);
return
;
}
/* paranoia */
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
.
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
;
long
saved_flags
;
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
)
{
pi_disconnect
(
PI
);
if
(
pd_retries
<
PD_MAX_RETRIES
)
{
pd_retries
++
;
pi_do_claimed
(
PI
,
do_pd_read_start
);
pi_connect
(
PI
);
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
);
return
;
}
spin_lock_irqsave
(
&
pd_lock
,
saved_flags
);
end_request
(
CURRENT
,
0
);
pd_busy
=
0
;
}
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
);
return
;
}
pd_ide_command
(
unit
,
IDE_READ
,
pd_block
,
pd_run
);
ps_set_intr
(
do_pd_read_drq
,
pd_ready
,
PD_TMO
,
nice
);
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
);
}
static
void
do_pd_read_drq
(
void
)
{
int
unit
=
pd_unit
;
long
saved_flags
;
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
)
{
pi_disconnect
(
PI
);
if
(
pd_retries
<
PD_MAX_RETRIES
)
{
pd_retries
++
;
pi_do_claimed
(
PI
,
do_pd_read_start
);
return
;
}
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
);
return
;
}
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
);
}
pi_disconnect
(
PI
);
spin_lock_irqsave
(
&
pd_lock
,
saved_flags
);
end_request
(
CURRENT
,
1
);
pd_busy
=
0
;
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
);
return
;
}
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
);
return
;
}
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
);
}
pi_disconnect
(
PI
);
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
;
long
saved_flags
;
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
)
{
pi_disconnect
(
PI
);
if
(
pd_retries
<
PD_MAX_RETRIES
)
{
pd_retries
++
;
pi_do_claimed
(
PI
,
do_pd_write_start
);
return
;
}
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
);
return
;
}
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
)
{
pi_disconnect
(
PI
);
if
(
pd_retries
<
PD_MAX_RETRIES
)
{
pd_retries
++
;
pi_do_claimed
(
PI
,
do_pd_write_start
);
return
;
}
spin_lock_irqsave
(
&
pd_lock
,
saved_flags
);
end_request
(
CURRENT
,
0
);
pd_busy
=
0
;
pi_connect
(
PI
);
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
);
return
;
}
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
--
;
pd_buf
+=
512
;
pd_block
++
;
if
(
!
pd_run
)
break
;
if
(
!
pd_count
)
pd_next_buf
(
unit
);
}
ps_set_intr
(
do_pd_write_done
,
pd_ready
,
PD_TMO
,
nice
);
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
)
{
pi_disconnect
(
PI
);
if
(
pd_retries
<
PD_MAX_RETRIES
)
{
pd_retries
++
;
pi_do_claimed
(
PI
,
do_pd_write_start
);
return
;
}
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
);
return
;
}
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
);
}
ps_set_intr
(
do_pd_write_done
,
pd_ready
,
PD_TMO
,
nice
);
}
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
)
{
pi_disconnect
(
PI
);
if
(
pd_retries
<
PD_MAX_RETRIES
)
{
pd_retries
++
;
pi_do_claimed
(
PI
,
do_pd_write_start
);
return
;
}
spin_lock_irqsave
(
&
pd_lock
,
saved_flags
);
end_request
(
CURRENT
,
0
);
pd_busy
=
0
;
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
)
{
pi_disconnect
(
PI
);
if
(
pd_retries
<
PD_MAX_RETRIES
)
{
pd_retries
++
;
pi_do_claimed
(
PI
,
do_pd_write_start
);
return
;
}
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
);
return
;
}
pi_disconnect
(
PI
);
spin_lock_irqsave
(
&
pd_lock
,
saved_flags
);
end_request
(
CURRENT
,
1
);
pd_busy
=
0
;
spin_unlock_irqrestore
(
&
pd_lock
,
saved_flags
);
return
;
}
pi_disconnect
(
PI
);
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
);
return
-
1
;
}
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
);
blk_init_queue
(
q
,
do_pd_request
,
&
pd_lock
);
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
())
{
if
(
!
pd_detect
())
{
unregister_blkdev
(
MAJOR_NR
,
name
);
return
-
1
;
}
return
0
;
return
0
;
}
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