Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
linux
Commits
a20c0ab1
Commit
a20c0ab1
authored
Sep 07, 2002
by
Alexander Viro
Committed by
Linus Torvalds
Sep 07, 2002
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[PATCH] (17/25) Lindent pcd.c
Lindent pcd.c.
parent
9aab49e3
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
498 additions
and
453 deletions
+498
-453
drivers/block/paride/pcd.c
drivers/block/paride/pcd.c
+498
-453
No files found.
drivers/block/paride/pcd.c
View file @
a20c0ab1
...
@@ -111,18 +111,19 @@
...
@@ -111,18 +111,19 @@
*/
*/
static
int
verbose
=
0
;
static
int
verbose
=
0
;
static
int
major
=
PCD_MAJOR
;
static
int
major
=
PCD_MAJOR
;
static
char
*
name
=
PCD_NAME
;
static
char
*
name
=
PCD_NAME
;
static
int
nice
=
0
;
static
int
nice
=
0
;
static
int
disable
=
0
;
static
int
disable
=
0
;
static
int
drive0
[
6
]
=
{
0
,
0
,
0
,
-
1
,
-
1
,
-
1
};
static
int
drive0
[
6
]
=
{
0
,
0
,
0
,
-
1
,
-
1
,
-
1
};
static
int
drive1
[
6
]
=
{
0
,
0
,
0
,
-
1
,
-
1
,
-
1
};
static
int
drive1
[
6
]
=
{
0
,
0
,
0
,
-
1
,
-
1
,
-
1
};
static
int
drive2
[
6
]
=
{
0
,
0
,
0
,
-
1
,
-
1
,
-
1
};
static
int
drive2
[
6
]
=
{
0
,
0
,
0
,
-
1
,
-
1
,
-
1
};
static
int
drive3
[
6
]
=
{
0
,
0
,
0
,
-
1
,
-
1
,
-
1
};
static
int
drive3
[
6
]
=
{
0
,
0
,
0
,
-
1
,
-
1
,
-
1
};
static
int
(
*
drives
[
4
])[
6
]
=
{
&
drive0
,
&
drive1
,
&
drive2
,
&
drive3
};
static
int
(
*
drives
[
4
])[
6
]
=
{
&
drive0
,
&
drive1
,
&
drive2
,
&
drive3
};
static
int
pcd_drive_count
;
static
int
pcd_drive_count
;
#define D_PRT 0
#define D_PRT 0
...
@@ -153,28 +154,30 @@ static spinlock_t pcd_lock;
...
@@ -153,28 +154,30 @@ static spinlock_t pcd_lock;
#include "setup.h"
#include "setup.h"
static
STT
pcd_stt
[
6
]
=
{
{
"drive0"
,
6
,
drive0
},
static
STT
pcd_stt
[
6
]
=
{
{
"drive1"
,
6
,
drive1
},
{
"drive0"
,
6
,
drive0
},
{
"drive2"
,
6
,
drive2
},
{
"drive1"
,
6
,
drive1
},
{
"drive3"
,
6
,
drive3
},
{
"drive2"
,
6
,
drive2
},
{
"disable"
,
1
,
&
disable
},
{
"drive3"
,
6
,
drive3
},
{
"nice"
,
1
,
&
nice
}};
{
"disable"
,
1
,
&
disable
},
{
"nice"
,
1
,
&
nice
}
void
pcd_setup
(
char
*
str
,
int
*
ints
)
};
{
generic_setup
(
pcd_stt
,
6
,
str
);
void
pcd_setup
(
char
*
str
,
int
*
ints
)
{
generic_setup
(
pcd_stt
,
6
,
str
);
}
}
#endif
#endif
MODULE_PARM
(
verbose
,
"i"
);
MODULE_PARM
(
verbose
,
"i"
);
MODULE_PARM
(
major
,
"i"
);
MODULE_PARM
(
major
,
"i"
);
MODULE_PARM
(
name
,
"s"
);
MODULE_PARM
(
name
,
"s"
);
MODULE_PARM
(
nice
,
"i"
);
MODULE_PARM
(
nice
,
"i"
);
MODULE_PARM
(
drive0
,
"1-6i"
);
MODULE_PARM
(
drive0
,
"1-6i"
);
MODULE_PARM
(
drive1
,
"1-6i"
);
MODULE_PARM
(
drive1
,
"1-6i"
);
MODULE_PARM
(
drive2
,
"1-6i"
);
MODULE_PARM
(
drive2
,
"1-6i"
);
MODULE_PARM
(
drive3
,
"1-6i"
);
MODULE_PARM
(
drive3
,
"1-6i"
);
#include "paride.h"
#include "paride.h"
...
@@ -189,10 +192,10 @@ MODULE_PARM(drive3,"1-6i");
...
@@ -189,10 +192,10 @@ MODULE_PARM(drive3,"1-6i");
#include "pseudo.h"
#include "pseudo.h"
#define PCD_RETRIES 5
#define PCD_RETRIES 5
#define PCD_TMO 800
/* timeout in jiffies */
#define PCD_TMO 800
/* timeout in jiffies */
#define PCD_DELAY 50
/* spin delay in uS */
#define PCD_DELAY 50
/* spin delay in uS */
#define PCD_READY_TMO 20
/* in seconds */
#define PCD_READY_TMO 20
/* in seconds */
#define PCD_RESET_TMO 100
/* in tenths of a second */
#define PCD_RESET_TMO 100
/* in tenths of a second */
#define PCD_SPIN (1000000*PCD_TMO)/(HZ*PCD_DELAY)
#define PCD_SPIN (1000000*PCD_TMO)/(HZ*PCD_DELAY)
...
@@ -208,28 +211,28 @@ static int pcd_media_changed(struct cdrom_device_info *cdi, int slot_nr);
...
@@ -208,28 +211,28 @@ static int pcd_media_changed(struct cdrom_device_info *cdi, int slot_nr);
static
int
pcd_tray_move
(
struct
cdrom_device_info
*
cdi
,
int
position
);
static
int
pcd_tray_move
(
struct
cdrom_device_info
*
cdi
,
int
position
);
static
int
pcd_lock_door
(
struct
cdrom_device_info
*
cdi
,
int
lock
);
static
int
pcd_lock_door
(
struct
cdrom_device_info
*
cdi
,
int
lock
);
static
int
pcd_drive_reset
(
struct
cdrom_device_info
*
cdi
);
static
int
pcd_drive_reset
(
struct
cdrom_device_info
*
cdi
);
static
int
pcd_get_mcn
(
struct
cdrom_device_info
*
cdi
,
struct
cdrom_mcn
*
mcn
);
static
int
pcd_get_mcn
(
struct
cdrom_device_info
*
cdi
,
struct
cdrom_mcn
*
mcn
);
static
int
pcd_audio_ioctl
(
struct
cdrom_device_info
*
cdi
,
static
int
pcd_audio_ioctl
(
struct
cdrom_device_info
*
cdi
,
unsigned
int
cmd
,
void
*
arg
);
unsigned
int
cmd
,
void
*
arg
);
static
int
pcd_packet
(
struct
cdrom_device_info
*
cdi
,
static
int
pcd_packet
(
struct
cdrom_device_info
*
cdi
,
struct
cdrom_generic_command
*
cgc
);
struct
cdrom_generic_command
*
cgc
);
static
int
pcd_detect
(
void
);
static
int
pcd_detect
(
void
);
static
void
pcd_probe_capabilities
(
void
);
static
void
pcd_probe_capabilities
(
void
);
static
void
do_pcd_read_drq
(
void
);
static
void
do_pcd_read_drq
(
void
);
static
void
do_pcd_request
(
request_queue_t
*
q
);
static
void
do_pcd_request
(
request_queue_t
*
q
);
static
void
do_pcd_read
(
void
);
static
void
do_pcd_read
(
void
);
struct
pcd_unit
{
struct
pcd_unit
{
struct
pi_adapter
pia
;
/* interface to paride layer */
struct
pi_adapter
pia
;
/* interface to paride layer */
struct
pi_adapter
*
pi
;
struct
pi_adapter
*
pi
;
int
drive
;
/* master/slave */
int
drive
;
/* master/slave */
int
last_sense
;
/* result of last request sense */
int
last_sense
;
/* result of last request sense */
int
changed
;
/* media change seen */
int
changed
;
/* media change seen */
int
present
;
/* does this unit exist ? */
int
present
;
/* does this unit exist ? */
char
*
name
;
/* pcd0, pcd1, etc */
char
*
name
;
/* pcd0, pcd1, etc */
struct
cdrom_device_info
info
;
/* uniform cdrom interface */
struct
cdrom_device_info
info
;
/* uniform cdrom interface */
};
};
struct
pcd_unit
pcd
[
PCD_UNITS
];
struct
pcd_unit
pcd
[
PCD_UNITS
];
...
@@ -239,96 +242,87 @@ struct pcd_unit pcd[PCD_UNITS];
...
@@ -239,96 +242,87 @@ struct pcd_unit pcd[PCD_UNITS];
#define PI PCD.pi
#define PI PCD.pi
static
char
pcd_scratch
[
64
];
static
char
pcd_scratch
[
64
];
static
char
pcd_buffer
[
2048
];
/* raw block buffer */
static
char
pcd_buffer
[
2048
];
/* raw block buffer */
static
int
pcd_bufblk
=
-
1
;
/* block in buffer, in CD units,
static
int
pcd_bufblk
=
-
1
;
/* block in buffer, in CD units,
-1 for nothing there. See also
-1 for nothing there. See also
pd_unit.
pd_unit.
*/
*/
/* the variables below are used mainly in the I/O request engine, which
/* the variables below are used mainly in the I/O request engine, which
processes only one request at a time.
processes only one request at a time.
*/
*/
static
int
pcd_unit
=
-
1
;
/* unit of current request & bufblk */
static
int
pcd_unit
=
-
1
;
/* unit of current request & bufblk */
static
int
pcd_retries
;
/* retries on current request */
static
int
pcd_retries
;
/* retries on current request */
static
int
pcd_busy
=
0
;
/* request being processed ? */
static
int
pcd_busy
=
0
;
/* request being processed ? */
static
int
pcd_sector
;
/* address of next requested sector */
static
int
pcd_sector
;
/* address of next requested sector */
static
int
pcd_count
;
/* number of blocks still to do */
static
int
pcd_count
;
/* number of blocks still to do */
static
char
*
pcd_buf
;
/* buffer for request in progress */
static
char
*
pcd_buf
;
/* buffer for request in progress */
static
int
pcd_warned
=
0
;
/* Have we logged a phase warning ? */
static
int
pcd_warned
=
0
;
/* Have we logged a phase warning ? */
/* kernel glue structures */
/* kernel glue structures */
static
struct
block_device_operations
pcd_bdops
=
{
static
struct
block_device_operations
pcd_bdops
=
{
owner:
THIS_MODULE
,
.
owner
=
THIS_MODULE
,
open:
cdrom_open
,
.
open
=
cdrom_open
,
release:
cdrom_release
,
.
release
=
cdrom_release
,
ioctl:
cdrom_ioctl
,
.
ioctl
=
cdrom_ioctl
,
check_media_change:
cdrom_media_changed
,
.
check_media_change
=
cdrom_media_changed
,
};
};
static
struct
cdrom_device_ops
pcd_dops
=
{
static
struct
cdrom_device_ops
pcd_dops
=
{
pcd_open
,
.
open
=
pcd_open
,
pcd_release
,
.
release
=
pcd_release
,
pcd_drive_status
,
.
drive_status
=
pcd_drive_status
,
pcd_media_changed
,
.
media_changed
=
pcd_media_changed
,
pcd_tray_move
,
.
tray_move
=
pcd_tray_move
,
pcd_lock_door
,
.
lock_door
=
pcd_lock_door
,
0
,
/* select speed */
.
get_mcn
=
pcd_get_mcn
,
0
,
/* select disk */
.
reset
=
pcd_drive_reset
,
0
,
/* get last session */
.
audio_ioctl
=
pcd_audio_ioctl
,
pcd_get_mcn
,
.
generic_packet
=
pcd_packet
,
pcd_drive_reset
,
.
capability
=
CDC_CLOSE_TRAY
|
CDC_OPEN_TRAY
|
CDC_LOCK
|
pcd_audio_ioctl
,
CDC_MCN
|
CDC_MEDIA_CHANGED
|
CDC_RESET
|
0
,
/* dev_ioctl */
CDC_PLAY_AUDIO
|
CDC_GENERIC_PACKET
|
CDC_CD_R
|
CDC_CLOSE_TRAY
|
CDC_CD_RW
,
CDC_OPEN_TRAY
|
CDC_LOCK
|
CDC_MCN
|
CDC_MEDIA_CHANGED
|
CDC_RESET
|
CDC_PLAY_AUDIO
|
CDC_GENERIC_PACKET
|
CDC_CD_R
|
CDC_CD_RW
,
0
,
pcd_packet
,
};
};
static
void
pcd_init_units
(
void
)
static
void
pcd_init_units
(
void
)
{
{
int
unit
,
j
;
int
unit
,
j
;
pcd_drive_count
=
0
;
pcd_drive_count
=
0
;
for
(
unit
=
0
;
unit
<
PCD_UNITS
;
unit
++
)
{
for
(
unit
=
0
;
unit
<
PCD_UNITS
;
unit
++
)
{
PCD
.
pi
=
&
PCD
.
pia
;
PCD
.
pi
=
&
PCD
.
pia
;
PCD
.
present
=
0
;
PCD
.
present
=
0
;
PCD
.
last_sense
=
0
;
PCD
.
last_sense
=
0
;
PCD
.
changed
=
1
;
PCD
.
changed
=
1
;
PCD
.
drive
=
DU
[
D_SLV
];
PCD
.
drive
=
DU
[
D_SLV
];
if
(
DU
[
D_PRT
])
pcd_drive_count
++
;
if
(
DU
[
D_PRT
])
pcd_drive_count
++
;
j
=
0
;
while
((
j
<
(
sizeof
(
PCD
.
info
.
name
)
-
2
))
&&
j
=
0
;
(
PCD
.
info
.
name
[
j
]
=
name
[
j
]))
j
++
;
while
((
j
<
(
sizeof
(
PCD
.
info
.
name
)
-
2
))
&&
PCD
.
info
.
name
[
j
++
]
=
'0'
+
unit
;
(
PCD
.
info
.
name
[
j
]
=
name
[
j
]))
PCD
.
info
.
name
[
j
]
=
0
;
j
++
;
PCD
.
info
.
name
[
j
++
]
=
'0'
+
unit
;
PCD
.
info
.
name
[
j
]
=
0
;
PCD
.
name
=
&
PCD
.
info
.
name
[
0
];
PCD
.
name
=
&
PCD
.
info
.
name
[
0
];
PCD
.
info
.
ops
=
&
pcd_dops
;
PCD
.
info
.
ops
=
&
pcd_dops
;
PCD
.
info
.
handle
=
NULL
;
PCD
.
info
.
handle
=
NULL
;
PCD
.
info
.
dev
=
mk_kdev
(
major
,
unit
);
PCD
.
info
.
dev
=
mk_kdev
(
major
,
unit
);
PCD
.
info
.
speed
=
0
;
PCD
.
info
.
speed
=
0
;
PCD
.
info
.
capacity
=
1
;
PCD
.
info
.
capacity
=
1
;
PCD
.
info
.
mask
=
0
;
PCD
.
info
.
mask
=
0
;
}
}
}
}
static
int
pcd_open
(
struct
cdrom_device_info
*
cdi
,
int
purpose
)
static
int
pcd_open
(
struct
cdrom_device_info
*
cdi
,
int
purpose
)
{
{
int
unit
=
DEVICE_NR
(
cdi
->
dev
);
int
unit
=
DEVICE_NR
(
cdi
->
dev
);
if
((
unit
>=
PCD_UNITS
)
||
(
!
PCD
.
present
))
if
((
unit
>=
PCD_UNITS
)
||
(
!
PCD
.
present
))
return
-
ENODEV
;
return
-
ENODEV
;
return
0
;
return
0
;
}
}
...
@@ -352,298 +346,331 @@ static inline void write_reg(int unit, int reg, int val)
...
@@ -352,298 +346,331 @@ static inline void write_reg(int unit, int reg, int val)
pi_write_regr
(
PI
,
0
,
reg
,
val
);
pi_write_regr
(
PI
,
0
,
reg
,
val
);
}
}
static
int
pcd_wait
(
int
unit
,
int
go
,
int
stop
,
char
*
fun
,
char
*
msg
)
static
int
pcd_wait
(
int
unit
,
int
go
,
int
stop
,
char
*
fun
,
char
*
msg
)
{
{
int
j
,
r
,
e
,
s
,
p
;
int
j
,
r
,
e
,
s
,
p
;
j
=
0
;
j
=
0
;
while
((((
r
=
status_reg
(
unit
))
&
go
)
||
(
stop
&&
(
!
(
r
&
stop
))))
&&
(
j
++<
PCD_SPIN
))
while
((((
r
=
status_reg
(
unit
))
&
go
)
||
(
stop
&&
(
!
(
r
&
stop
))))
&&
(
j
++
<
PCD_SPIN
))
udelay
(
PCD_DELAY
);
udelay
(
PCD_DELAY
);
if
((
r
&
(
IDE_ERR
&
stop
))
||
(
j
>=
PCD_SPIN
))
{
if
((
r
&
(
IDE_ERR
&
stop
))
||
(
j
>=
PCD_SPIN
))
{
s
=
read_reg
(
unit
,
7
);
s
=
read_reg
(
unit
,
7
);
e
=
read_reg
(
unit
,
1
);
e
=
read_reg
(
unit
,
1
);
p
=
read_reg
(
unit
,
2
);
p
=
read_reg
(
unit
,
2
);
if
(
j
>=
PCD_SPIN
)
e
|=
0x100
;
if
(
j
>=
PCD_SPIN
)
if
(
fun
)
printk
(
"%s: %s %s: alt=0x%x stat=0x%x err=0x%x"
e
|=
0x100
;
" loop=%d phase=%d
\n
"
,
if
(
fun
)
PCD
.
name
,
fun
,
msg
,
r
,
s
,
e
,
j
,
p
);
printk
(
"%s: %s %s: alt=0x%x stat=0x%x err=0x%x"
return
(
s
<<
8
)
+
r
;
" loop=%d phase=%d
\n
"
,
PCD
.
name
,
fun
,
msg
,
r
,
s
,
e
,
j
,
p
);
return
(
s
<<
8
)
+
r
;
}
}
return
0
;
return
0
;
}
}
static
int
pcd_command
(
int
unit
,
char
*
cmd
,
int
dlen
,
char
*
fun
)
static
int
pcd_command
(
int
unit
,
char
*
cmd
,
int
dlen
,
char
*
fun
)
{
{
pi_connect
(
PI
);
pi_connect
(
PI
);
write_reg
(
unit
,
6
,
0xa0
+
0x10
*
PCD
.
drive
);
write_reg
(
unit
,
6
,
0xa0
+
0x10
*
PCD
.
drive
);
if
(
pcd_wait
(
unit
,
IDE_BUSY
|
IDE_DRQ
,
0
,
fun
,
"before command"
))
{
if
(
pcd_wait
(
unit
,
IDE_BUSY
|
IDE_DRQ
,
0
,
fun
,
"before command"
))
{
pi_disconnect
(
PI
);
pi_disconnect
(
PI
);
return
-
1
;
return
-
1
;
}
}
write_reg
(
unit
,
4
,
dlen
%
256
);
write_reg
(
unit
,
4
,
dlen
%
256
);
write_reg
(
unit
,
5
,
dlen
/
256
);
write_reg
(
unit
,
5
,
dlen
/
256
);
write_reg
(
unit
,
7
,
0xa0
);
/* ATAPI packet command */
write_reg
(
unit
,
7
,
0xa0
);
/* ATAPI packet command */
if
(
pcd_wait
(
unit
,
IDE_BUSY
,
IDE_DRQ
,
fun
,
"command DRQ"
))
{
if
(
pcd_wait
(
unit
,
IDE_BUSY
,
IDE_DRQ
,
fun
,
"command DRQ"
))
{
pi_disconnect
(
PI
);
pi_disconnect
(
PI
);
return
-
1
;
return
-
1
;
}
}
if
(
read_reg
(
unit
,
2
)
!=
1
)
{
if
(
read_reg
(
unit
,
2
)
!=
1
)
{
printk
(
"%s: %s: command phase error
\n
"
,
PCD
.
name
,
fun
);
printk
(
"%s: %s: command phase error
\n
"
,
PCD
.
name
,
fun
);
pi_disconnect
(
PI
);
pi_disconnect
(
PI
);
return
-
1
;
return
-
1
;
}
}
pi_write_block
(
PI
,
cmd
,
12
);
pi_write_block
(
PI
,
cmd
,
12
);
return
0
;
return
0
;
}
}
static
int
pcd_completion
(
int
unit
,
char
*
buf
,
char
*
fun
)
static
int
pcd_completion
(
int
unit
,
char
*
buf
,
char
*
fun
)
{
{
int
r
,
d
,
p
,
n
,
k
,
j
;
int
r
,
d
,
p
,
n
,
k
,
j
;
r
=
-
1
;
k
=
0
;
j
=
0
;
r
=
-
1
;
k
=
0
;
if
(
!
pcd_wait
(
unit
,
IDE_BUSY
,
IDE_DRQ
|
IDE_READY
|
IDE_ERR
,
j
=
0
;
fun
,
"completion"
))
{
r
=
0
;
if
(
!
pcd_wait
(
unit
,
IDE_BUSY
,
IDE_DRQ
|
IDE_READY
|
IDE_ERR
,
while
(
read_reg
(
unit
,
7
)
&
IDE_DRQ
)
{
fun
,
"completion"
))
{
d
=
(
read_reg
(
unit
,
4
)
+
256
*
read_reg
(
unit
,
5
));
r
=
0
;
n
=
((
d
+
3
)
&
0xfffc
);
while
(
read_reg
(
unit
,
7
)
&
IDE_DRQ
)
{
p
=
read_reg
(
unit
,
2
)
&
3
;
d
=
(
read_reg
(
unit
,
4
)
+
256
*
read_reg
(
unit
,
5
));
n
=
((
d
+
3
)
&
0xfffc
);
if
((
p
==
2
)
&&
(
n
>
0
)
&&
(
j
==
0
))
{
p
=
read_reg
(
unit
,
2
)
&
3
;
pi_read_block
(
PI
,
buf
,
n
);
if
(
verbose
>
1
)
if
((
p
==
2
)
&&
(
n
>
0
)
&&
(
j
==
0
))
{
printk
(
"%s: %s: Read %d bytes
\n
"
,
PCD
.
name
,
fun
,
n
);
pi_read_block
(
PI
,
buf
,
n
);
r
=
0
;
j
++
;
if
(
verbose
>
1
)
}
else
{
printk
(
"%s: %s: Read %d bytes
\n
"
,
if
(
verbose
>
1
)
PCD
.
name
,
fun
,
n
);
printk
(
"%s: %s: Unexpected phase %d, d=%d, k=%d
\n
"
,
r
=
0
;
PCD
.
name
,
fun
,
p
,
d
,
k
);
j
++
;
if
((
verbose
<
2
)
&&
!
pcd_warned
)
{
}
else
{
pcd_warned
=
1
;
if
(
verbose
>
1
)
printk
(
"%s: WARNING: ATAPI phase errors
\n
"
,
PCD
.
name
);
printk
(
"%s: %s: Unexpected phase %d, d=%d, k=%d
\n
"
,
PCD
.
name
,
fun
,
p
,
d
,
k
);
if
((
verbose
<
2
)
&&
!
pcd_warned
)
{
pcd_warned
=
1
;
printk
(
"%s: WARNING: ATAPI phase errors
\n
"
,
PCD
.
name
);
}
mdelay
(
1
);
}
if
(
k
++
>
PCD_TMO
)
{
printk
(
"%s: Stuck DRQ
\n
"
,
PCD
.
name
);
break
;
}
if
(
pcd_wait
(
unit
,
IDE_BUSY
,
IDE_DRQ
|
IDE_READY
|
IDE_ERR
,
fun
,
"completion"
))
{
r
=
-
1
;
break
;
}
}
mdelay
(
1
);
}
if
(
k
++
>
PCD_TMO
)
{
printk
(
"%s: Stuck DRQ
\n
"
,
PCD
.
name
);
break
;
}
if
(
pcd_wait
(
unit
,
IDE_BUSY
,
IDE_DRQ
|
IDE_READY
|
IDE_ERR
,
fun
,
"completion"
))
{
r
=
-
1
;
break
;
}
}
}
}
}
pi_disconnect
(
PI
);
pi_disconnect
(
PI
);
return
r
;
return
r
;
}
}
static
void
pcd_req_sense
(
int
unit
,
char
*
fun
)
static
void
pcd_req_sense
(
int
unit
,
char
*
fun
)
{
{
char
rs_cmd
[
12
]
=
{
0x03
,
0
,
0
,
0
,
16
,
0
,
0
,
0
,
0
,
0
,
0
,
0
};
char
rs_cmd
[
12
]
=
{
0x03
,
0
,
0
,
0
,
16
,
0
,
0
,
0
,
0
,
0
,
0
,
0
};
char
buf
[
16
];
char
buf
[
16
];
int
r
,
c
;
int
r
,
c
;
r
=
pcd_command
(
unit
,
rs_cmd
,
16
,
"Request sense"
);
r
=
pcd_command
(
unit
,
rs_cmd
,
16
,
"Request sense"
);
mdelay
(
1
);
mdelay
(
1
);
if
(
!
r
)
pcd_completion
(
unit
,
buf
,
"Request sense"
);
if
(
!
r
)
pcd_completion
(
unit
,
buf
,
"Request sense"
);
PCD
.
last_sense
=
-
1
;
c
=
2
;
PCD
.
last_sense
=
-
1
;
c
=
2
;
if
(
!
r
)
{
if
(
!
r
)
{
if
(
fun
)
printk
(
"%s: %s: Sense key: %x, ASC: %x, ASQ: %x
\n
"
,
if
(
fun
)
PCD
.
name
,
fun
,
buf
[
2
]
&
0xf
,
buf
[
12
],
buf
[
13
]);
printk
(
"%s: %s: Sense key: %x, ASC: %x, ASQ: %x
\n
"
,
c
=
buf
[
2
]
&
0xf
;
PCD
.
name
,
fun
,
buf
[
2
]
&
0xf
,
buf
[
12
],
buf
[
13
]);
PCD
.
last_sense
=
c
|
((
buf
[
12
]
&
0xff
)
<<
8
)
|
((
buf
[
13
]
&
0xff
)
<<
16
);
c
=
buf
[
2
]
&
0xf
;
}
PCD
.
last_sense
=
if
((
c
==
2
)
||
(
c
==
6
))
PCD
.
changed
=
1
;
c
|
((
buf
[
12
]
&
0xff
)
<<
8
)
|
((
buf
[
13
]
&
0xff
)
<<
16
);
}
if
((
c
==
2
)
||
(
c
==
6
))
PCD
.
changed
=
1
;
}
}
static
int
pcd_atapi
(
int
unit
,
char
*
cmd
,
int
dlen
,
char
*
buf
,
char
*
fun
)
static
int
pcd_atapi
(
int
unit
,
char
*
cmd
,
int
dlen
,
char
*
buf
,
char
*
fun
)
{
{
int
r
;
int
r
;
r
=
pcd_command
(
unit
,
cmd
,
dlen
,
fun
);
r
=
pcd_command
(
unit
,
cmd
,
dlen
,
fun
);
mdelay
(
1
);
mdelay
(
1
);
if
(
!
r
)
r
=
pcd_completion
(
unit
,
buf
,
fun
);
if
(
!
r
)
if
(
r
)
pcd_req_sense
(
unit
,
fun
);
r
=
pcd_completion
(
unit
,
buf
,
fun
);
if
(
r
)
pcd_req_sense
(
unit
,
fun
);
return
r
;
return
r
;
}
}
static
int
pcd_packet
(
struct
cdrom_device_info
*
cdi
,
static
int
pcd_packet
(
struct
cdrom_device_info
*
cdi
,
struct
cdrom_generic_command
*
cgc
)
struct
cdrom_generic_command
*
cgc
)
{
{
char
*
un_cmd
;
char
*
un_cmd
;
int
unit
=
DEVICE_NR
(
cdi
->
dev
);
int
unit
=
DEVICE_NR
(
cdi
->
dev
);
un_cmd
=
cgc
->
cmd
;
un_cmd
=
cgc
->
cmd
;
return
pcd_atapi
(
unit
,
un_cmd
,
cgc
->
buflen
,
cgc
->
buffer
,
"generic packet"
);
return
pcd_atapi
(
unit
,
un_cmd
,
cgc
->
buflen
,
cgc
->
buffer
,
"generic packet"
);
}
}
#define DBMSG(msg) ((verbose>1)?(msg):NULL)
#define DBMSG(msg) ((verbose>1)?(msg):NULL)
static
int
pcd_media_changed
(
struct
cdrom_device_info
*
cdi
,
int
slot_nr
)
static
int
pcd_media_changed
(
struct
cdrom_device_info
*
cdi
,
int
slot_nr
)
{
{
int
r
;
int
r
;
int
unit
=
DEVICE_NR
(
cdi
->
dev
);
int
unit
=
DEVICE_NR
(
cdi
->
dev
);
r
=
PCD
.
changed
;
r
=
PCD
.
changed
;
PCD
.
changed
=
0
;
PCD
.
changed
=
0
;
return
r
;
return
r
;
}
}
static
int
pcd_lock_door
(
struct
cdrom_device_info
*
cdi
,
int
lock
)
static
int
pcd_lock_door
(
struct
cdrom_device_info
*
cdi
,
int
lock
)
{
char
un_cmd
[
12
]
=
{
0x1e
,
0
,
0
,
0
,
lock
,
0
,
0
,
0
,
0
,
0
,
0
,
0
};
int
unit
=
DEVICE_NR
(
cdi
->
dev
);
{
char
un_cmd
[
12
]
=
{
0x1e
,
0
,
0
,
0
,
lock
,
0
,
0
,
0
,
0
,
0
,
0
,
0
};
return
pcd_atapi
(
unit
,
un_cmd
,
0
,
pcd_scratch
,
int
unit
=
DEVICE_NR
(
cdi
->
dev
);
lock
?
"lock door"
:
"unlock door"
);
return
pcd_atapi
(
unit
,
un_cmd
,
0
,
pcd_scratch
,
lock
?
"lock door"
:
"unlock door"
);
}
}
static
int
pcd_tray_move
(
struct
cdrom_device_info
*
cdi
,
int
position
)
static
int
pcd_tray_move
(
struct
cdrom_device_info
*
cdi
,
int
position
)
{
char
ej_cmd
[
12
]
=
{
0x1b
,
0
,
0
,
0
,
3
-
position
,
0
,
0
,
0
,
0
,
0
,
0
,
0
};
int
unit
=
DEVICE_NR
(
cdi
->
dev
);
{
char
ej_cmd
[
12
]
=
{
0x1b
,
0
,
0
,
0
,
3
-
position
,
0
,
0
,
0
,
0
,
0
,
0
,
0
};
return
pcd_atapi
(
unit
,
ej_cmd
,
0
,
pcd_scratch
,
int
unit
=
DEVICE_NR
(
cdi
->
dev
);
position
?
"eject"
:
"close tray"
);
return
pcd_atapi
(
unit
,
ej_cmd
,
0
,
pcd_scratch
,
position
?
"eject"
:
"close tray"
);
}
}
static
void
pcd_sleep
(
int
cs
)
static
void
pcd_sleep
(
int
cs
)
{
{
current
->
state
=
TASK_INTERRUPTIBLE
;
current
->
state
=
TASK_INTERRUPTIBLE
;
schedule_timeout
(
cs
);
schedule_timeout
(
cs
);
}
}
static
int
pcd_reset
(
int
unit
)
static
int
pcd_reset
(
int
unit
)
{
{
int
i
,
k
,
flg
;
int
i
,
k
,
flg
;
int
expect
[
5
]
=
{
1
,
1
,
1
,
0x14
,
0xeb
};
int
expect
[
5
]
=
{
1
,
1
,
1
,
0x14
,
0xeb
};
pi_connect
(
PI
);
pi_connect
(
PI
);
write_reg
(
unit
,
6
,
0xa0
+
0x10
*
PCD
.
drive
);
write_reg
(
unit
,
6
,
0xa0
+
0x10
*
PCD
.
drive
);
write_reg
(
unit
,
7
,
8
);
write_reg
(
unit
,
7
,
8
);
pcd_sleep
(
20
*
HZ
/
1000
);
/* delay a bit */
pcd_sleep
(
20
*
HZ
/
1000
);
/* delay a bit */
k
=
0
;
k
=
0
;
while
((
k
++
<
PCD_RESET_TMO
)
&&
(
status_reg
(
unit
)
&
IDE_BUSY
))
while
((
k
++
<
PCD_RESET_TMO
)
&&
(
status_reg
(
unit
)
&
IDE_BUSY
))
pcd_sleep
(
HZ
/
10
);
pcd_sleep
(
HZ
/
10
);
flg
=
1
;
flg
=
1
;
for
(
i
=
0
;
i
<
5
;
i
++
)
flg
&=
(
read_reg
(
unit
,
i
+
1
)
==
expect
[
i
]);
for
(
i
=
0
;
i
<
5
;
i
++
)
flg
&=
(
read_reg
(
unit
,
i
+
1
)
==
expect
[
i
]);
if
(
verbose
)
{
if
(
verbose
)
{
printk
(
"%s: Reset (%d) signature = "
,
PCD
.
name
,
k
);
printk
(
"%s: Reset (%d) signature = "
,
PCD
.
name
,
k
);
for
(
i
=
0
;
i
<
5
;
i
++
)
printk
(
"%3x"
,
read_reg
(
unit
,
i
+
1
));
for
(
i
=
0
;
i
<
5
;
i
++
)
if
(
!
flg
)
printk
(
" (incorrect)"
);
printk
(
"%3x"
,
read_reg
(
unit
,
i
+
1
));
if
(
!
flg
)
printk
(
" (incorrect)"
);
printk
(
"
\n
"
);
printk
(
"
\n
"
);
}
}
pi_disconnect
(
PI
);
pi_disconnect
(
PI
);
return
flg
-
1
;
return
flg
-
1
;
}
}
static
int
pcd_drive_reset
(
struct
cdrom_device_info
*
cdi
)
static
int
pcd_drive_reset
(
struct
cdrom_device_info
*
cdi
)
{
{
return
pcd_reset
(
DEVICE_NR
(
cdi
->
dev
));
return
pcd_reset
(
DEVICE_NR
(
cdi
->
dev
));
}
}
static
int
pcd_ready_wait
(
int
unit
,
int
tmo
)
static
int
pcd_ready_wait
(
int
unit
,
int
tmo
)
{
{
char
tr_cmd
[
12
]
=
{
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
};
char
tr_cmd
[
12
]
=
{
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
};
int
k
,
p
;
int
k
,
p
;
k
=
0
;
k
=
0
;
while
(
k
<
tmo
)
{
while
(
k
<
tmo
)
{
PCD
.
last_sense
=
0
;
PCD
.
last_sense
=
0
;
pcd_atapi
(
unit
,
tr_cmd
,
0
,
NULL
,
DBMSG
(
"test unit ready"
));
pcd_atapi
(
unit
,
tr_cmd
,
0
,
NULL
,
DBMSG
(
"test unit ready"
));
p
=
PCD
.
last_sense
;
p
=
PCD
.
last_sense
;
if
(
!
p
)
return
0
;
if
(
!
p
)
if
(
!
(((
p
&
0xffff
)
==
0x0402
)
||
((
p
&
0xff
)
==
6
)))
return
p
;
return
0
;
k
++
;
if
(
!
(((
p
&
0xffff
)
==
0x0402
)
||
((
p
&
0xff
)
==
6
)))
pcd_sleep
(
HZ
);
return
p
;
}
k
++
;
return
0x000020
;
/* timeout */
pcd_sleep
(
HZ
);
}
return
0x000020
;
/* timeout */
}
}
static
int
pcd_drive_status
(
struct
cdrom_device_info
*
cdi
,
int
slot_nr
)
static
int
pcd_drive_status
(
struct
cdrom_device_info
*
cdi
,
int
slot_nr
)
{
char
rc_cmd
[
12
]
=
{
0x25
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
};
int
unit
=
DEVICE_NR
(
cdi
->
dev
);
{
char
rc_cmd
[
12
]
=
{
0x25
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
};
if
(
pcd_ready_wait
(
unit
,
PCD_READY_TMO
))
int
unit
=
DEVICE_NR
(
cdi
->
dev
);
if
(
pcd_ready_wait
(
unit
,
PCD_READY_TMO
))
return
CDS_DRIVE_NOT_READY
;
return
CDS_DRIVE_NOT_READY
;
if
(
pcd_atapi
(
unit
,
rc_cmd
,
8
,
pcd_scratch
,
DBMSG
(
"check media"
)))
if
(
pcd_atapi
(
unit
,
rc_cmd
,
8
,
pcd_scratch
,
DBMSG
(
"check media"
)))
return
CDS_NO_DISC
;
return
CDS_NO_DISC
;
return
CDS_DISC_OK
;
return
CDS_DISC_OK
;
}
}
static
int
pcd_identify
(
int
unit
,
char
*
id
)
static
int
pcd_identify
(
int
unit
,
char
*
id
)
{
{
int
k
,
s
;
int
k
,
s
;
char
id_cmd
[
12
]
=
{
0x12
,
0
,
0
,
0
,
36
,
0
,
0
,
0
,
0
,
0
,
0
,
0
};
char
id_cmd
[
12
]
=
{
0x12
,
0
,
0
,
0
,
36
,
0
,
0
,
0
,
0
,
0
,
0
,
0
};
pcd_bufblk
=
-
1
;
pcd_bufblk
=
-
1
;
s
=
pcd_atapi
(
unit
,
id_cmd
,
36
,
pcd_buffer
,
"identify"
);
s
=
pcd_atapi
(
unit
,
id_cmd
,
36
,
pcd_buffer
,
"identify"
);
if
(
s
)
return
-
1
;
if
(
s
)
return
-
1
;
if
((
pcd_buffer
[
0
]
&
0x1f
)
!=
5
)
{
if
((
pcd_buffer
[
0
]
&
0x1f
)
!=
5
)
{
if
(
verbose
)
printk
(
"%s: %s is not a CD-ROM
\n
"
,
if
(
verbose
)
PCD
.
name
,
PCD
.
drive
?
"Slave"
:
"Master"
);
printk
(
"%s: %s is not a CD-ROM
\n
"
,
return
-
1
;
PCD
.
name
,
PCD
.
drive
?
"Slave"
:
"Master"
);
return
-
1
;
}
for
(
k
=
0
;
k
<
16
;
k
++
)
id
[
k
]
=
pcd_buffer
[
16
+
k
];
id
[
16
]
=
0
;
k
=
16
;
while
((
k
>=
0
)
&&
(
id
[
k
]
<=
0x20
))
{
id
[
k
]
=
0
;
k
--
;
}
}
for
(
k
=
0
;
k
<
16
;
k
++
)
id
[
k
]
=
pcd_buffer
[
16
+
k
];
id
[
16
]
=
0
;
k
=
16
;
while
((
k
>=
0
)
&&
(
id
[
k
]
<=
0x20
))
{
id
[
k
]
=
0
;
k
--
;
}
printk
(
"%s: %s: %s
\n
"
,
PCD
.
name
,
PCD
.
drive
?
"Slave"
:
"Master"
,
id
);
printk
(
"%s: %s: %s
\n
"
,
PCD
.
name
,
PCD
.
drive
?
"Slave"
:
"Master"
,
id
);
return
0
;
return
0
;
}
}
static
int
pcd_probe
(
int
unit
,
int
ms
,
char
*
id
)
/*
* returns 0, with id set if drive is detected
/* returns 0, with id set if drive is detect
ed
* -1, if drive detection fail
ed
-1, if drive detection failed
*/
*/
static
int
pcd_probe
(
int
unit
,
int
ms
,
char
*
id
)
{
{
if
(
ms
==
-
1
)
{
if
(
ms
==
-
1
)
{
for
(
PCD
.
drive
=
0
;
PCD
.
drive
<=
1
;
PCD
.
drive
++
)
for
(
PCD
.
drive
=
0
;
PCD
.
drive
<=
1
;
PCD
.
drive
++
)
if
(
!
pcd_reset
(
unit
)
&&
!
pcd_identify
(
unit
,
id
))
if
(
!
pcd_reset
(
unit
)
&&
!
pcd_identify
(
unit
,
id
))
return
0
;
return
0
;
}
else
{
}
else
{
PCD
.
drive
=
ms
;
PCD
.
drive
=
ms
;
if
(
!
pcd_reset
(
unit
)
&&
!
pcd_identify
(
unit
,
id
))
if
(
!
pcd_reset
(
unit
)
&&
!
pcd_identify
(
unit
,
id
))
return
0
;
return
0
;
}
}
return
-
1
;
return
-
1
;
}
}
static
void
pcd_probe_capabilities
(
void
)
static
void
pcd_probe_capabilities
(
void
)
{
{
int
unit
,
r
;
int
unit
,
r
;
char
buffer
[
32
];
char
buffer
[
32
];
char
cmd
[
12
]
=
{
0x5a
,
1
<<
3
,
0x2a
,
0
,
0
,
0
,
0
,
18
,
0
,
0
,
0
,
0
};
char
cmd
[
12
]
=
{
0x5a
,
1
<<
3
,
0x2a
,
0
,
0
,
0
,
0
,
18
,
0
,
0
,
0
,
0
};
for
(
unit
=
0
;
unit
<
PCD_UNITS
;
unit
++
)
{
for
(
unit
=
0
;
unit
<
PCD_UNITS
;
unit
++
)
{
if
(
!
PCD
.
present
)
continue
;
if
(
!
PCD
.
present
)
r
=
pcd_atapi
(
unit
,
cmd
,
18
,
buffer
,
"mode sense capabilities"
);
continue
;
if
(
r
)
continue
;
r
=
pcd_atapi
(
unit
,
cmd
,
18
,
buffer
,
"mode sense capabilities"
);
if
(
r
)
continue
;
/* we should now have the cap page */
/* we should now have the cap page */
if
((
buffer
[
11
]
&
1
)
==
0
)
if
((
buffer
[
11
]
&
1
)
==
0
)
PCD
.
info
.
mask
|=
CDC_CD_R
;
PCD
.
info
.
mask
|=
CDC_CD_R
;
...
@@ -660,241 +687,259 @@ static void pcd_probe_capabilities( void )
...
@@ -660,241 +687,259 @@ static void pcd_probe_capabilities( void )
}
}
}
}
static
int
pcd_detect
(
void
)
static
int
pcd_detect
(
void
)
{
{
char
id
[
18
];
char
id
[
18
];
int
k
,
unit
;
int
k
,
unit
;
printk
(
"%s: %s version %s, major %d, nice %d
\n
"
,
printk
(
"%s: %s version %s, major %d, nice %d
\n
"
,
name
,
name
,
PCD_VERSION
,
major
,
nice
);
name
,
name
,
PCD_VERSION
,
major
,
nice
);
k
=
0
;
k
=
0
;
if
(
pcd_drive_count
==
0
)
{
/* nothing spec'd - so autoprobe for 1 */
if
(
pcd_drive_count
==
0
)
{
/* nothing spec'd - so autoprobe for 1 */
unit
=
0
;
unit
=
0
;
if
(
pi_init
(
PI
,
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
pcd_buffer
,
if
(
pi_init
(
PI
,
1
,
-
1
,
-
1
,
-
1
,
-
1
,
-
1
,
pcd_buffer
,
PI_PCD
,
verbose
,
PCD
.
name
))
{
PI_PCD
,
verbose
,
PCD
.
name
))
{
if
(
!
pcd_probe
(
unit
,
-
1
,
id
))
{
if
(
!
pcd_probe
(
unit
,
-
1
,
id
))
{
PCD
.
present
=
1
;
PCD
.
present
=
1
;
k
++
;
k
++
;
}
else
pi_release
(
PI
);
}
else
}
pi_release
(
PI
);
}
}
else
for
(
unit
=
0
;
unit
<
PCD_UNITS
;
unit
++
)
if
(
DU
[
D_PRT
])
if
(
pi_init
(
PI
,
0
,
DU
[
D_PRT
],
DU
[
D_MOD
],
DU
[
D_UNI
],
}
else
DU
[
D_PRO
],
DU
[
D_DLY
],
pcd_buffer
,
PI_PCD
,
verbose
,
for
(
unit
=
0
;
unit
<
PCD_UNITS
;
unit
++
)
PCD
.
name
))
{
if
(
DU
[
D_PRT
])
if
(
!
pcd_probe
(
unit
,
DU
[
D_SLV
],
id
))
{
if
(
pi_init
PCD
.
present
=
1
;
(
PI
,
0
,
DU
[
D_PRT
],
DU
[
D_MOD
],
DU
[
D_UNI
],
k
++
;
DU
[
D_PRO
],
DU
[
D_DLY
],
pcd_buffer
,
PI_PCD
,
}
else
pi_release
(
PI
);
verbose
,
PCD
.
name
))
{
}
if
(
!
pcd_probe
(
unit
,
DU
[
D_SLV
],
id
))
{
PCD
.
present
=
1
;
if
(
k
)
return
0
;
k
++
;
}
else
printk
(
"%s: No CD-ROM drive found
\n
"
,
name
);
pi_release
(
PI
);
}
if
(
k
)
return
0
;
printk
(
"%s: No CD-ROM drive found
\n
"
,
name
);
return
-
1
;
return
-
1
;
}
}
/* I/O request processing */
/* I/O request processing */
static
void
do_pcd_request
(
request_queue_t
*
q
)
static
void
do_pcd_request
(
request_queue_t
*
q
)
{
{
int
unit
;
int
unit
;
if
(
pcd_busy
)
return
;
while
(
1
)
{
if
(
blk_queue_empty
(
QUEUE
))
return
;
if
(
rq_data_dir
(
CURRENT
)
==
READ
)
{
if
(
pcd_busy
)
unit
=
minor
(
CURRENT
->
rq_dev
);
if
(
unit
!=
pcd_unit
)
{
pcd_bufblk
=
-
1
;
pcd_unit
=
unit
;
}
pcd_sector
=
CURRENT
->
sector
;
pcd_count
=
CURRENT
->
current_nr_sectors
;
pcd_buf
=
CURRENT
->
buffer
;
pcd_busy
=
1
;
ps_set_intr
(
do_pcd_read
,
0
,
0
,
nice
);
return
;
return
;
}
while
(
1
)
{
else
end_request
(
CURRENT
,
0
);
if
(
blk_queue_empty
(
QUEUE
))
return
;
if
(
rq_data_dir
(
CURRENT
)
==
READ
)
{
unit
=
minor
(
CURRENT
->
rq_dev
);
if
(
unit
!=
pcd_unit
)
{
pcd_bufblk
=
-
1
;
pcd_unit
=
unit
;
}
pcd_sector
=
CURRENT
->
sector
;
pcd_count
=
CURRENT
->
current_nr_sectors
;
pcd_buf
=
CURRENT
->
buffer
;
pcd_busy
=
1
;
ps_set_intr
(
do_pcd_read
,
0
,
0
,
nice
);
return
;
}
else
end_request
(
CURRENT
,
0
);
}
}
}
}
static
int
pcd_ready
(
void
)
static
int
pcd_ready
(
void
)
{
{
int
unit
=
pcd_unit
;
int
unit
=
pcd_unit
;
return
(((
status_reg
(
unit
)
&
(
IDE_BUSY
|
IDE_DRQ
))
==
IDE_DRQ
))
;
return
(((
status_reg
(
unit
)
&
(
IDE_BUSY
|
IDE_DRQ
))
==
IDE_DRQ
))
;
}
}
static
void
pcd_transfer
(
void
)
static
void
pcd_transfer
(
void
)
{
{
int
k
,
o
;
int
k
,
o
;
while
(
pcd_count
&&
(
pcd_sector
/
4
==
pcd_bufblk
))
{
while
(
pcd_count
&&
(
pcd_sector
/
4
==
pcd_bufblk
))
{
o
=
(
pcd_sector
%
4
)
*
512
;
o
=
(
pcd_sector
%
4
)
*
512
;
for
(
k
=
0
;
k
<
512
;
k
++
)
pcd_buf
[
k
]
=
pcd_buffer
[
o
+
k
];
for
(
k
=
0
;
k
<
512
;
k
++
)
pcd_buf
[
k
]
=
pcd_buffer
[
o
+
k
];
pcd_count
--
;
pcd_count
--
;
pcd_buf
+=
512
;
pcd_buf
+=
512
;
pcd_sector
++
;
pcd_sector
++
;
}
}
}
}
static
void
pcd_start
(
void
)
static
void
pcd_start
(
void
)
{
{
int
unit
=
pcd_unit
;
int
unit
=
pcd_unit
;
int
b
,
i
;
int
b
,
i
;
char
rd_cmd
[
12
]
=
{
0xa8
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
1
,
0
,
0
};
char
rd_cmd
[
12
]
=
{
0xa8
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
1
,
0
,
0
};
long
saved_flags
;
long
saved_flags
;
pcd_bufblk
=
pcd_sector
/
4
;
pcd_bufblk
=
pcd_sector
/
4
;
b
=
pcd_bufblk
;
b
=
pcd_bufblk
;
for
(
i
=
0
;
i
<
4
;
i
++
)
{
for
(
i
=
0
;
i
<
4
;
i
++
)
{
rd_cmd
[
5
-
i
]
=
b
&
0xff
;
rd_cmd
[
5
-
i
]
=
b
&
0xff
;
b
=
b
>>
8
;
b
=
b
>>
8
;
}
}
if
(
pcd_command
(
unit
,
rd_cmd
,
2048
,
"read block"
))
{
if
(
pcd_command
(
unit
,
rd_cmd
,
2048
,
"read block"
))
{
pcd_bufblk
=
-
1
;
pcd_bufblk
=
-
1
;
spin_lock_irqsave
(
&
pcd_lock
,
saved_flags
);
spin_lock_irqsave
(
&
pcd_lock
,
saved_flags
);
pcd_busy
=
0
;
pcd_busy
=
0
;
end_request
(
CURRENT
,
0
);
end_request
(
CURRENT
,
0
);
do_pcd_request
(
NULL
);
do_pcd_request
(
NULL
);
spin_unlock_irqrestore
(
&
pcd_lock
,
saved_flags
);
spin_unlock_irqrestore
(
&
pcd_lock
,
saved_flags
);
return
;
return
;
}
}
mdelay
(
1
);
mdelay
(
1
);
ps_set_intr
(
do_pcd_read_drq
,
pcd_ready
,
PCD_TMO
,
nice
);
ps_set_intr
(
do_pcd_read_drq
,
pcd_ready
,
PCD_TMO
,
nice
);
}
}
static
void
do_pcd_read
(
void
)
static
void
do_pcd_read
(
void
)
{
int
unit
=
pcd_unit
;
{
int
unit
=
pcd_unit
;
long
saved_flags
;
long
saved_flags
;
pcd_busy
=
1
;
pcd_busy
=
1
;
pcd_retries
=
0
;
pcd_retries
=
0
;
pcd_transfer
();
pcd_transfer
();
if
(
!
pcd_count
)
{
if
(
!
pcd_count
)
{
spin_lock_irqsave
(
&
pcd_lock
,
saved_flags
);
spin_lock_irqsave
(
&
pcd_lock
,
saved_flags
);
end_request
(
CURRENT
,
1
);
end_request
(
CURRENT
,
1
);
pcd_busy
=
0
;
pcd_busy
=
0
;
do_pcd_request
(
NULL
);
do_pcd_request
(
NULL
);
spin_unlock_irqrestore
(
&
pcd_lock
,
saved_flags
);
spin_unlock_irqrestore
(
&
pcd_lock
,
saved_flags
);
return
;
return
;
}
}
pi_do_claimed
(
PI
,
pcd_start
);
pi_do_claimed
(
PI
,
pcd_start
);
}
}
static
void
do_pcd_read_drq
(
void
)
static
void
do_pcd_read_drq
(
void
)
{
{
int
unit
=
pcd_unit
;
int
unit
=
pcd_unit
;
long
saved_flags
;
long
saved_flags
;
if
(
pcd_completion
(
unit
,
pcd_buffer
,
"read block"
))
{
if
(
pcd_completion
(
unit
,
pcd_buffer
,
"read block"
))
{
if
(
pcd_retries
<
PCD_RETRIES
)
{
if
(
pcd_retries
<
PCD_RETRIES
)
{
mdelay
(
1
);
mdelay
(
1
);
pcd_retries
++
;
pcd_retries
++
;
pi_do_claimed
(
PI
,
pcd_start
);
pi_do_claimed
(
PI
,
pcd_start
);
return
;
return
;
}
}
spin_lock_irqsave
(
&
pcd_lock
,
saved_flags
);
spin_lock_irqsave
(
&
pcd_lock
,
saved_flags
);
pcd_busy
=
0
;
pcd_busy
=
0
;
pcd_bufblk
=
-
1
;
pcd_bufblk
=
-
1
;
end_request
(
CURRENT
,
0
);
end_request
(
CURRENT
,
0
);
do_pcd_request
(
NULL
);
do_pcd_request
(
NULL
);
spin_unlock_irqrestore
(
&
pcd_lock
,
saved_flags
);
spin_unlock_irqrestore
(
&
pcd_lock
,
saved_flags
);
return
;
return
;
}
}
do_pcd_read
();
do_pcd_read
();
spin_lock_irqsave
(
&
pcd_lock
,
saved_flags
);
spin_lock_irqsave
(
&
pcd_lock
,
saved_flags
);
do_pcd_request
(
NULL
);
do_pcd_request
(
NULL
);
spin_unlock_irqrestore
(
&
pcd_lock
,
saved_flags
);
spin_unlock_irqrestore
(
&
pcd_lock
,
saved_flags
);
}
}
/* the audio_ioctl stuff is adapted from sr_ioctl.c */
/* the audio_ioctl stuff is adapted from sr_ioctl.c */
static
int
pcd_audio_ioctl
(
struct
cdrom_device_info
*
cdi
,
static
int
pcd_audio_ioctl
(
struct
cdrom_device_info
*
cdi
,
unsigned
int
cmd
,
void
*
arg
)
unsigned
int
cmd
,
void
*
arg
)
{
int
unit
=
DEVICE_NR
(
cdi
->
dev
);
{
int
unit
=
DEVICE_NR
(
cdi
->
dev
);
switch
(
cmd
)
{
switch
(
cmd
)
{
case
CDROMREADTOCHDR
:
case
CDROMREADTOCHDR
:
{
char
cmd
[
12
]
=
{
char
cmd
[
12
]
=
{
GPCMD_READ_TOC_PMA_ATIP
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
12
,
0
,
0
,
0
};
{
GPCMD_READ_TOC_PMA_ATIP
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
12
,
struct
cdrom_tochdr
*
tochdr
=
(
struct
cdrom_tochdr
*
)
arg
;
0
,
0
,
0
};
char
buffer
[
32
];
struct
cdrom_tochdr
*
tochdr
=
int
r
;
(
struct
cdrom_tochdr
*
)
arg
;
char
buffer
[
32
];
r
=
pcd_atapi
(
unit
,
cmd
,
12
,
buffer
,
"read toc header"
);
int
r
;
tochdr
->
cdth_trk0
=
buffer
[
2
];
r
=
pcd_atapi
(
unit
,
cmd
,
12
,
buffer
,
"read toc header"
);
tochdr
->
cdth_trk1
=
buffer
[
3
];
tochdr
->
cdth_trk0
=
buffer
[
2
];
return
r
*
EIO
;
tochdr
->
cdth_trk1
=
buffer
[
3
];
}
return
r
*
EIO
;
case
CDROMREADTOCENTRY
:
}
{
char
cmd
[
12
]
=
{
GPCMD_READ_TOC_PMA_ATIP
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
12
,
0
,
0
,
0
};
case
CDROMREADTOCENTRY
:
struct
cdrom_tocentry
*
tocentry
=
(
struct
cdrom_tocentry
*
)
arg
;
{
unsigned
char
buffer
[
32
];
char
cmd
[
12
]
=
int
r
;
{
GPCMD_READ_TOC_PMA_ATIP
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
12
,
0
,
0
,
0
};
cmd
[
1
]
=
(
tocentry
->
cdte_format
==
CDROM_MSF
?
0x02
:
0
);
cmd
[
6
]
=
tocentry
->
cdte_track
;
struct
cdrom_tocentry
*
tocentry
=
(
struct
cdrom_tocentry
*
)
arg
;
r
=
pcd_atapi
(
unit
,
cmd
,
12
,
buffer
,
"read toc entry"
);
unsigned
char
buffer
[
32
];
int
r
;
tocentry
->
cdte_ctrl
=
buffer
[
5
]
&
0xf
;
tocentry
->
cdte_adr
=
buffer
[
5
]
>>
4
;
cmd
[
1
]
=
tocentry
->
cdte_datamode
=
(
tocentry
->
cdte_ctrl
&
0x04
)
?
1
:
0
;
(
tocentry
->
cdte_format
==
CDROM_MSF
?
0x02
:
0
);
if
(
tocentry
->
cdte_format
==
CDROM_MSF
)
{
cmd
[
6
]
=
tocentry
->
cdte_track
;
tocentry
->
cdte_addr
.
msf
.
minute
=
buffer
[
9
];
tocentry
->
cdte_addr
.
msf
.
second
=
buffer
[
10
];
r
=
pcd_atapi
(
unit
,
cmd
,
12
,
buffer
,
"read toc entry"
);
tocentry
->
cdte_addr
.
msf
.
frame
=
buffer
[
11
];
}
else
tocentry
->
cdte_ctrl
=
buffer
[
5
]
&
0xf
;
tocentry
->
cdte_addr
.
lba
=
tocentry
->
cdte_adr
=
buffer
[
5
]
>>
4
;
(((((
buffer
[
8
]
<<
8
)
+
buffer
[
9
])
<<
8
)
tocentry
->
cdte_datamode
=
+
buffer
[
10
])
<<
8
)
+
buffer
[
11
];
(
tocentry
->
cdte_ctrl
&
0x04
)
?
1
:
0
;
if
(
tocentry
->
cdte_format
==
CDROM_MSF
)
{
return
r
*
EIO
;
tocentry
->
cdte_addr
.
msf
.
minute
=
buffer
[
9
];
}
tocentry
->
cdte_addr
.
msf
.
second
=
buffer
[
10
];
tocentry
->
cdte_addr
.
msf
.
frame
=
buffer
[
11
];
default:
}
else
tocentry
->
cdte_addr
.
lba
=
return
-
ENOSYS
;
(((((
buffer
[
8
]
<<
8
)
+
buffer
[
9
])
<<
8
)
}
+
buffer
[
10
])
<<
8
)
+
buffer
[
11
];
}
return
r
*
EIO
;
static
int
pcd_get_mcn
(
struct
cdrom_device_info
*
cdi
,
struct
cdrom_mcn
*
mcn
)
}
{
char
cmd
[
12
]
=
{
GPCMD_READ_SUBCHANNEL
,
0
,
0x40
,
2
,
0
,
0
,
0
,
0
,
24
,
0
,
0
,
0
};
default:
char
buffer
[
32
];
int
k
;
return
-
ENOSYS
;
int
unit
=
DEVICE_NR
(
cdi
->
dev
);
}
}
if
(
pcd_atapi
(
unit
,
cmd
,
24
,
buffer
,
"get mcn"
))
return
-
EIO
;
static
int
pcd_get_mcn
(
struct
cdrom_device_info
*
cdi
,
struct
cdrom_mcn
*
mcn
)
for
(
k
=
0
;
k
<
13
;
k
++
)
mcn
->
medium_catalog_number
[
k
]
=
buffer
[
k
+
9
];
{
char
cmd
[
12
]
=
{
GPCMD_READ_SUBCHANNEL
,
0
,
0x40
,
2
,
0
,
0
,
0
,
0
,
24
,
0
,
0
,
0
};
char
buffer
[
32
];
int
k
;
int
unit
=
DEVICE_NR
(
cdi
->
dev
);
if
(
pcd_atapi
(
unit
,
cmd
,
24
,
buffer
,
"get mcn"
))
return
-
EIO
;
for
(
k
=
0
;
k
<
13
;
k
++
)
mcn
->
medium_catalog_number
[
k
]
=
buffer
[
k
+
9
];
mcn
->
medium_catalog_number
[
13
]
=
0
;
mcn
->
medium_catalog_number
[
13
]
=
0
;
return
0
;
return
0
;
}
}
static
int
__init
pcd_init
(
void
)
static
int
__init
pcd_init
(
void
)
{
{
int
unit
;
int
unit
;
...
@@ -910,12 +955,12 @@ static int __init pcd_init(void)
...
@@ -910,12 +955,12 @@ static int __init pcd_init(void)
/* get the atapi capabilities page */
/* get the atapi capabilities page */
pcd_probe_capabilities
();
pcd_probe_capabilities
();
if
(
register_blkdev
(
MAJOR_NR
,
name
,
&
pcd_bdops
))
{
if
(
register_blkdev
(
MAJOR_NR
,
name
,
&
pcd_bdops
))
{
printk
(
"pcd: unable to get major number %d
\n
"
,
MAJOR_NR
);
printk
(
"pcd: unable to get major number %d
\n
"
,
MAJOR_NR
);
return
-
1
;
return
-
1
;
}
}
for
(
unit
=
0
;
unit
<
PCD_UNITS
;
unit
++
)
{
for
(
unit
=
0
;
unit
<
PCD_UNITS
;
unit
++
)
{
if
(
PCD
.
present
)
{
if
(
PCD
.
present
)
{
register_cdrom
(
&
PCD
.
info
);
register_cdrom
(
&
PCD
.
info
);
devfs_plain_cdrom
(
&
PCD
.
info
,
&
pcd_bdops
);
devfs_plain_cdrom
(
&
PCD
.
info
,
&
pcd_bdops
);
...
@@ -930,12 +975,12 @@ static int __init pcd_init(void)
...
@@ -930,12 +975,12 @@ static int __init pcd_init(void)
static
void
__exit
pcd_exit
(
void
)
static
void
__exit
pcd_exit
(
void
)
{
{
int
unit
;
int
unit
;
for
(
unit
=
0
;
unit
<
PCD_UNITS
;
unit
++
)
for
(
unit
=
0
;
unit
<
PCD_UNITS
;
unit
++
)
if
(
PCD
.
present
)
{
if
(
PCD
.
present
)
{
pi_release
(
PI
);
pi_release
(
PI
);
unregister_cdrom
(
&
PCD
.
info
);
unregister_cdrom
(
&
PCD
.
info
);
}
}
unregister_blkdev
(
MAJOR_NR
,
name
);
unregister_blkdev
(
MAJOR_NR
,
name
);
}
}
MODULE_LICENSE
(
"GPL"
);
MODULE_LICENSE
(
"GPL"
);
...
...
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