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
d4bf2053
Commit
d4bf2053
authored
Nov 18, 2005
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'upstream-fixes' of master.kernel.org:/pub/scm/linux/kernel/git/jgarzik/libata-dev
parents
8907e94b
e2b1be56
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
162 additions
and
38 deletions
+162
-38
drivers/scsi/sata_mv.c
drivers/scsi/sata_mv.c
+2
-1
drivers/scsi/sata_sil24.c
drivers/scsi/sata_sil24.c
+160
-37
No files found.
drivers/scsi/sata_mv.c
View file @
d4bf2053
...
@@ -2,6 +2,7 @@
...
@@ -2,6 +2,7 @@
* sata_mv.c - Marvell SATA support
* sata_mv.c - Marvell SATA support
*
*
* Copyright 2005: EMC Corporation, all rights reserved.
* Copyright 2005: EMC Corporation, all rights reserved.
* Copyright 2005 Red Hat, Inc. All rights reserved.
*
*
* Please ALWAYS copy linux-ide@vger.kernel.org on emails.
* Please ALWAYS copy linux-ide@vger.kernel.org on emails.
*
*
...
@@ -36,7 +37,7 @@
...
@@ -36,7 +37,7 @@
#include <asm/io.h>
#include <asm/io.h>
#define DRV_NAME "sata_mv"
#define DRV_NAME "sata_mv"
#define DRV_VERSION "0.
2
5"
#define DRV_VERSION "0.5"
enum
{
enum
{
/* BAR's are enumerated in terms of pci_resource_start() terms */
/* BAR's are enumerated in terms of pci_resource_start() terms */
...
...
drivers/scsi/sata_sil24.c
View file @
d4bf2053
...
@@ -5,17 +5,6 @@
...
@@ -5,17 +5,6 @@
*
*
* Based on preview driver from Silicon Image.
* Based on preview driver from Silicon Image.
*
*
* NOTE: No NCQ/ATAPI support yet. The preview driver didn't support
* NCQ nor ATAPI, and, unfortunately, I couldn't find out how to make
* those work. Enabling those shouldn't be difficult. Basic
* structure is all there (in libata-dev tree). If you have any
* information about this hardware, please contact me or linux-ide.
* Info is needed on...
*
* - How to issue tagged commands and turn on sactive on issue accordingly.
* - Where to put an ATAPI command and how to tell the device to send it.
* - How to enable/use 64bit.
*
* This program is free software; you can redistribute it and/or modify it
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2, or (at your option) any
* Free Software Foundation; either version 2, or (at your option) any
...
@@ -42,7 +31,7 @@
...
@@ -42,7 +31,7 @@
#include <asm/io.h>
#include <asm/io.h>
#define DRV_NAME "sata_sil24"
#define DRV_NAME "sata_sil24"
#define DRV_VERSION "0.2
2"
/* Silicon Image's preview driver was 0.10 */
#define DRV_VERSION "0.2
3"
/*
/*
* Port request block (PRB) 32 bytes
* Port request block (PRB) 32 bytes
...
@@ -221,11 +210,22 @@ enum {
...
@@ -221,11 +210,22 @@ enum {
IRQ_STAT_4PORTS
=
0xf
,
IRQ_STAT_4PORTS
=
0xf
,
};
};
struct
sil24_
cmd
_block
{
struct
sil24_
ata
_block
{
struct
sil24_prb
prb
;
struct
sil24_prb
prb
;
struct
sil24_sge
sge
[
LIBATA_MAX_PRD
];
struct
sil24_sge
sge
[
LIBATA_MAX_PRD
];
};
};
struct
sil24_atapi_block
{
struct
sil24_prb
prb
;
u8
cdb
[
16
];
struct
sil24_sge
sge
[
LIBATA_MAX_PRD
-
1
];
};
union
sil24_cmd_block
{
struct
sil24_ata_block
ata
;
struct
sil24_atapi_block
atapi
;
};
/*
/*
* ap->private_data
* ap->private_data
*
*
...
@@ -233,7 +233,7 @@ struct sil24_cmd_block {
...
@@ -233,7 +233,7 @@ struct sil24_cmd_block {
* here from the previous interrupt.
* here from the previous interrupt.
*/
*/
struct
sil24_port_priv
{
struct
sil24_port_priv
{
struct
sil24_cmd_block
*
cmd_block
;
/* 32 cmd blocks */
union
sil24_cmd_block
*
cmd_block
;
/* 32 cmd blocks */
dma_addr_t
cmd_block_dma
;
/* DMA base addr for them */
dma_addr_t
cmd_block_dma
;
/* DMA base addr for them */
struct
ata_taskfile
tf
;
/* Cached taskfile registers */
struct
ata_taskfile
tf
;
/* Cached taskfile registers */
};
};
...
@@ -244,6 +244,7 @@ struct sil24_host_priv {
...
@@ -244,6 +244,7 @@ struct sil24_host_priv {
void
__iomem
*
port_base
;
/* port registers (4 * 8192 bytes @BAR2) */
void
__iomem
*
port_base
;
/* port registers (4 * 8192 bytes @BAR2) */
};
};
static
void
sil24_dev_config
(
struct
ata_port
*
ap
,
struct
ata_device
*
dev
);
static
u8
sil24_check_status
(
struct
ata_port
*
ap
);
static
u8
sil24_check_status
(
struct
ata_port
*
ap
);
static
u32
sil24_scr_read
(
struct
ata_port
*
ap
,
unsigned
sc_reg
);
static
u32
sil24_scr_read
(
struct
ata_port
*
ap
,
unsigned
sc_reg
);
static
void
sil24_scr_write
(
struct
ata_port
*
ap
,
unsigned
sc_reg
,
u32
val
);
static
void
sil24_scr_write
(
struct
ata_port
*
ap
,
unsigned
sc_reg
,
u32
val
);
...
@@ -297,6 +298,8 @@ static struct scsi_host_template sil24_sht = {
...
@@ -297,6 +298,8 @@ static struct scsi_host_template sil24_sht = {
static
const
struct
ata_port_operations
sil24_ops
=
{
static
const
struct
ata_port_operations
sil24_ops
=
{
.
port_disable
=
ata_port_disable
,
.
port_disable
=
ata_port_disable
,
.
dev_config
=
sil24_dev_config
,
.
check_status
=
sil24_check_status
,
.
check_status
=
sil24_check_status
,
.
check_altstatus
=
sil24_check_status
,
.
check_altstatus
=
sil24_check_status
,
.
dev_select
=
ata_noop_dev_select
,
.
dev_select
=
ata_noop_dev_select
,
...
@@ -333,7 +336,7 @@ static struct ata_port_info sil24_port_info[] = {
...
@@ -333,7 +336,7 @@ static struct ata_port_info sil24_port_info[] = {
{
{
.
sht
=
&
sil24_sht
,
.
sht
=
&
sil24_sht
,
.
host_flags
=
ATA_FLAG_SATA
|
ATA_FLAG_NO_LEGACY
|
.
host_flags
=
ATA_FLAG_SATA
|
ATA_FLAG_NO_LEGACY
|
ATA_FLAG_S
ATA_RESE
T
|
ATA_FLAG_MMIO
|
ATA_FLAG_S
RS
T
|
ATA_FLAG_MMIO
|
ATA_FLAG_PIO_DMA
|
SIL24_NPORTS2FLAG
(
4
),
ATA_FLAG_PIO_DMA
|
SIL24_NPORTS2FLAG
(
4
),
.
pio_mask
=
0x1f
,
/* pio0-4 */
.
pio_mask
=
0x1f
,
/* pio0-4 */
.
mwdma_mask
=
0x07
,
/* mwdma0-2 */
.
mwdma_mask
=
0x07
,
/* mwdma0-2 */
...
@@ -344,7 +347,7 @@ static struct ata_port_info sil24_port_info[] = {
...
@@ -344,7 +347,7 @@ static struct ata_port_info sil24_port_info[] = {
{
{
.
sht
=
&
sil24_sht
,
.
sht
=
&
sil24_sht
,
.
host_flags
=
ATA_FLAG_SATA
|
ATA_FLAG_NO_LEGACY
|
.
host_flags
=
ATA_FLAG_SATA
|
ATA_FLAG_NO_LEGACY
|
ATA_FLAG_S
ATA_RESE
T
|
ATA_FLAG_MMIO
|
ATA_FLAG_S
RS
T
|
ATA_FLAG_MMIO
|
ATA_FLAG_PIO_DMA
|
SIL24_NPORTS2FLAG
(
2
),
ATA_FLAG_PIO_DMA
|
SIL24_NPORTS2FLAG
(
2
),
.
pio_mask
=
0x1f
,
/* pio0-4 */
.
pio_mask
=
0x1f
,
/* pio0-4 */
.
mwdma_mask
=
0x07
,
/* mwdma0-2 */
.
mwdma_mask
=
0x07
,
/* mwdma0-2 */
...
@@ -355,7 +358,7 @@ static struct ata_port_info sil24_port_info[] = {
...
@@ -355,7 +358,7 @@ static struct ata_port_info sil24_port_info[] = {
{
{
.
sht
=
&
sil24_sht
,
.
sht
=
&
sil24_sht
,
.
host_flags
=
ATA_FLAG_SATA
|
ATA_FLAG_NO_LEGACY
|
.
host_flags
=
ATA_FLAG_SATA
|
ATA_FLAG_NO_LEGACY
|
ATA_FLAG_S
ATA_RESE
T
|
ATA_FLAG_MMIO
|
ATA_FLAG_S
RS
T
|
ATA_FLAG_MMIO
|
ATA_FLAG_PIO_DMA
|
SIL24_NPORTS2FLAG
(
1
),
ATA_FLAG_PIO_DMA
|
SIL24_NPORTS2FLAG
(
1
),
.
pio_mask
=
0x1f
,
/* pio0-4 */
.
pio_mask
=
0x1f
,
/* pio0-4 */
.
mwdma_mask
=
0x07
,
/* mwdma0-2 */
.
mwdma_mask
=
0x07
,
/* mwdma0-2 */
...
@@ -364,6 +367,16 @@ static struct ata_port_info sil24_port_info[] = {
...
@@ -364,6 +367,16 @@ static struct ata_port_info sil24_port_info[] = {
},
},
};
};
static
void
sil24_dev_config
(
struct
ata_port
*
ap
,
struct
ata_device
*
dev
)
{
void
__iomem
*
port
=
(
void
__iomem
*
)
ap
->
ioaddr
.
cmd_addr
;
if
(
ap
->
cdb_len
==
16
)
writel
(
PORT_CS_CDB16
,
port
+
PORT_CTRL_STAT
);
else
writel
(
PORT_CS_CDB16
,
port
+
PORT_CTRL_CLR
);
}
static
inline
void
sil24_update_tf
(
struct
ata_port
*
ap
)
static
inline
void
sil24_update_tf
(
struct
ata_port
*
ap
)
{
{
struct
sil24_port_priv
*
pp
=
ap
->
private_data
;
struct
sil24_port_priv
*
pp
=
ap
->
private_data
;
...
@@ -415,22 +428,73 @@ static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
...
@@ -415,22 +428,73 @@ static void sil24_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
*
tf
=
pp
->
tf
;
*
tf
=
pp
->
tf
;
}
}
static
void
sil24_phy_reset
(
struct
ata_port
*
ap
)
static
int
sil24_issue_SRST
(
struct
ata_port
*
ap
)
{
{
__sata_phy_reset
(
ap
);
void
__iomem
*
port
=
(
void
__iomem
*
)
ap
->
ioaddr
.
cmd_addr
;
struct
sil24_port_priv
*
pp
=
ap
->
private_data
;
struct
sil24_prb
*
prb
=
&
pp
->
cmd_block
[
0
].
ata
.
prb
;
dma_addr_t
paddr
=
pp
->
cmd_block_dma
;
u32
irq_enable
,
irq_stat
;
int
cnt
;
/* temporarily turn off IRQs during SRST */
irq_enable
=
readl
(
port
+
PORT_IRQ_ENABLE_SET
);
writel
(
irq_enable
,
port
+
PORT_IRQ_ENABLE_CLR
);
/*
/*
* No ATAPI yet. Just unconditionally indicate ATA device.
* XXX: Not sure whether the following sleep is needed or not.
* If ATAPI device is attached, it will fail ATA_CMD_ID_ATA
* The original driver had it. So....
* and libata core will ignore the device.
*/
*/
if
(
!
(
ap
->
flags
&
ATA_FLAG_PORT_DISABLED
))
msleep
(
10
);
ap
->
device
[
0
].
class
=
ATA_DEV_ATA
;
prb
->
ctrl
=
PRB_CTRL_SRST
;
prb
->
fis
[
1
]
=
0
;
/* no PM yet */
writel
((
u32
)
paddr
,
port
+
PORT_CMD_ACTIVATE
);
for
(
cnt
=
0
;
cnt
<
100
;
cnt
++
)
{
irq_stat
=
readl
(
port
+
PORT_IRQ_STAT
);
writel
(
irq_stat
,
port
+
PORT_IRQ_STAT
);
/* clear irq */
irq_stat
>>=
PORT_IRQ_RAW_SHIFT
;
if
(
irq_stat
&
(
PORT_IRQ_COMPLETE
|
PORT_IRQ_ERROR
))
break
;
msleep
(
1
);
}
/* restore IRQs */
writel
(
irq_enable
,
port
+
PORT_IRQ_ENABLE_SET
);
if
(
!
(
irq_stat
&
PORT_IRQ_COMPLETE
))
return
-
1
;
/* update TF */
sil24_update_tf
(
ap
);
return
0
;
}
static
void
sil24_phy_reset
(
struct
ata_port
*
ap
)
{
struct
sil24_port_priv
*
pp
=
ap
->
private_data
;
__sata_phy_reset
(
ap
);
if
(
ap
->
flags
&
ATA_FLAG_PORT_DISABLED
)
return
;
if
(
sil24_issue_SRST
(
ap
)
<
0
)
{
printk
(
KERN_ERR
DRV_NAME
" ata%u: SRST failed, disabling port
\n
"
,
ap
->
id
);
ap
->
ops
->
port_disable
(
ap
);
return
;
}
ap
->
device
->
class
=
ata_dev_classify
(
&
pp
->
tf
);
}
}
static
inline
void
sil24_fill_sg
(
struct
ata_queued_cmd
*
qc
,
static
inline
void
sil24_fill_sg
(
struct
ata_queued_cmd
*
qc
,
struct
sil24_
cmd_block
*
cb
)
struct
sil24_
sge
*
sge
)
{
{
struct
sil24_sge
*
sge
=
cb
->
sge
;
struct
scatterlist
*
sg
;
struct
scatterlist
*
sg
;
unsigned
int
idx
=
0
;
unsigned
int
idx
=
0
;
...
@@ -451,23 +515,47 @@ static void sil24_qc_prep(struct ata_queued_cmd *qc)
...
@@ -451,23 +515,47 @@ static void sil24_qc_prep(struct ata_queued_cmd *qc)
{
{
struct
ata_port
*
ap
=
qc
->
ap
;
struct
ata_port
*
ap
=
qc
->
ap
;
struct
sil24_port_priv
*
pp
=
ap
->
private_data
;
struct
sil24_port_priv
*
pp
=
ap
->
private_data
;
struct
sil24_cmd_block
*
cb
=
pp
->
cmd_block
+
qc
->
tag
;
union
sil24_cmd_block
*
cb
=
pp
->
cmd_block
+
qc
->
tag
;
struct
sil24_prb
*
prb
=
&
cb
->
prb
;
struct
sil24_prb
*
prb
;
struct
sil24_sge
*
sge
;
switch
(
qc
->
tf
.
protocol
)
{
switch
(
qc
->
tf
.
protocol
)
{
case
ATA_PROT_PIO
:
case
ATA_PROT_PIO
:
case
ATA_PROT_DMA
:
case
ATA_PROT_DMA
:
case
ATA_PROT_NODATA
:
case
ATA_PROT_NODATA
:
prb
=
&
cb
->
ata
.
prb
;
sge
=
cb
->
ata
.
sge
;
prb
->
ctrl
=
0
;
break
;
case
ATA_PROT_ATAPI
:
case
ATA_PROT_ATAPI_DMA
:
case
ATA_PROT_ATAPI_NODATA
:
prb
=
&
cb
->
atapi
.
prb
;
sge
=
cb
->
atapi
.
sge
;
memset
(
cb
->
atapi
.
cdb
,
0
,
32
);
memcpy
(
cb
->
atapi
.
cdb
,
qc
->
cdb
,
ap
->
cdb_len
);
if
(
qc
->
tf
.
protocol
!=
ATA_PROT_ATAPI_NODATA
)
{
if
(
qc
->
tf
.
flags
&
ATA_TFLAG_WRITE
)
prb
->
ctrl
=
PRB_CTRL_PACKET_WRITE
;
else
prb
->
ctrl
=
PRB_CTRL_PACKET_READ
;
}
else
prb
->
ctrl
=
0
;
break
;
break
;
default:
default:
/* ATAPI isn't supported yet */
prb
=
NULL
;
/* shut up, gcc */
sge
=
NULL
;
BUG
();
BUG
();
}
}
ata_tf_to_fis
(
&
qc
->
tf
,
prb
->
fis
,
0
);
ata_tf_to_fis
(
&
qc
->
tf
,
prb
->
fis
,
0
);
if
(
qc
->
flags
&
ATA_QCFLAG_DMAMAP
)
if
(
qc
->
flags
&
ATA_QCFLAG_DMAMAP
)
sil24_fill_sg
(
qc
,
cb
);
sil24_fill_sg
(
qc
,
sge
);
}
}
static
int
sil24_qc_issue
(
struct
ata_queued_cmd
*
qc
)
static
int
sil24_qc_issue
(
struct
ata_queued_cmd
*
qc
)
...
@@ -486,6 +574,31 @@ static void sil24_irq_clear(struct ata_port *ap)
...
@@ -486,6 +574,31 @@ static void sil24_irq_clear(struct ata_port *ap)
/* unused */
/* unused */
}
}
static
int
__sil24_restart_controller
(
void
__iomem
*
port
)
{
u32
tmp
;
int
cnt
;
writel
(
PORT_CS_INIT
,
port
+
PORT_CTRL_STAT
);
/* Max ~10ms */
for
(
cnt
=
0
;
cnt
<
10000
;
cnt
++
)
{
tmp
=
readl
(
port
+
PORT_CTRL_STAT
);
if
(
tmp
&
PORT_CS_RDY
)
return
0
;
udelay
(
1
);
}
return
-
1
;
}
static
void
sil24_restart_controller
(
struct
ata_port
*
ap
)
{
if
(
__sil24_restart_controller
((
void
__iomem
*
)
ap
->
ioaddr
.
cmd_addr
))
printk
(
KERN_ERR
DRV_NAME
" ata%u: failed to restart controller
\n
"
,
ap
->
id
);
}
static
int
__sil24_reset_controller
(
void
__iomem
*
port
)
static
int
__sil24_reset_controller
(
void
__iomem
*
port
)
{
{
int
cnt
;
int
cnt
;
...
@@ -505,7 +618,11 @@ static int __sil24_reset_controller(void __iomem *port)
...
@@ -505,7 +618,11 @@ static int __sil24_reset_controller(void __iomem *port)
if
(
tmp
&
PORT_CS_DEV_RST
)
if
(
tmp
&
PORT_CS_DEV_RST
)
return
-
1
;
return
-
1
;
if
(
tmp
&
PORT_CS_RDY
)
return
0
;
return
0
;
return
__sil24_restart_controller
(
port
);
}
}
static
void
sil24_reset_controller
(
struct
ata_port
*
ap
)
static
void
sil24_reset_controller
(
struct
ata_port
*
ap
)
...
@@ -567,7 +684,13 @@ static void sil24_error_intr(struct ata_port *ap, u32 slot_stat)
...
@@ -567,7 +684,13 @@ static void sil24_error_intr(struct ata_port *ap, u32 slot_stat)
if
(
serror
)
if
(
serror
)
writel
(
serror
,
port
+
PORT_SERROR
);
writel
(
serror
,
port
+
PORT_SERROR
);
printk
(
KERN_ERR
DRV_NAME
" ata%u: error interrupt on port%d
\n
"
/*
* Don't log ATAPI device errors. They're supposed to happen
* and any serious errors will be logged using sense data by
* the SCSI layer.
*/
if
(
ap
->
device
[
0
].
class
!=
ATA_DEV_ATAPI
||
cmd_err
>
PORT_CERR_SDB
)
printk
(
"ata%u: error interrupt on port%d
\n
"
" stat=0x%x irq=0x%x cmd_err=%d sstatus=0x%x serror=0x%x
\n
"
,
" stat=0x%x irq=0x%x cmd_err=%d sstatus=0x%x serror=0x%x
\n
"
,
ap
->
id
,
ap
->
port_no
,
slot_stat
,
irq_stat
,
cmd_err
,
sstatus
,
serror
);
ap
->
id
,
ap
->
port_no
,
slot_stat
,
irq_stat
,
cmd_err
,
sstatus
,
serror
);
...
@@ -577,6 +700,7 @@ static void sil24_error_intr(struct ata_port *ap, u32 slot_stat)
...
@@ -577,6 +700,7 @@ static void sil24_error_intr(struct ata_port *ap, u32 slot_stat)
*/
*/
sil24_update_tf
(
ap
);
sil24_update_tf
(
ap
);
err_mask
=
ac_err_mask
(
pp
->
tf
.
command
);
err_mask
=
ac_err_mask
(
pp
->
tf
.
command
);
sil24_restart_controller
(
ap
);
}
else
{
}
else
{
/*
/*
* Other errors. libata currently doesn't have any
* Other errors. libata currently doesn't have any
...
@@ -584,12 +708,11 @@ static void sil24_error_intr(struct ata_port *ap, u32 slot_stat)
...
@@ -584,12 +708,11 @@ static void sil24_error_intr(struct ata_port *ap, u32 slot_stat)
* ATA_ERR.
* ATA_ERR.
*/
*/
err_mask
=
AC_ERR_OTHER
;
err_mask
=
AC_ERR_OTHER
;
sil24_reset_controller
(
ap
);
}
}
if
(
qc
)
if
(
qc
)
ata_qc_complete
(
qc
,
err_mask
);
ata_qc_complete
(
qc
,
err_mask
);
sil24_reset_controller
(
ap
);
}
}
static
inline
void
sil24_host_intr
(
struct
ata_port
*
ap
)
static
inline
void
sil24_host_intr
(
struct
ata_port
*
ap
)
...
@@ -665,7 +788,7 @@ static int sil24_port_start(struct ata_port *ap)
...
@@ -665,7 +788,7 @@ static int sil24_port_start(struct ata_port *ap)
{
{
struct
device
*
dev
=
ap
->
host_set
->
dev
;
struct
device
*
dev
=
ap
->
host_set
->
dev
;
struct
sil24_port_priv
*
pp
;
struct
sil24_port_priv
*
pp
;
struct
sil24_cmd_block
*
cb
;
union
sil24_cmd_block
*
cb
;
size_t
cb_size
=
sizeof
(
*
cb
);
size_t
cb_size
=
sizeof
(
*
cb
);
dma_addr_t
cb_dma
;
dma_addr_t
cb_dma
;
int
rc
=
-
ENOMEM
;
int
rc
=
-
ENOMEM
;
...
...
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