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
c79dd287
Commit
c79dd287
authored
Aug 13, 2004
by
Jeff Garzik
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[libata] support commands SYNCHRONIZE CACHE, VERIFY, VERIFY(16)
parent
e4babc07
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
142 additions
and
7 deletions
+142
-7
drivers/scsi/libata-scsi.c
drivers/scsi/libata-scsi.c
+132
-7
include/linux/ata.h
include/linux/ata.h
+2
-0
include/linux/libata.h
include/linux/libata.h
+7
-0
include/scsi/scsi.h
include/scsi/scsi.h
+1
-0
No files found.
drivers/scsi/libata-scsi.c
View file @
c79dd287
...
@@ -218,6 +218,124 @@ int ata_scsi_error(struct Scsi_Host *host)
...
@@ -218,6 +218,124 @@ int ata_scsi_error(struct Scsi_Host *host)
return
0
;
return
0
;
}
}
/**
* ata_scsi_flush_xlat - Translate SCSI SYNCHRONIZE CACHE command
* @qc: Storage for translated ATA taskfile
* @scsicmd: SCSI command to translate (ignored)
*
* Sets up an ATA taskfile to issue FLUSH CACHE or
* FLUSH CACHE EXT.
*
* LOCKING:
* spin_lock_irqsave(host_set lock)
*
* RETURNS:
* Zero on success, non-zero on error.
*/
static
unsigned
int
ata_scsi_flush_xlat
(
struct
ata_queued_cmd
*
qc
,
u8
*
scsicmd
)
{
struct
ata_taskfile
*
tf
=
&
qc
->
tf
;
tf
->
flags
|=
ATA_TFLAG_DEVICE
;
tf
->
protocol
=
ATA_PROT_NODATA
;
if
((
tf
->
flags
&
ATA_TFLAG_LBA48
)
&&
(
ata_id_has_flush_ext
(
qc
->
dev
)))
tf
->
command
=
ATA_CMD_FLUSH_EXT
;
else
tf
->
command
=
ATA_CMD_FLUSH
;
return
0
;
}
/**
* ata_scsi_verify_xlat - Translate SCSI VERIFY command into an ATA one
* @qc: Storage for translated ATA taskfile
* @scsicmd: SCSI command to translate
*
* Converts SCSI VERIFY command to an ATA READ VERIFY command.
*
* LOCKING:
* spin_lock_irqsave(host_set lock)
*
* RETURNS:
* Zero on success, non-zero on error.
*/
static
unsigned
int
ata_scsi_verify_xlat
(
struct
ata_queued_cmd
*
qc
,
u8
*
scsicmd
)
{
struct
ata_taskfile
*
tf
=
&
qc
->
tf
;
unsigned
int
lba48
=
tf
->
flags
&
ATA_TFLAG_LBA48
;
u64
dev_sectors
=
qc
->
dev
->
n_sectors
;
u64
sect
=
0
;
u32
n_sect
=
0
;
tf
->
flags
|=
ATA_TFLAG_ISADDR
|
ATA_TFLAG_DEVICE
;
tf
->
protocol
=
ATA_PROT_NODATA
;
tf
->
device
|=
ATA_LBA
;
if
(
scsicmd
[
0
]
==
VERIFY
)
{
sect
|=
((
u64
)
scsicmd
[
2
])
<<
24
;
sect
|=
((
u64
)
scsicmd
[
3
])
<<
16
;
sect
|=
((
u64
)
scsicmd
[
4
])
<<
8
;
sect
|=
((
u64
)
scsicmd
[
5
]);
n_sect
|=
((
u32
)
scsicmd
[
7
])
<<
8
;
n_sect
|=
((
u32
)
scsicmd
[
8
]);
}
else
if
(
scsicmd
[
0
]
==
VERIFY_16
)
{
sect
|=
((
u64
)
scsicmd
[
2
])
<<
56
;
sect
|=
((
u64
)
scsicmd
[
3
])
<<
48
;
sect
|=
((
u64
)
scsicmd
[
4
])
<<
40
;
sect
|=
((
u64
)
scsicmd
[
5
])
<<
32
;
sect
|=
((
u64
)
scsicmd
[
6
])
<<
24
;
sect
|=
((
u64
)
scsicmd
[
7
])
<<
16
;
sect
|=
((
u64
)
scsicmd
[
8
])
<<
8
;
sect
|=
((
u64
)
scsicmd
[
9
]);
n_sect
|=
((
u32
)
scsicmd
[
10
])
<<
24
;
n_sect
|=
((
u32
)
scsicmd
[
11
])
<<
16
;
n_sect
|=
((
u32
)
scsicmd
[
12
])
<<
8
;
n_sect
|=
((
u32
)
scsicmd
[
13
]);
}
else
return
1
;
if
(
!
n_sect
)
return
1
;
if
(
sect
>=
dev_sectors
)
return
1
;
if
((
sect
+
n_sect
)
>
dev_sectors
)
return
1
;
if
(
lba48
)
{
if
(
n_sect
>
(
64
*
1024
))
return
1
;
}
else
{
if
(
n_sect
>
256
)
return
1
;
}
if
(
lba48
)
{
tf
->
hob_nsect
=
(
n_sect
>>
8
)
&
0xff
;
tf
->
hob_lbah
=
(
sect
>>
40
)
&
0xff
;
tf
->
hob_lbam
=
(
sect
>>
32
)
&
0xff
;
tf
->
hob_lbal
=
(
sect
>>
24
)
&
0xff
;
}
else
tf
->
device
|=
(
sect
>>
24
)
&
0xf
;
tf
->
nsect
=
n_sect
&
0xff
;
tf
->
hob_lbah
=
(
sect
>>
16
)
&
0xff
;
tf
->
hob_lbam
=
(
sect
>>
8
)
&
0xff
;
tf
->
hob_lbal
=
sect
&
0xff
;
return
0
;
}
/**
/**
* ata_scsi_rw_xlat - Translate SCSI r/w command into an ATA one
* ata_scsi_rw_xlat - Translate SCSI r/w command into an ATA one
* @qc: Storage for translated ATA taskfile
* @qc: Storage for translated ATA taskfile
...
@@ -244,10 +362,6 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
...
@@ -244,10 +362,6 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd)
unsigned
int
lba48
=
tf
->
flags
&
ATA_TFLAG_LBA48
;
unsigned
int
lba48
=
tf
->
flags
&
ATA_TFLAG_LBA48
;
tf
->
flags
|=
ATA_TFLAG_ISADDR
|
ATA_TFLAG_DEVICE
;
tf
->
flags
|=
ATA_TFLAG_ISADDR
|
ATA_TFLAG_DEVICE
;
tf
->
hob_nsect
=
0
;
tf
->
hob_lbal
=
0
;
tf
->
hob_lbam
=
0
;
tf
->
hob_lbah
=
0
;
tf
->
protocol
=
qc
->
dev
->
xfer_protocol
;
tf
->
protocol
=
qc
->
dev
->
xfer_protocol
;
tf
->
device
|=
ATA_LBA
;
tf
->
device
|=
ATA_LBA
;
...
@@ -1086,6 +1200,7 @@ ata_scsi_find_dev(struct ata_port *ap, struct scsi_cmnd *cmd)
...
@@ -1086,6 +1200,7 @@ ata_scsi_find_dev(struct ata_port *ap, struct scsi_cmnd *cmd)
/**
/**
* ata_get_xlat_func - check if SCSI to ATA translation is possible
* ata_get_xlat_func - check if SCSI to ATA translation is possible
* @dev: ATA device
* @cmd: SCSI command opcode to consider
* @cmd: SCSI command opcode to consider
*
*
* Look up the SCSI command given, and determine whether the
* Look up the SCSI command given, and determine whether the
...
@@ -1095,7 +1210,7 @@ ata_scsi_find_dev(struct ata_port *ap, struct scsi_cmnd *cmd)
...
@@ -1095,7 +1210,7 @@ ata_scsi_find_dev(struct ata_port *ap, struct scsi_cmnd *cmd)
* Pointer to translation function if possible, %NULL if not.
* Pointer to translation function if possible, %NULL if not.
*/
*/
static
inline
ata_xlat_func_t
ata_get_xlat_func
(
u8
cmd
)
static
inline
ata_xlat_func_t
ata_get_xlat_func
(
struct
ata_device
*
dev
,
u8
cmd
)
{
{
switch
(
cmd
)
{
switch
(
cmd
)
{
case
READ_6
:
case
READ_6
:
...
@@ -1106,6 +1221,15 @@ static inline ata_xlat_func_t ata_get_xlat_func(u8 cmd)
...
@@ -1106,6 +1221,15 @@ static inline ata_xlat_func_t ata_get_xlat_func(u8 cmd)
case
WRITE_10
:
case
WRITE_10
:
case
WRITE_16
:
case
WRITE_16
:
return
ata_scsi_rw_xlat
;
return
ata_scsi_rw_xlat
;
case
SYNCHRONIZE_CACHE
:
if
(
ata_try_flush_cache
(
dev
))
return
ata_scsi_flush_xlat
;
break
;
case
VERIFY
:
case
VERIFY_16
:
return
ata_scsi_verify_xlat
;
}
}
return
NULL
;
return
NULL
;
...
@@ -1170,7 +1294,8 @@ int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
...
@@ -1170,7 +1294,8 @@ int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *))
}
}
if
(
dev
->
class
==
ATA_DEV_ATA
)
{
if
(
dev
->
class
==
ATA_DEV_ATA
)
{
ata_xlat_func_t
xlat_func
=
ata_get_xlat_func
(
cmd
->
cmnd
[
0
]);
ata_xlat_func_t
xlat_func
=
ata_get_xlat_func
(
dev
,
cmd
->
cmnd
[
0
]);
if
(
xlat_func
)
if
(
xlat_func
)
ata_scsi_translate
(
ap
,
dev
,
cmd
,
done
,
xlat_func
);
ata_scsi_translate
(
ap
,
dev
,
cmd
,
done
,
xlat_func
);
...
@@ -1211,7 +1336,7 @@ static void ata_scsi_simulate(struct ata_port *ap, struct ata_device *dev,
...
@@ -1211,7 +1336,7 @@ static void ata_scsi_simulate(struct ata_port *ap, struct ata_device *dev,
switch
(
scsicmd
[
0
])
{
switch
(
scsicmd
[
0
])
{
/* no-op's, complete with success */
/* no-op's, complete with success */
case
SYNCHRONIZE_CACHE
:
/* FIXME: temporary */
case
SYNCHRONIZE_CACHE
:
case
REZERO_UNIT
:
case
REZERO_UNIT
:
case
SEEK_6
:
case
SEEK_6
:
case
SEEK_10
:
case
SEEK_10
:
...
...
include/linux/ata.h
View file @
c79dd287
...
@@ -215,6 +215,8 @@ struct ata_taskfile {
...
@@ -215,6 +215,8 @@ struct ata_taskfile {
#define ata_id_is_ata(dev) (((dev)->id[0] & (1 << 15)) == 0)
#define ata_id_is_ata(dev) (((dev)->id[0] & (1 << 15)) == 0)
#define ata_id_rahead_enabled(dev) ((dev)->id[85] & (1 << 6))
#define ata_id_rahead_enabled(dev) ((dev)->id[85] & (1 << 6))
#define ata_id_wcache_enabled(dev) ((dev)->id[85] & (1 << 5))
#define ata_id_wcache_enabled(dev) ((dev)->id[85] & (1 << 5))
#define ata_id_has_flush(dev) ((dev)->id[83] & (1 << 12))
#define ata_id_has_flush_ext(dev) ((dev)->id[83] & (1 << 13))
#define ata_id_has_lba48(dev) ((dev)->id[83] & (1 << 10))
#define ata_id_has_lba48(dev) ((dev)->id[83] & (1 << 10))
#define ata_id_has_wcache(dev) ((dev)->id[82] & (1 << 5))
#define ata_id_has_wcache(dev) ((dev)->id[82] & (1 << 5))
#define ata_id_has_pm(dev) ((dev)->id[82] & (1 << 3))
#define ata_id_has_pm(dev) ((dev)->id[82] & (1 << 3))
...
...
include/linux/libata.h
View file @
c79dd287
...
@@ -607,4 +607,11 @@ static inline u8 ata_bmdma_status(struct ata_port *ap)
...
@@ -607,4 +607,11 @@ static inline u8 ata_bmdma_status(struct ata_port *ap)
return
host_stat
;
return
host_stat
;
}
}
static
inline
int
ata_try_flush_cache
(
struct
ata_device
*
dev
)
{
return
ata_id_wcache_enabled
(
dev
)
||
ata_id_has_flush
(
dev
)
||
ata_id_has_flush_ext
(
dev
);
}
#endif
/* __LINUX_LIBATA_H__ */
#endif
/* __LINUX_LIBATA_H__ */
include/scsi/scsi.h
View file @
c79dd287
...
@@ -108,6 +108,7 @@ extern const char *const scsi_device_types[MAX_SCSI_DEVICE_CODE];
...
@@ -108,6 +108,7 @@ extern const char *const scsi_device_types[MAX_SCSI_DEVICE_CODE];
#define WRITE_LONG_2 0xea
#define WRITE_LONG_2 0xea
#define READ_16 0x88
#define READ_16 0x88
#define WRITE_16 0x8a
#define WRITE_16 0x8a
#define VERIFY_16 0x8f
#define SERVICE_ACTION_IN 0x9e
#define SERVICE_ACTION_IN 0x9e
/* values for service action in */
/* values for service action in */
#define SAI_READ_CAPACITY_16 0x10
#define SAI_READ_CAPACITY_16 0x10
...
...
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