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
fbf0e134
Commit
fbf0e134
authored
Nov 17, 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
b7fd1edd
a2c91a88
Changes
12
Show whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
898 additions
and
198 deletions
+898
-198
drivers/scsi/Kconfig
drivers/scsi/Kconfig
+1
-1
drivers/scsi/ahci.c
drivers/scsi/ahci.c
+16
-14
drivers/scsi/ata_piix.c
drivers/scsi/ata_piix.c
+1
-1
drivers/scsi/libata-core.c
drivers/scsi/libata-core.c
+32
-6
drivers/scsi/libata.h
drivers/scsi/libata.h
+1
-1
drivers/scsi/sata_mv.c
drivers/scsi/sata_mv.c
+822
-169
drivers/scsi/sata_promise.c
drivers/scsi/sata_promise.c
+1
-1
drivers/scsi/sata_qstor.c
drivers/scsi/sata_qstor.c
+1
-1
drivers/scsi/sata_sil24.c
drivers/scsi/sata_sil24.c
+20
-1
drivers/scsi/sata_svw.c
drivers/scsi/sata_svw.c
+1
-1
drivers/scsi/sata_sx4.c
drivers/scsi/sata_sx4.c
+1
-1
drivers/scsi/sata_vsc.c
drivers/scsi/sata_vsc.c
+1
-1
No files found.
drivers/scsi/Kconfig
View file @
fbf0e134
...
...
@@ -497,7 +497,7 @@ config SCSI_ATA_PIIX
If unsure, say N.
config SCSI_SATA_MV
tristate "Marvell SATA support"
tristate "Marvell SATA support
(HIGHLY EXPERIMENTAL)
"
depends on SCSI_SATA && PCI && EXPERIMENTAL
help
This option enables support for the Marvell Serial ATA family.
...
...
drivers/scsi/ahci.c
View file @
fbf0e134
...
...
@@ -48,7 +48,7 @@
#include <asm/io.h>
#define DRV_NAME "ahci"
#define DRV_VERSION "1.
01
"
#define DRV_VERSION "1.
2
"
enum
{
...
...
@@ -558,13 +558,15 @@ static void ahci_qc_prep(struct ata_queued_cmd *qc)
pp
->
cmd_slot
[
0
].
opts
|=
cpu_to_le32
(
n_elem
<<
16
);
}
static
void
ahci_
intr_error
(
struct
ata_port
*
ap
,
u32
irq_stat
)
static
void
ahci_
restart_port
(
struct
ata_port
*
ap
,
u32
irq_stat
)
{
void
__iomem
*
mmio
=
ap
->
host_set
->
mmio_base
;
void
__iomem
*
port_mmio
=
ahci_port_base
(
mmio
,
ap
->
port_no
);
u32
tmp
;
int
work
;
if
((
ap
->
device
[
0
].
class
!=
ATA_DEV_ATAPI
)
||
((
irq_stat
&
PORT_IRQ_TF_ERR
)
==
0
))
printk
(
KERN_WARNING
"ata%u: port reset, "
"p_is %x is %x pis %x cmd %x tf %x ss %x se %x
\n
"
,
ap
->
id
,
...
...
@@ -632,7 +634,7 @@ static void ahci_eng_timeout(struct ata_port *ap)
printk
(
KERN_ERR
"ata%u: BUG: timeout without command
\n
"
,
ap
->
id
);
}
else
{
ahci_
intr_error
(
ap
,
readl
(
port_mmio
+
PORT_IRQ_STAT
));
ahci_
restart_port
(
ap
,
readl
(
port_mmio
+
PORT_IRQ_STAT
));
/* hack alert! We cannot use the supplied completion
* function from inside the ->eh_strategy_handler() thread.
...
...
@@ -677,7 +679,7 @@ static inline int ahci_host_intr(struct ata_port *ap, struct ata_queued_cmd *qc)
err_mask
=
AC_ERR_HOST_BUS
;
/* command processing has stopped due to error; restart */
ahci_
intr_error
(
ap
,
status
);
ahci_
restart_port
(
ap
,
status
);
if
(
qc
)
ata_qc_complete
(
qc
,
err_mask
);
...
...
drivers/scsi/ata_piix.c
View file @
fbf0e134
...
...
@@ -50,7 +50,7 @@
#include <linux/libata.h>
#define DRV_NAME "ata_piix"
#define DRV_VERSION "1.0
4
"
#define DRV_VERSION "1.0
5
"
enum
{
PIIX_IOCFG
=
0x54
,
/* IDE I/O configuration register */
...
...
drivers/scsi/libata-core.c
View file @
fbf0e134
...
...
@@ -1046,6 +1046,30 @@ static unsigned int ata_pio_modes(const struct ata_device *adev)
return
modes
;
}
static
int
ata_qc_wait_err
(
struct
ata_queued_cmd
*
qc
,
struct
completion
*
wait
)
{
int
rc
=
0
;
if
(
wait_for_completion_timeout
(
wait
,
30
*
HZ
)
<
1
)
{
/* timeout handling */
unsigned
int
err_mask
=
ac_err_mask
(
ata_chk_status
(
qc
->
ap
));
if
(
!
err_mask
)
{
printk
(
KERN_WARNING
"ata%u: slow completion (cmd %x)
\n
"
,
qc
->
ap
->
id
,
qc
->
tf
.
command
);
}
else
{
printk
(
KERN_WARNING
"ata%u: qc timeout (cmd %x)
\n
"
,
qc
->
ap
->
id
,
qc
->
tf
.
command
);
rc
=
-
EIO
;
}
ata_qc_complete
(
qc
,
err_mask
);
}
return
rc
;
}
/**
* ata_dev_identify - obtain IDENTIFY x DEVICE page
* @ap: port on which device we wish to probe resides
...
...
@@ -1125,7 +1149,7 @@ static void ata_dev_identify(struct ata_port *ap, unsigned int device)
if
(
rc
)
goto
err_out
;
else
wait_for_completion
(
&
wait
);
ata_qc_wait_err
(
qc
,
&
wait
);
spin_lock_irqsave
(
&
ap
->
host_set
->
lock
,
flags
);
ap
->
ops
->
tf_read
(
ap
,
&
qc
->
tf
);
...
...
@@ -1575,6 +1599,8 @@ int ata_timing_compute(struct ata_device *adev, unsigned short speed,
if
(
!
(
s
=
ata_timing_find_mode
(
speed
)))
return
-
EINVAL
;
memcpy
(
t
,
s
,
sizeof
(
*
s
));
/*
* If the drive is an EIDE drive, it can tell us it needs extended
* PIO/MW_DMA cycle timing.
...
...
@@ -1595,7 +1621,7 @@ int ata_timing_compute(struct ata_device *adev, unsigned short speed,
* Convert the timing to bus clock counts.
*/
ata_timing_quantize
(
s
,
t
,
T
,
UT
);
ata_timing_quantize
(
t
,
t
,
T
,
UT
);
/*
* Even in DMA/UDMA modes we still use PIO access for IDENTIFY, S.M.A.R.T
...
...
@@ -2267,7 +2293,7 @@ static void ata_dev_set_xfermode(struct ata_port *ap, struct ata_device *dev)
if
(
rc
)
ata_port_disable
(
ap
);
else
wait_for_completion
(
&
wait
);
ata_qc_wait_err
(
qc
,
&
wait
);
DPRINTK
(
"EXIT
\n
"
);
}
...
...
@@ -2315,7 +2341,7 @@ static void ata_dev_reread_id(struct ata_port *ap, struct ata_device *dev)
if
(
rc
)
goto
err_out
;
wait_for_completion
(
&
wait
);
ata_qc_wait_err
(
qc
,
&
wait
);
swap_buf_le16
(
dev
->
id
,
ATA_ID_WORDS
);
...
...
@@ -2371,7 +2397,7 @@ static void ata_dev_init_params(struct ata_port *ap, struct ata_device *dev)
if
(
rc
)
ata_port_disable
(
ap
);
else
wait_for_completion
(
&
wait
);
ata_qc_wait_err
(
qc
,
&
wait
);
DPRINTK
(
"EXIT
\n
"
);
}
...
...
drivers/scsi/libata.h
View file @
fbf0e134
...
...
@@ -29,7 +29,7 @@
#define __LIBATA_H__
#define DRV_NAME "libata"
#define DRV_VERSION "1.
12
"
/* must be exactly four chars */
#define DRV_VERSION "1.
20
"
/* must be exactly four chars */
struct
ata_scsi_args
{
u16
*
id
;
...
...
drivers/scsi/sata_mv.c
View file @
fbf0e134
...
...
@@ -50,6 +50,9 @@ enum {
MV_PCI_REG_BASE
=
0
,
MV_IRQ_COAL_REG_BASE
=
0x18000
,
/* 6xxx part only */
MV_SATAHC0_REG_BASE
=
0x20000
,
MV_FLASH_CTL
=
0x1046c
,
MV_GPIO_PORT_CTL
=
0x104f0
,
MV_RESET_CFG
=
0x180d8
,
MV_PCI_REG_SZ
=
MV_MAJOR_REG_AREA_SZ
,
MV_SATAHC_REG_SZ
=
MV_MAJOR_REG_AREA_SZ
,
...
...
@@ -72,11 +75,6 @@ enum {
MV_SG_TBL_SZ
=
(
16
*
MV_MAX_SG_CT
),
MV_PORT_PRIV_DMA_SZ
=
(
MV_CRQB_Q_SZ
+
MV_CRPB_Q_SZ
+
MV_SG_TBL_SZ
),
/* Our DMA boundary is determined by an ePRD being unable to handle
* anything larger than 64KB
*/
MV_DMA_BOUNDARY
=
0xffffU
,
MV_PORTS_PER_HC
=
4
,
/* == (port / MV_PORTS_PER_HC) to determine HC from 0-7 port */
MV_PORT_HC_SHIFT
=
2
,
...
...
@@ -86,16 +84,9 @@ enum {
/* Host Flags */
MV_FLAG_DUAL_HC
=
(
1
<<
30
),
/* two SATA Host Controllers */
MV_FLAG_IRQ_COALESCE
=
(
1
<<
29
),
/* IRQ coalescing capability */
MV_FLAG_GLBL_SFT_RST
=
(
1
<<
28
),
/* Global Soft Reset support */
MV_COMMON_FLAGS
=
(
ATA_FLAG_SATA
|
ATA_FLAG_NO_LEGACY
|
ATA_FLAG_SATA_RESET
|
ATA_FLAG_MMIO
),
MV_6XXX_FLAGS
=
(
MV_FLAG_IRQ_COALESCE
|
MV_FLAG_GLBL_SFT_RST
),
chip_504x
=
0
,
chip_508x
=
1
,
chip_604x
=
2
,
chip_608x
=
3
,
MV_6XXX_FLAGS
=
MV_FLAG_IRQ_COALESCE
,
CRQB_FLAG_READ
=
(
1
<<
0
),
CRQB_TAG_SHIFT
=
1
,
...
...
@@ -116,6 +107,17 @@ enum {
PCI_MASTER_EMPTY
=
(
1
<<
3
),
GLOB_SFT_RST
=
(
1
<<
4
),
MV_PCI_MODE
=
0xd00
,
MV_PCI_EXP_ROM_BAR_CTL
=
0xd2c
,
MV_PCI_DISC_TIMER
=
0xd04
,
MV_PCI_MSI_TRIGGER
=
0xc38
,
MV_PCI_SERR_MASK
=
0xc28
,
MV_PCI_XBAR_TMOUT
=
0x1d04
,
MV_PCI_ERR_LOW_ADDRESS
=
0x1d40
,
MV_PCI_ERR_HIGH_ADDRESS
=
0x1d44
,
MV_PCI_ERR_ATTRIBUTE
=
0x1d48
,
MV_PCI_ERR_COMMAND
=
0x1d50
,
PCI_IRQ_CAUSE_OFS
=
0x1d58
,
PCI_IRQ_MASK_OFS
=
0x1d5c
,
PCI_UNMASK_ALL_IRQS
=
0x7fffff
,
/* bits 22-0 */
...
...
@@ -153,6 +155,15 @@ enum {
/* SATA registers */
SATA_STATUS_OFS
=
0x300
,
/* ctrl, err regs follow status */
SATA_ACTIVE_OFS
=
0x350
,
PHY_MODE3
=
0x310
,
PHY_MODE4
=
0x314
,
PHY_MODE2
=
0x330
,
MV5_PHY_MODE
=
0x74
,
MV5_LT_MODE
=
0x30
,
MV5_PHY_CTL
=
0x0C
,
SATA_INTERFACE_CTL
=
0x050
,
MV_M2_PREAMP_MASK
=
0x7e0
,
/* Port registers */
EDMA_CFG_OFS
=
0
,
...
...
@@ -192,7 +203,6 @@ enum {
EDMA_REQ_Q_BASE_HI_OFS
=
0x10
,
EDMA_REQ_Q_IN_PTR_OFS
=
0x14
,
/* also contains BASE_LO */
EDMA_REQ_Q_BASE_LO_MASK
=
0xfffffc00U
,
EDMA_REQ_Q_OUT_PTR_OFS
=
0x18
,
EDMA_REQ_Q_PTR_SHIFT
=
5
,
...
...
@@ -200,7 +210,6 @@ enum {
EDMA_RSP_Q_BASE_HI_OFS
=
0x1c
,
EDMA_RSP_Q_IN_PTR_OFS
=
0x20
,
EDMA_RSP_Q_OUT_PTR_OFS
=
0x24
,
/* also contains BASE_LO */
EDMA_RSP_Q_BASE_LO_MASK
=
0xffffff00U
,
EDMA_RSP_Q_PTR_SHIFT
=
3
,
EDMA_CMD_OFS
=
0x28
,
...
...
@@ -208,14 +217,44 @@ enum {
EDMA_DS
=
(
1
<<
1
),
ATA_RST
=
(
1
<<
2
),
EDMA_IORDY_TMOUT
=
0x34
,
EDMA_ARB_CFG
=
0x38
,
/* Host private flags (hp_flags) */
MV_HP_FLAG_MSI
=
(
1
<<
0
),
MV_HP_ERRATA_50XXB0
=
(
1
<<
1
),
MV_HP_ERRATA_50XXB2
=
(
1
<<
2
),
MV_HP_ERRATA_60X1B2
=
(
1
<<
3
),
MV_HP_ERRATA_60X1C0
=
(
1
<<
4
),
MV_HP_50XX
=
(
1
<<
5
),
/* Port private flags (pp_flags) */
MV_PP_FLAG_EDMA_EN
=
(
1
<<
0
),
MV_PP_FLAG_EDMA_DS_ACT
=
(
1
<<
1
),
};
#define IS_50XX(hpriv) ((hpriv)->hp_flags & MV_HP_50XX)
#define IS_60XX(hpriv) (((hpriv)->hp_flags & MV_HP_50XX) == 0)
enum
{
/* Our DMA boundary is determined by an ePRD being unable to handle
* anything larger than 64KB
*/
MV_DMA_BOUNDARY
=
0xffffU
,
EDMA_REQ_Q_BASE_LO_MASK
=
0xfffffc00U
,
EDMA_RSP_Q_BASE_LO_MASK
=
0xffffff00U
,
};
enum
chip_type
{
chip_504x
,
chip_508x
,
chip_5080
,
chip_604x
,
chip_608x
,
};
/* Command ReQuest Block: 32B */
struct
mv_crqb
{
u32
sg_addr
;
...
...
@@ -252,14 +291,37 @@ struct mv_port_priv {
u32
pp_flags
;
};
struct
mv_port_signal
{
u32
amps
;
u32
pre
;
};
struct
mv_host_priv
;
struct
mv_hw_ops
{
void
(
*
phy_errata
)(
struct
mv_host_priv
*
hpriv
,
void
__iomem
*
mmio
,
unsigned
int
port
);
void
(
*
enable_leds
)(
struct
mv_host_priv
*
hpriv
,
void
__iomem
*
mmio
);
void
(
*
read_preamp
)(
struct
mv_host_priv
*
hpriv
,
int
idx
,
void
__iomem
*
mmio
);
int
(
*
reset_hc
)(
struct
mv_host_priv
*
hpriv
,
void
__iomem
*
mmio
,
unsigned
int
n_hc
);
void
(
*
reset_flash
)(
struct
mv_host_priv
*
hpriv
,
void
__iomem
*
mmio
);
void
(
*
reset_bus
)(
struct
pci_dev
*
pdev
,
void
__iomem
*
mmio
);
};
struct
mv_host_priv
{
u32
hp_flags
;
struct
mv_port_signal
signal
[
8
];
const
struct
mv_hw_ops
*
ops
;
};
static
void
mv_irq_clear
(
struct
ata_port
*
ap
);
static
u32
mv_scr_read
(
struct
ata_port
*
ap
,
unsigned
int
sc_reg_in
);
static
void
mv_scr_write
(
struct
ata_port
*
ap
,
unsigned
int
sc_reg_in
,
u32
val
);
static
u32
mv5_scr_read
(
struct
ata_port
*
ap
,
unsigned
int
sc_reg_in
);
static
void
mv5_scr_write
(
struct
ata_port
*
ap
,
unsigned
int
sc_reg_in
,
u32
val
);
static
void
mv_phy_reset
(
struct
ata_port
*
ap
);
static
void
__mv_phy_reset
(
struct
ata_port
*
ap
,
int
can_sleep
);
static
void
mv_host_stop
(
struct
ata_host_set
*
host_set
);
static
int
mv_port_start
(
struct
ata_port
*
ap
);
static
void
mv_port_stop
(
struct
ata_port
*
ap
);
...
...
@@ -270,6 +332,29 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance,
static
void
mv_eng_timeout
(
struct
ata_port
*
ap
);
static
int
mv_init_one
(
struct
pci_dev
*
pdev
,
const
struct
pci_device_id
*
ent
);
static
void
mv5_phy_errata
(
struct
mv_host_priv
*
hpriv
,
void
__iomem
*
mmio
,
unsigned
int
port
);
static
void
mv5_enable_leds
(
struct
mv_host_priv
*
hpriv
,
void
__iomem
*
mmio
);
static
void
mv5_read_preamp
(
struct
mv_host_priv
*
hpriv
,
int
idx
,
void
__iomem
*
mmio
);
static
int
mv5_reset_hc
(
struct
mv_host_priv
*
hpriv
,
void
__iomem
*
mmio
,
unsigned
int
n_hc
);
static
void
mv5_reset_flash
(
struct
mv_host_priv
*
hpriv
,
void
__iomem
*
mmio
);
static
void
mv5_reset_bus
(
struct
pci_dev
*
pdev
,
void
__iomem
*
mmio
);
static
void
mv6_phy_errata
(
struct
mv_host_priv
*
hpriv
,
void
__iomem
*
mmio
,
unsigned
int
port
);
static
void
mv6_enable_leds
(
struct
mv_host_priv
*
hpriv
,
void
__iomem
*
mmio
);
static
void
mv6_read_preamp
(
struct
mv_host_priv
*
hpriv
,
int
idx
,
void
__iomem
*
mmio
);
static
int
mv6_reset_hc
(
struct
mv_host_priv
*
hpriv
,
void
__iomem
*
mmio
,
unsigned
int
n_hc
);
static
void
mv6_reset_flash
(
struct
mv_host_priv
*
hpriv
,
void
__iomem
*
mmio
);
static
void
mv_reset_pci_bus
(
struct
pci_dev
*
pdev
,
void
__iomem
*
mmio
);
static
void
mv_channel_reset
(
struct
mv_host_priv
*
hpriv
,
void
__iomem
*
mmio
,
unsigned
int
port_no
);
static
void
mv_stop_and_reset
(
struct
ata_port
*
ap
);
static
struct
scsi_host_template
mv_sht
=
{
.
module
=
THIS_MODULE
,
.
name
=
DRV_NAME
,
...
...
@@ -278,7 +363,7 @@ static struct scsi_host_template mv_sht = {
.
eh_strategy_handler
=
ata_scsi_error
,
.
can_queue
=
MV_USE_Q_DEPTH
,
.
this_id
=
ATA_SHT_THIS_ID
,
.
sg_tablesize
=
MV_MAX_SG_CT
,
.
sg_tablesize
=
MV_MAX_SG_CT
/
2
,
.
max_sectors
=
ATA_MAX_SECTORS
,
.
cmd_per_lun
=
ATA_SHT_CMD_PER_LUN
,
.
emulated
=
ATA_SHT_EMULATED
,
...
...
@@ -290,7 +375,34 @@ static struct scsi_host_template mv_sht = {
.
ordered_flush
=
1
,
};
static
const
struct
ata_port_operations
mv_ops
=
{
static
const
struct
ata_port_operations
mv5_ops
=
{
.
port_disable
=
ata_port_disable
,
.
tf_load
=
ata_tf_load
,
.
tf_read
=
ata_tf_read
,
.
check_status
=
ata_check_status
,
.
exec_command
=
ata_exec_command
,
.
dev_select
=
ata_std_dev_select
,
.
phy_reset
=
mv_phy_reset
,
.
qc_prep
=
mv_qc_prep
,
.
qc_issue
=
mv_qc_issue
,
.
eng_timeout
=
mv_eng_timeout
,
.
irq_handler
=
mv_interrupt
,
.
irq_clear
=
mv_irq_clear
,
.
scr_read
=
mv5_scr_read
,
.
scr_write
=
mv5_scr_write
,
.
port_start
=
mv_port_start
,
.
port_stop
=
mv_port_stop
,
.
host_stop
=
mv_host_stop
,
};
static
const
struct
ata_port_operations
mv6_ops
=
{
.
port_disable
=
ata_port_disable
,
.
tf_load
=
ata_tf_load
,
...
...
@@ -322,22 +434,29 @@ static struct ata_port_info mv_port_info[] = {
.
sht
=
&
mv_sht
,
.
host_flags
=
MV_COMMON_FLAGS
,
.
pio_mask
=
0x1f
,
/* pio0-4 */
.
udma_mask
=
0
,
/* 0x7f (udma0-6 disabled for now)
*/
.
port_ops
=
&
mv_ops
,
.
udma_mask
=
0
x7f
,
/* udma0-6
*/
.
port_ops
=
&
mv
5
_ops
,
},
{
/* chip_508x */
.
sht
=
&
mv_sht
,
.
host_flags
=
(
MV_COMMON_FLAGS
|
MV_FLAG_DUAL_HC
),
.
pio_mask
=
0x1f
,
/* pio0-4 */
.
udma_mask
=
0
,
/* 0x7f (udma0-6 disabled for now) */
.
port_ops
=
&
mv_ops
,
.
udma_mask
=
0x7f
,
/* udma0-6 */
.
port_ops
=
&
mv5_ops
,
},
{
/* chip_5080 */
.
sht
=
&
mv_sht
,
.
host_flags
=
(
MV_COMMON_FLAGS
|
MV_FLAG_DUAL_HC
),
.
pio_mask
=
0x1f
,
/* pio0-4 */
.
udma_mask
=
0x7f
,
/* udma0-6 */
.
port_ops
=
&
mv5_ops
,
},
{
/* chip_604x */
.
sht
=
&
mv_sht
,
.
host_flags
=
(
MV_COMMON_FLAGS
|
MV_6XXX_FLAGS
),
.
pio_mask
=
0x1f
,
/* pio0-4 */
.
udma_mask
=
0x7f
,
/* udma0-6 */
.
port_ops
=
&
mv_ops
,
.
port_ops
=
&
mv
6
_ops
,
},
{
/* chip_608x */
.
sht
=
&
mv_sht
,
...
...
@@ -345,14 +464,14 @@ static struct ata_port_info mv_port_info[] = {
MV_FLAG_DUAL_HC
),
.
pio_mask
=
0x1f
,
/* pio0-4 */
.
udma_mask
=
0x7f
,
/* udma0-6 */
.
port_ops
=
&
mv_ops
,
.
port_ops
=
&
mv
6
_ops
,
},
};
static
const
struct
pci_device_id
mv_pci_tbl
[]
=
{
{
PCI_DEVICE
(
PCI_VENDOR_ID_MARVELL
,
0x5040
),
0
,
0
,
chip_504x
},
{
PCI_DEVICE
(
PCI_VENDOR_ID_MARVELL
,
0x5041
),
0
,
0
,
chip_504x
},
{
PCI_DEVICE
(
PCI_VENDOR_ID_MARVELL
,
0x5080
),
0
,
0
,
chip_508
x
},
{
PCI_DEVICE
(
PCI_VENDOR_ID_MARVELL
,
0x5080
),
0
,
0
,
chip_508
0
},
{
PCI_DEVICE
(
PCI_VENDOR_ID_MARVELL
,
0x5081
),
0
,
0
,
chip_508x
},
{
PCI_DEVICE
(
PCI_VENDOR_ID_MARVELL
,
0x6040
),
0
,
0
,
chip_604x
},
...
...
@@ -371,6 +490,24 @@ static struct pci_driver mv_pci_driver = {
.
remove
=
ata_pci_remove_one
,
};
static
const
struct
mv_hw_ops
mv5xxx_ops
=
{
.
phy_errata
=
mv5_phy_errata
,
.
enable_leds
=
mv5_enable_leds
,
.
read_preamp
=
mv5_read_preamp
,
.
reset_hc
=
mv5_reset_hc
,
.
reset_flash
=
mv5_reset_flash
,
.
reset_bus
=
mv5_reset_bus
,
};
static
const
struct
mv_hw_ops
mv6xxx_ops
=
{
.
phy_errata
=
mv6_phy_errata
,
.
enable_leds
=
mv6_enable_leds
,
.
read_preamp
=
mv6_read_preamp
,
.
reset_hc
=
mv6_reset_hc
,
.
reset_flash
=
mv6_reset_flash
,
.
reset_bus
=
mv_reset_pci_bus
,
};
/*
* Functions
*/
...
...
@@ -386,11 +523,27 @@ static inline void __iomem *mv_hc_base(void __iomem *base, unsigned int hc)
return
(
base
+
MV_SATAHC0_REG_BASE
+
(
hc
*
MV_SATAHC_REG_SZ
));
}
static
inline
unsigned
int
mv_hc_from_port
(
unsigned
int
port
)
{
return
port
>>
MV_PORT_HC_SHIFT
;
}
static
inline
unsigned
int
mv_hardport_from_port
(
unsigned
int
port
)
{
return
port
&
MV_PORT_MASK
;
}
static
inline
void
__iomem
*
mv_hc_base_from_port
(
void
__iomem
*
base
,
unsigned
int
port
)
{
return
mv_hc_base
(
base
,
mv_hc_from_port
(
port
));
}
static
inline
void
__iomem
*
mv_port_base
(
void
__iomem
*
base
,
unsigned
int
port
)
{
return
(
mv_hc_base
(
base
,
port
>>
MV_PORT_HC_SHIFT
)
+
return
mv_hc_base_from_port
(
base
,
port
)
+
MV_SATAHC_ARBTR_REG_SZ
+
(
(
port
&
MV_PORT_MASK
)
*
MV_PORT_REG_SZ
)
);
(
mv_hardport_from_port
(
port
)
*
MV_PORT_REG_SZ
);
}
static
inline
void
__iomem
*
mv_ap_base
(
struct
ata_port
*
ap
)
...
...
@@ -398,9 +551,9 @@ static inline void __iomem *mv_ap_base(struct ata_port *ap)
return
mv_port_base
(
ap
->
host_set
->
mmio_base
,
ap
->
port_no
);
}
static
inline
int
mv_get_hc_count
(
unsigned
long
h
p
_flags
)
static
inline
int
mv_get_hc_count
(
unsigned
long
h
ost
_flags
)
{
return
((
h
p
_flags
&
MV_FLAG_DUAL_HC
)
?
2
:
1
);
return
((
h
ost
_flags
&
MV_FLAG_DUAL_HC
)
?
2
:
1
);
}
static
void
mv_irq_clear
(
struct
ata_port
*
ap
)
...
...
@@ -584,70 +737,6 @@ static void mv_scr_write(struct ata_port *ap, unsigned int sc_reg_in, u32 val)
}
}
/**
* mv_global_soft_reset - Perform the 6xxx global soft reset
* @mmio_base: base address of the HBA
*
* This routine only applies to 6xxx parts.
*
* LOCKING:
* Inherited from caller.
*/
static
int
mv_global_soft_reset
(
void
__iomem
*
mmio_base
)
{
void
__iomem
*
reg
=
mmio_base
+
PCI_MAIN_CMD_STS_OFS
;
int
i
,
rc
=
0
;
u32
t
;
/* Following procedure defined in PCI "main command and status
* register" table.
*/
t
=
readl
(
reg
);
writel
(
t
|
STOP_PCI_MASTER
,
reg
);
for
(
i
=
0
;
i
<
1000
;
i
++
)
{
udelay
(
1
);
t
=
readl
(
reg
);
if
(
PCI_MASTER_EMPTY
&
t
)
{
break
;
}
}
if
(
!
(
PCI_MASTER_EMPTY
&
t
))
{
printk
(
KERN_ERR
DRV_NAME
": PCI master won't flush
\n
"
);
rc
=
1
;
goto
done
;
}
/* set reset */
i
=
5
;
do
{
writel
(
t
|
GLOB_SFT_RST
,
reg
);
t
=
readl
(
reg
);
udelay
(
1
);
}
while
(
!
(
GLOB_SFT_RST
&
t
)
&&
(
i
--
>
0
));
if
(
!
(
GLOB_SFT_RST
&
t
))
{
printk
(
KERN_ERR
DRV_NAME
": can't set global reset
\n
"
);
rc
=
1
;
goto
done
;
}
/* clear reset and *reenable the PCI master* (not mentioned in spec) */
i
=
5
;
do
{
writel
(
t
&
~
(
GLOB_SFT_RST
|
STOP_PCI_MASTER
),
reg
);
t
=
readl
(
reg
);
udelay
(
1
);
}
while
((
GLOB_SFT_RST
&
t
)
&&
(
i
--
>
0
));
if
(
GLOB_SFT_RST
&
t
)
{
printk
(
KERN_ERR
DRV_NAME
": can't clear global reset
\n
"
);
rc
=
1
;
}
done:
return
rc
;
}
/**
* mv_host_stop - Host specific cleanup/stop routine.
* @host_set: host data structure
...
...
@@ -805,21 +894,31 @@ static void mv_fill_sg(struct ata_queued_cmd *qc)
struct
scatterlist
*
sg
;
ata_for_each_sg
(
sg
,
qc
)
{
u32
sg_len
;
dma_addr_t
addr
;
u32
sg_len
,
len
,
offset
;
addr
=
sg_dma_address
(
sg
);
sg_len
=
sg_dma_len
(
sg
);
while
(
sg_len
)
{
offset
=
addr
&
MV_DMA_BOUNDARY
;
len
=
sg_len
;
if
((
offset
+
sg_len
)
>
0x10000
)
len
=
0x10000
-
offset
;
pp
->
sg_tbl
[
i
].
addr
=
cpu_to_le32
(
addr
&
0xffffffff
);
pp
->
sg_tbl
[
i
].
addr_hi
=
cpu_to_le32
((
addr
>>
16
)
>>
16
);
assert
(
0
==
(
sg_len
&
~
MV_DMA_BOUNDARY
));
pp
->
sg_tbl
[
i
].
flags_size
=
cpu_to_le32
(
sg_len
);
if
(
ata_sg_is_last
(
sg
,
qc
))
pp
->
sg_tbl
[
i
].
flags_size
=
cpu_to_le32
(
len
);
sg_len
-=
len
;
addr
+=
len
;
if
(
!
sg_len
&&
ata_sg_is_last
(
sg
,
qc
))
pp
->
sg_tbl
[
i
].
flags_size
|=
cpu_to_le32
(
EPRD_FLAG_END_OF_TBL
);
i
++
;
}
}
}
static
inline
unsigned
mv_inc_q_index
(
unsigned
*
index
)
...
...
@@ -1055,7 +1154,7 @@ static void mv_err_intr(struct ata_port *ap)
/* check for fatal here and recover if needed */
if
(
EDMA_ERR_FATAL
&
edma_err_cause
)
{
mv_
phy
_reset
(
ap
);
mv_
stop_and
_reset
(
ap
);
}
}
...
...
@@ -1120,6 +1219,10 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant,
handled
++
;
}
if
(
ap
&&
(
ap
->
flags
&
(
ATA_FLAG_PORT_DISABLED
|
ATA_FLAG_NOINTR
)))
continue
;
err_mask
=
ac_err_mask
(
ata_status
);
shift
=
port
<<
1
;
/* (port * 2) */
...
...
@@ -1138,6 +1241,7 @@ static void mv_host_intr(struct ata_host_set *host_set, u32 relevant,
VPRINTK
(
"port %u IRQ found for qc, "
"ata_status 0x%x
\n
"
,
port
,
ata_status
);
/* mark qc status appropriately */
if
(
!
(
qc
->
tf
.
ctl
&
ATA_NIEN
))
ata_qc_complete
(
qc
,
err_mask
);
}
}
...
...
@@ -1202,8 +1306,422 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance,
return
IRQ_RETVAL
(
handled
);
}
static
void
__iomem
*
mv5_phy_base
(
void
__iomem
*
mmio
,
unsigned
int
port
)
{
void
__iomem
*
hc_mmio
=
mv_hc_base_from_port
(
mmio
,
port
);
unsigned
long
ofs
=
(
mv_hardport_from_port
(
port
)
+
1
)
*
0x100UL
;
return
hc_mmio
+
ofs
;
}
static
unsigned
int
mv5_scr_offset
(
unsigned
int
sc_reg_in
)
{
unsigned
int
ofs
;
switch
(
sc_reg_in
)
{
case
SCR_STATUS
:
case
SCR_ERROR
:
case
SCR_CONTROL
:
ofs
=
sc_reg_in
*
sizeof
(
u32
);
break
;
default:
ofs
=
0xffffffffU
;
break
;
}
return
ofs
;
}
static
u32
mv5_scr_read
(
struct
ata_port
*
ap
,
unsigned
int
sc_reg_in
)
{
void
__iomem
*
mmio
=
mv5_phy_base
(
ap
->
host_set
->
mmio_base
,
ap
->
port_no
);
unsigned
int
ofs
=
mv5_scr_offset
(
sc_reg_in
);
if
(
ofs
!=
0xffffffffU
)
return
readl
(
mmio
+
ofs
);
else
return
(
u32
)
ofs
;
}
static
void
mv5_scr_write
(
struct
ata_port
*
ap
,
unsigned
int
sc_reg_in
,
u32
val
)
{
void
__iomem
*
mmio
=
mv5_phy_base
(
ap
->
host_set
->
mmio_base
,
ap
->
port_no
);
unsigned
int
ofs
=
mv5_scr_offset
(
sc_reg_in
);
if
(
ofs
!=
0xffffffffU
)
writelfl
(
val
,
mmio
+
ofs
);
}
static
void
mv5_reset_bus
(
struct
pci_dev
*
pdev
,
void
__iomem
*
mmio
)
{
u8
rev_id
;
int
early_5080
;
pci_read_config_byte
(
pdev
,
PCI_REVISION_ID
,
&
rev_id
);
early_5080
=
(
pdev
->
device
==
0x5080
)
&&
(
rev_id
==
0
);
if
(
!
early_5080
)
{
u32
tmp
=
readl
(
mmio
+
MV_PCI_EXP_ROM_BAR_CTL
);
tmp
|=
(
1
<<
0
);
writel
(
tmp
,
mmio
+
MV_PCI_EXP_ROM_BAR_CTL
);
}
mv_reset_pci_bus
(
pdev
,
mmio
);
}
static
void
mv5_reset_flash
(
struct
mv_host_priv
*
hpriv
,
void
__iomem
*
mmio
)
{
writel
(
0x0fcfffff
,
mmio
+
MV_FLASH_CTL
);
}
static
void
mv5_read_preamp
(
struct
mv_host_priv
*
hpriv
,
int
idx
,
void
__iomem
*
mmio
)
{
void
__iomem
*
phy_mmio
=
mv5_phy_base
(
mmio
,
idx
);
u32
tmp
;
tmp
=
readl
(
phy_mmio
+
MV5_PHY_MODE
);
hpriv
->
signal
[
idx
].
pre
=
tmp
&
0x1800
;
/* bits 12:11 */
hpriv
->
signal
[
idx
].
amps
=
tmp
&
0xe0
;
/* bits 7:5 */
}
static
void
mv5_enable_leds
(
struct
mv_host_priv
*
hpriv
,
void
__iomem
*
mmio
)
{
u32
tmp
;
writel
(
0
,
mmio
+
MV_GPIO_PORT_CTL
);
/* FIXME: handle MV_HP_ERRATA_50XXB2 errata */
tmp
=
readl
(
mmio
+
MV_PCI_EXP_ROM_BAR_CTL
);
tmp
|=
~
(
1
<<
0
);
writel
(
tmp
,
mmio
+
MV_PCI_EXP_ROM_BAR_CTL
);
}
static
void
mv5_phy_errata
(
struct
mv_host_priv
*
hpriv
,
void
__iomem
*
mmio
,
unsigned
int
port
)
{
void
__iomem
*
phy_mmio
=
mv5_phy_base
(
mmio
,
port
);
const
u32
mask
=
(
1
<<
12
)
|
(
1
<<
11
)
|
(
1
<<
7
)
|
(
1
<<
6
)
|
(
1
<<
5
);
u32
tmp
;
int
fix_apm_sq
=
(
hpriv
->
hp_flags
&
MV_HP_ERRATA_50XXB0
);
if
(
fix_apm_sq
)
{
tmp
=
readl
(
phy_mmio
+
MV5_LT_MODE
);
tmp
|=
(
1
<<
19
);
writel
(
tmp
,
phy_mmio
+
MV5_LT_MODE
);
tmp
=
readl
(
phy_mmio
+
MV5_PHY_CTL
);
tmp
&=
~
0x3
;
tmp
|=
0x1
;
writel
(
tmp
,
phy_mmio
+
MV5_PHY_CTL
);
}
tmp
=
readl
(
phy_mmio
+
MV5_PHY_MODE
);
tmp
&=
~
mask
;
tmp
|=
hpriv
->
signal
[
port
].
pre
;
tmp
|=
hpriv
->
signal
[
port
].
amps
;
writel
(
tmp
,
phy_mmio
+
MV5_PHY_MODE
);
}
#undef ZERO
#define ZERO(reg) writel(0, port_mmio + (reg))
static
void
mv5_reset_hc_port
(
struct
mv_host_priv
*
hpriv
,
void
__iomem
*
mmio
,
unsigned
int
port
)
{
void
__iomem
*
port_mmio
=
mv_port_base
(
mmio
,
port
);
writelfl
(
EDMA_DS
,
port_mmio
+
EDMA_CMD_OFS
);
mv_channel_reset
(
hpriv
,
mmio
,
port
);
ZERO
(
0x028
);
/* command */
writel
(
0x11f
,
port_mmio
+
EDMA_CFG_OFS
);
ZERO
(
0x004
);
/* timer */
ZERO
(
0x008
);
/* irq err cause */
ZERO
(
0x00c
);
/* irq err mask */
ZERO
(
0x010
);
/* rq bah */
ZERO
(
0x014
);
/* rq inp */
ZERO
(
0x018
);
/* rq outp */
ZERO
(
0x01c
);
/* respq bah */
ZERO
(
0x024
);
/* respq outp */
ZERO
(
0x020
);
/* respq inp */
ZERO
(
0x02c
);
/* test control */
writel
(
0xbc
,
port_mmio
+
EDMA_IORDY_TMOUT
);
}
#undef ZERO
#define ZERO(reg) writel(0, hc_mmio + (reg))
static
void
mv5_reset_one_hc
(
struct
mv_host_priv
*
hpriv
,
void
__iomem
*
mmio
,
unsigned
int
hc
)
{
void
__iomem
*
hc_mmio
=
mv_hc_base
(
mmio
,
hc
);
u32
tmp
;
ZERO
(
0x00c
);
ZERO
(
0x010
);
ZERO
(
0x014
);
ZERO
(
0x018
);
tmp
=
readl
(
hc_mmio
+
0x20
);
tmp
&=
0x1c1c1c1c
;
tmp
|=
0x03030303
;
writel
(
tmp
,
hc_mmio
+
0x20
);
}
#undef ZERO
static
int
mv5_reset_hc
(
struct
mv_host_priv
*
hpriv
,
void
__iomem
*
mmio
,
unsigned
int
n_hc
)
{
unsigned
int
hc
,
port
;
for
(
hc
=
0
;
hc
<
n_hc
;
hc
++
)
{
for
(
port
=
0
;
port
<
MV_PORTS_PER_HC
;
port
++
)
mv5_reset_hc_port
(
hpriv
,
mmio
,
(
hc
*
MV_PORTS_PER_HC
)
+
port
);
mv5_reset_one_hc
(
hpriv
,
mmio
,
hc
);
}
return
0
;
}
#undef ZERO
#define ZERO(reg) writel(0, mmio + (reg))
static
void
mv_reset_pci_bus
(
struct
pci_dev
*
pdev
,
void
__iomem
*
mmio
)
{
u32
tmp
;
tmp
=
readl
(
mmio
+
MV_PCI_MODE
);
tmp
&=
0xff00ffff
;
writel
(
tmp
,
mmio
+
MV_PCI_MODE
);
ZERO
(
MV_PCI_DISC_TIMER
);
ZERO
(
MV_PCI_MSI_TRIGGER
);
writel
(
0x000100ff
,
mmio
+
MV_PCI_XBAR_TMOUT
);
ZERO
(
HC_MAIN_IRQ_MASK_OFS
);
ZERO
(
MV_PCI_SERR_MASK
);
ZERO
(
PCI_IRQ_CAUSE_OFS
);
ZERO
(
PCI_IRQ_MASK_OFS
);
ZERO
(
MV_PCI_ERR_LOW_ADDRESS
);
ZERO
(
MV_PCI_ERR_HIGH_ADDRESS
);
ZERO
(
MV_PCI_ERR_ATTRIBUTE
);
ZERO
(
MV_PCI_ERR_COMMAND
);
}
#undef ZERO
static
void
mv6_reset_flash
(
struct
mv_host_priv
*
hpriv
,
void
__iomem
*
mmio
)
{
u32
tmp
;
mv5_reset_flash
(
hpriv
,
mmio
);
tmp
=
readl
(
mmio
+
MV_GPIO_PORT_CTL
);
tmp
&=
0x3
;
tmp
|=
(
1
<<
5
)
|
(
1
<<
6
);
writel
(
tmp
,
mmio
+
MV_GPIO_PORT_CTL
);
}
/**
* mv_phy_reset - Perform eDMA reset followed by COMRESET
* mv6_reset_hc - Perform the 6xxx global soft reset
* @mmio: base address of the HBA
*
* This routine only applies to 6xxx parts.
*
* LOCKING:
* Inherited from caller.
*/
static
int
mv6_reset_hc
(
struct
mv_host_priv
*
hpriv
,
void
__iomem
*
mmio
,
unsigned
int
n_hc
)
{
void
__iomem
*
reg
=
mmio
+
PCI_MAIN_CMD_STS_OFS
;
int
i
,
rc
=
0
;
u32
t
;
/* Following procedure defined in PCI "main command and status
* register" table.
*/
t
=
readl
(
reg
);
writel
(
t
|
STOP_PCI_MASTER
,
reg
);
for
(
i
=
0
;
i
<
1000
;
i
++
)
{
udelay
(
1
);
t
=
readl
(
reg
);
if
(
PCI_MASTER_EMPTY
&
t
)
{
break
;
}
}
if
(
!
(
PCI_MASTER_EMPTY
&
t
))
{
printk
(
KERN_ERR
DRV_NAME
": PCI master won't flush
\n
"
);
rc
=
1
;
goto
done
;
}
/* set reset */
i
=
5
;
do
{
writel
(
t
|
GLOB_SFT_RST
,
reg
);
t
=
readl
(
reg
);
udelay
(
1
);
}
while
(
!
(
GLOB_SFT_RST
&
t
)
&&
(
i
--
>
0
));
if
(
!
(
GLOB_SFT_RST
&
t
))
{
printk
(
KERN_ERR
DRV_NAME
": can't set global reset
\n
"
);
rc
=
1
;
goto
done
;
}
/* clear reset and *reenable the PCI master* (not mentioned in spec) */
i
=
5
;
do
{
writel
(
t
&
~
(
GLOB_SFT_RST
|
STOP_PCI_MASTER
),
reg
);
t
=
readl
(
reg
);
udelay
(
1
);
}
while
((
GLOB_SFT_RST
&
t
)
&&
(
i
--
>
0
));
if
(
GLOB_SFT_RST
&
t
)
{
printk
(
KERN_ERR
DRV_NAME
": can't clear global reset
\n
"
);
rc
=
1
;
}
done:
return
rc
;
}
static
void
mv6_read_preamp
(
struct
mv_host_priv
*
hpriv
,
int
idx
,
void
__iomem
*
mmio
)
{
void
__iomem
*
port_mmio
;
u32
tmp
;
tmp
=
readl
(
mmio
+
MV_RESET_CFG
);
if
((
tmp
&
(
1
<<
0
))
==
0
)
{
hpriv
->
signal
[
idx
].
amps
=
0x7
<<
8
;
hpriv
->
signal
[
idx
].
pre
=
0x1
<<
5
;
return
;
}
port_mmio
=
mv_port_base
(
mmio
,
idx
);
tmp
=
readl
(
port_mmio
+
PHY_MODE2
);
hpriv
->
signal
[
idx
].
amps
=
tmp
&
0x700
;
/* bits 10:8 */
hpriv
->
signal
[
idx
].
pre
=
tmp
&
0xe0
;
/* bits 7:5 */
}
static
void
mv6_enable_leds
(
struct
mv_host_priv
*
hpriv
,
void
__iomem
*
mmio
)
{
writel
(
0x00000060
,
mmio
+
MV_GPIO_PORT_CTL
);
}
static
void
mv6_phy_errata
(
struct
mv_host_priv
*
hpriv
,
void
__iomem
*
mmio
,
unsigned
int
port
)
{
void
__iomem
*
port_mmio
=
mv_port_base
(
mmio
,
port
);
u32
hp_flags
=
hpriv
->
hp_flags
;
int
fix_phy_mode2
=
hp_flags
&
(
MV_HP_ERRATA_60X1B2
|
MV_HP_ERRATA_60X1C0
);
int
fix_phy_mode4
=
hp_flags
&
(
MV_HP_ERRATA_60X1B2
|
MV_HP_ERRATA_60X1C0
);
u32
m2
,
tmp
;
if
(
fix_phy_mode2
)
{
m2
=
readl
(
port_mmio
+
PHY_MODE2
);
m2
&=
~
(
1
<<
16
);
m2
|=
(
1
<<
31
);
writel
(
m2
,
port_mmio
+
PHY_MODE2
);
udelay
(
200
);
m2
=
readl
(
port_mmio
+
PHY_MODE2
);
m2
&=
~
((
1
<<
16
)
|
(
1
<<
31
));
writel
(
m2
,
port_mmio
+
PHY_MODE2
);
udelay
(
200
);
}
/* who knows what this magic does */
tmp
=
readl
(
port_mmio
+
PHY_MODE3
);
tmp
&=
~
0x7F800000
;
tmp
|=
0x2A800000
;
writel
(
tmp
,
port_mmio
+
PHY_MODE3
);
if
(
fix_phy_mode4
)
{
u32
m4
;
m4
=
readl
(
port_mmio
+
PHY_MODE4
);
if
(
hp_flags
&
MV_HP_ERRATA_60X1B2
)
tmp
=
readl
(
port_mmio
+
0x310
);
m4
=
(
m4
&
~
(
1
<<
1
))
|
(
1
<<
0
);
writel
(
m4
,
port_mmio
+
PHY_MODE4
);
if
(
hp_flags
&
MV_HP_ERRATA_60X1B2
)
writel
(
tmp
,
port_mmio
+
0x310
);
}
/* Revert values of pre-emphasis and signal amps to the saved ones */
m2
=
readl
(
port_mmio
+
PHY_MODE2
);
m2
&=
~
MV_M2_PREAMP_MASK
;
m2
|=
hpriv
->
signal
[
port
].
amps
;
m2
|=
hpriv
->
signal
[
port
].
pre
;
m2
&=
~
(
1
<<
16
);
writel
(
m2
,
port_mmio
+
PHY_MODE2
);
}
static
void
mv_channel_reset
(
struct
mv_host_priv
*
hpriv
,
void
__iomem
*
mmio
,
unsigned
int
port_no
)
{
void
__iomem
*
port_mmio
=
mv_port_base
(
mmio
,
port_no
);
writelfl
(
ATA_RST
,
port_mmio
+
EDMA_CMD_OFS
);
if
(
IS_60XX
(
hpriv
))
{
u32
ifctl
=
readl
(
port_mmio
+
SATA_INTERFACE_CTL
);
ifctl
|=
(
1
<<
12
)
|
(
1
<<
7
);
writelfl
(
ifctl
,
port_mmio
+
SATA_INTERFACE_CTL
);
}
udelay
(
25
);
/* allow reset propagation */
/* Spec never mentions clearing the bit. Marvell's driver does
* clear the bit, however.
*/
writelfl
(
0
,
port_mmio
+
EDMA_CMD_OFS
);
hpriv
->
ops
->
phy_errata
(
hpriv
,
mmio
,
port_no
);
if
(
IS_50XX
(
hpriv
))
mdelay
(
1
);
}
static
void
mv_stop_and_reset
(
struct
ata_port
*
ap
)
{
struct
mv_host_priv
*
hpriv
=
ap
->
host_set
->
private_data
;
void
__iomem
*
mmio
=
ap
->
host_set
->
mmio_base
;
mv_stop_dma
(
ap
);
mv_channel_reset
(
hpriv
,
mmio
,
ap
->
port_no
);
__mv_phy_reset
(
ap
,
0
);
}
static
inline
void
__msleep
(
unsigned
int
msec
,
int
can_sleep
)
{
if
(
can_sleep
)
msleep
(
msec
);
else
mdelay
(
msec
);
}
/**
* __mv_phy_reset - Perform eDMA reset followed by COMRESET
* @ap: ATA channel to manipulate
*
* Part of this is taken from __sata_phy_reset and modified to
...
...
@@ -1213,41 +1731,47 @@ static irqreturn_t mv_interrupt(int irq, void *dev_instance,
* Inherited from caller. This is coded to safe to call at
* interrupt level, i.e. it does not sleep.
*/
static
void
mv_phy_reset
(
struct
ata_port
*
a
p
)
static
void
__mv_phy_reset
(
struct
ata_port
*
ap
,
int
can_slee
p
)
{
struct
mv_port_priv
*
pp
=
ap
->
private_data
;
struct
mv_host_priv
*
hpriv
=
ap
->
host_set
->
private_data
;
void
__iomem
*
port_mmio
=
mv_ap_base
(
ap
);
struct
ata_taskfile
tf
;
struct
ata_device
*
dev
=
&
ap
->
device
[
0
];
unsigned
long
timeout
;
int
retry
=
5
;
u32
sstatus
;
VPRINTK
(
"ENTER, port %u, mmio 0x%p
\n
"
,
ap
->
port_no
,
port_mmio
);
mv_stop_dma
(
ap
);
writelfl
(
ATA_RST
,
port_mmio
+
EDMA_CMD_OFS
);
udelay
(
25
);
/* allow reset propagation */
/* Spec never mentions clearing the bit. Marvell's driver does
* clear the bit, however.
*/
writelfl
(
0
,
port_mmio
+
EDMA_CMD_OFS
);
VPRINTK
(
"S-regs after ATA_RST: SStat 0x%08x SErr 0x%08x "
DPRINTK
(
"S-regs after ATA_RST: SStat 0x%08x SErr 0x%08x "
"SCtrl 0x%08x
\n
"
,
mv_scr_read
(
ap
,
SCR_STATUS
),
mv_scr_read
(
ap
,
SCR_ERROR
),
mv_scr_read
(
ap
,
SCR_CONTROL
));
/* proceed to init communications via the scr_control reg */
/* Issue COMRESET via SControl */
comreset_retry:
scr_write_flush
(
ap
,
SCR_CONTROL
,
0x301
);
mdelay
(
1
);
__msleep
(
1
,
can_sleep
);
scr_write_flush
(
ap
,
SCR_CONTROL
,
0x300
);
timeout
=
jiffies
+
(
HZ
*
1
);
__msleep
(
20
,
can_sleep
);
timeout
=
jiffies
+
msecs_to_jiffies
(
200
);
do
{
mdelay
(
10
)
;
if
((
s
cr_read
(
ap
,
SCR_STATUS
)
&
0xf
)
!=
1
)
sstatus
=
scr_read
(
ap
,
SCR_STATUS
)
&
0x3
;
if
((
s
status
==
3
)
||
(
sstatus
==
0
)
)
break
;
__msleep
(
1
,
can_sleep
);
}
while
(
time_before
(
jiffies
,
timeout
));
VPRINTK
(
"S-regs after PHY wake: SStat 0x%08x SErr 0x%08x "
/* work around errata */
if
(
IS_60XX
(
hpriv
)
&&
(
sstatus
!=
0x0
)
&&
(
sstatus
!=
0x113
)
&&
(
sstatus
!=
0x123
)
&&
(
retry
--
>
0
))
goto
comreset_retry
;
DPRINTK
(
"S-regs after PHY wake: SStat 0x%08x SErr 0x%08x "
"SCtrl 0x%08x
\n
"
,
mv_scr_read
(
ap
,
SCR_STATUS
),
mv_scr_read
(
ap
,
SCR_ERROR
),
mv_scr_read
(
ap
,
SCR_CONTROL
));
...
...
@@ -1261,6 +1785,21 @@ static void mv_phy_reset(struct ata_port *ap)
}
ap
->
cbl
=
ATA_CBL_SATA
;
/* even after SStatus reflects that device is ready,
* it seems to take a while for link to be fully
* established (and thus Status no longer 0x80/0x7F),
* so we poll a bit for that, here.
*/
retry
=
20
;
while
(
1
)
{
u8
drv_stat
=
ata_check_status
(
ap
);
if
((
drv_stat
!=
0x80
)
&&
(
drv_stat
!=
0x7f
))
break
;
__msleep
(
500
,
can_sleep
);
if
(
retry
--
<=
0
)
break
;
}
tf
.
lbah
=
readb
((
void
__iomem
*
)
ap
->
ioaddr
.
lbah_addr
);
tf
.
lbam
=
readb
((
void
__iomem
*
)
ap
->
ioaddr
.
lbam_addr
);
tf
.
lbal
=
readb
((
void
__iomem
*
)
ap
->
ioaddr
.
lbal_addr
);
...
...
@@ -1271,9 +1810,19 @@ static void mv_phy_reset(struct ata_port *ap)
VPRINTK
(
"Port disabled post-sig: No device present.
\n
"
);
ata_port_disable
(
ap
);
}
writelfl
(
0
,
port_mmio
+
EDMA_ERR_IRQ_CAUSE_OFS
);
pp
->
pp_flags
&=
~
MV_PP_FLAG_EDMA_EN
;
VPRINTK
(
"EXIT
\n
"
);
}
static
void
mv_phy_reset
(
struct
ata_port
*
ap
)
{
__mv_phy_reset
(
ap
,
1
);
}
/**
* mv_eng_timeout - Routine called by libata when SCSI times out I/O
* @ap: ATA channel to manipulate
...
...
@@ -1300,7 +1849,7 @@ static void mv_eng_timeout(struct ata_port *ap)
&
qc
->
scsicmd
->
cmnd
);
mv_err_intr
(
ap
);
mv_
phy
_reset
(
ap
);
mv_
stop_and
_reset
(
ap
);
if
(
!
qc
)
{
printk
(
KERN_ERR
"ata%u: BUG: timeout without command
\n
"
,
...
...
@@ -1368,8 +1917,86 @@ static void mv_port_init(struct ata_ioports *port, void __iomem *port_mmio)
readl
(
port_mmio
+
EDMA_ERR_IRQ_MASK_OFS
));
}
static
int
mv_chip_id
(
struct
pci_dev
*
pdev
,
struct
mv_host_priv
*
hpriv
,
unsigned
int
board_idx
)
{
u8
rev_id
;
u32
hp_flags
=
hpriv
->
hp_flags
;
pci_read_config_byte
(
pdev
,
PCI_REVISION_ID
,
&
rev_id
);
switch
(
board_idx
)
{
case
chip_5080
:
hpriv
->
ops
=
&
mv5xxx_ops
;
hp_flags
|=
MV_HP_50XX
;
switch
(
rev_id
)
{
case
0x1
:
hp_flags
|=
MV_HP_ERRATA_50XXB0
;
break
;
case
0x3
:
hp_flags
|=
MV_HP_ERRATA_50XXB2
;
break
;
default:
dev_printk
(
KERN_WARNING
,
&
pdev
->
dev
,
"Applying 50XXB2 workarounds to unknown rev
\n
"
);
hp_flags
|=
MV_HP_ERRATA_50XXB2
;
break
;
}
break
;
case
chip_504x
:
case
chip_508x
:
hpriv
->
ops
=
&
mv5xxx_ops
;
hp_flags
|=
MV_HP_50XX
;
switch
(
rev_id
)
{
case
0x0
:
hp_flags
|=
MV_HP_ERRATA_50XXB0
;
break
;
case
0x3
:
hp_flags
|=
MV_HP_ERRATA_50XXB2
;
break
;
default:
dev_printk
(
KERN_WARNING
,
&
pdev
->
dev
,
"Applying B2 workarounds to unknown rev
\n
"
);
hp_flags
|=
MV_HP_ERRATA_50XXB2
;
break
;
}
break
;
case
chip_604x
:
case
chip_608x
:
hpriv
->
ops
=
&
mv6xxx_ops
;
switch
(
rev_id
)
{
case
0x7
:
hp_flags
|=
MV_HP_ERRATA_60X1B2
;
break
;
case
0x9
:
hp_flags
|=
MV_HP_ERRATA_60X1C0
;
break
;
default:
dev_printk
(
KERN_WARNING
,
&
pdev
->
dev
,
"Applying B2 workarounds to unknown rev
\n
"
);
hp_flags
|=
MV_HP_ERRATA_60X1B2
;
break
;
}
break
;
default:
printk
(
KERN_ERR
DRV_NAME
": BUG: invalid board index %u
\n
"
,
board_idx
);
return
1
;
}
hpriv
->
hp_flags
=
hp_flags
;
return
0
;
}
/**
* mv_host_init - Perform some early initialization of the host.
* mv_init_host - Perform some early initialization of the host.
* @pdev: host PCI device
* @probe_ent: early data struct representing the host
*
* If possible, do an early global reset of the host. Then do
...
...
@@ -1378,23 +2005,48 @@ static void mv_port_init(struct ata_ioports *port, void __iomem *port_mmio)
* LOCKING:
* Inherited from caller.
*/
static
int
mv_host_init
(
struct
ata_probe_ent
*
probe_ent
)
static
int
mv_init_host
(
struct
pci_dev
*
pdev
,
struct
ata_probe_ent
*
probe_ent
,
unsigned
int
board_idx
)
{
int
rc
=
0
,
n_hc
,
port
,
hc
;
void
__iomem
*
mmio
=
probe_ent
->
mmio_base
;
void
__iomem
*
port_mmio
;
struct
mv_host_priv
*
hpriv
=
probe_ent
->
private_data
;
if
((
MV_FLAG_GLBL_SFT_RST
&
probe_ent
->
host_flags
)
&&
mv_global_soft_reset
(
probe_ent
->
mmio_base
))
{
rc
=
1
;
/* global interrupt mask */
writel
(
0
,
mmio
+
HC_MAIN_IRQ_MASK_OFS
);
rc
=
mv_chip_id
(
pdev
,
hpriv
,
board_idx
);
if
(
rc
)
goto
done
;
}
n_hc
=
mv_get_hc_count
(
probe_ent
->
host_flags
);
probe_ent
->
n_ports
=
MV_PORTS_PER_HC
*
n_hc
;
for
(
port
=
0
;
port
<
probe_ent
->
n_ports
;
port
++
)
hpriv
->
ops
->
read_preamp
(
hpriv
,
port
,
mmio
);
rc
=
hpriv
->
ops
->
reset_hc
(
hpriv
,
mmio
,
n_hc
);
if
(
rc
)
goto
done
;
hpriv
->
ops
->
reset_flash
(
hpriv
,
mmio
);
hpriv
->
ops
->
reset_bus
(
pdev
,
mmio
);
hpriv
->
ops
->
enable_leds
(
hpriv
,
mmio
);
for
(
port
=
0
;
port
<
probe_ent
->
n_ports
;
port
++
)
{
port_mmio
=
mv_port_base
(
mmio
,
port
);
if
(
IS_60XX
(
hpriv
))
{
void
__iomem
*
port_mmio
=
mv_port_base
(
mmio
,
port
);
u32
ifctl
=
readl
(
port_mmio
+
SATA_INTERFACE_CTL
);
ifctl
|=
(
1
<<
12
);
writelfl
(
ifctl
,
port_mmio
+
SATA_INTERFACE_CTL
);
}
hpriv
->
ops
->
phy_errata
(
hpriv
,
mmio
,
port
);
}
for
(
port
=
0
;
port
<
probe_ent
->
n_ports
;
port
++
)
{
void
__iomem
*
port_mmio
=
mv_port_base
(
mmio
,
port
);
mv_port_init
(
&
probe_ent
->
port
[
port
],
port_mmio
);
}
...
...
@@ -1423,6 +2075,7 @@ static int mv_host_init(struct ata_probe_ent *probe_ent)
readl
(
mmio
+
HC_MAIN_IRQ_MASK_OFS
),
readl
(
mmio
+
PCI_IRQ_CAUSE_OFS
),
readl
(
mmio
+
PCI_IRQ_MASK_OFS
));
done:
return
rc
;
}
...
...
@@ -1528,7 +2181,7 @@ static int mv_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
probe_ent
->
private_data
=
hpriv
;
/* initialize adapter */
rc
=
mv_
host_init
(
probe_ent
);
rc
=
mv_
init_host
(
pdev
,
probe_ent
,
board_idx
);
if
(
rc
)
{
goto
err_out_hpriv
;
}
...
...
drivers/scsi/sata_promise.c
View file @
fbf0e134
...
...
@@ -46,7 +46,7 @@
#include "sata_promise.h"
#define DRV_NAME "sata_promise"
#define DRV_VERSION "1.0
2
"
#define DRV_VERSION "1.0
3
"
enum
{
...
...
drivers/scsi/sata_qstor.c
View file @
fbf0e134
...
...
@@ -41,7 +41,7 @@
#include <linux/libata.h>
#define DRV_NAME "sata_qstor"
#define DRV_VERSION "0.0
4
"
#define DRV_VERSION "0.0
5
"
enum
{
QS_PORTS
=
4
,
...
...
drivers/scsi/sata_sil24.c
View file @
fbf0e134
...
...
@@ -139,6 +139,7 @@ enum {
PORT_CS_DEV_RST
=
(
1
<<
1
),
/* device reset */
PORT_CS_INIT
=
(
1
<<
2
),
/* port initialize */
PORT_CS_IRQ_WOC
=
(
1
<<
3
),
/* interrupt write one to clear */
PORT_CS_CDB16
=
(
1
<<
5
),
/* 0=12b cdb, 1=16b cdb */
PORT_CS_RESUME
=
(
1
<<
6
),
/* port resume */
PORT_CS_32BIT_ACTV
=
(
1
<<
10
),
/* 32-bit activation */
PORT_CS_PM_EN
=
(
1
<<
13
),
/* port multiplier enable */
...
...
@@ -188,11 +189,29 @@ enum {
PORT_CERR_XFR_PCIPERR
=
35
,
/* PSD ecode 11 - PCI prity err during transfer */
PORT_CERR_SENDSERVICE
=
36
,
/* FIS received while sending service */
/* bits of PRB control field */
PRB_CTRL_PROTOCOL
=
(
1
<<
0
),
/* override def. ATA protocol */
PRB_CTRL_PACKET_READ
=
(
1
<<
4
),
/* PACKET cmd read */
PRB_CTRL_PACKET_WRITE
=
(
1
<<
5
),
/* PACKET cmd write */
PRB_CTRL_NIEN
=
(
1
<<
6
),
/* Mask completion irq */
PRB_CTRL_SRST
=
(
1
<<
7
),
/* Soft reset request (ign BSY?) */
/* PRB protocol field */
PRB_PROT_PACKET
=
(
1
<<
0
),
PRB_PROT_TCQ
=
(
1
<<
1
),
PRB_PROT_NCQ
=
(
1
<<
2
),
PRB_PROT_READ
=
(
1
<<
3
),
PRB_PROT_WRITE
=
(
1
<<
4
),
PRB_PROT_TRANSPARENT
=
(
1
<<
5
),
/*
* Other constants
*/
SGE_TRM
=
(
1
<<
31
),
/* Last SGE in chain */
PRB_SOFT_RST
=
(
1
<<
7
),
/* Soft reset request (ign BSY?) */
SGE_LNK
=
(
1
<<
30
),
/* linked list
Points to SGT, not SGE */
SGE_DRD
=
(
1
<<
29
),
/* discard data read (/dev/null)
data address ignored */
/* board id */
BID_SIL3124
=
0
,
...
...
drivers/scsi/sata_svw.c
View file @
fbf0e134
...
...
@@ -54,7 +54,7 @@
#endif
/* CONFIG_PPC_OF */
#define DRV_NAME "sata_svw"
#define DRV_VERSION "1.0
6
"
#define DRV_VERSION "1.0
7
"
/* Taskfile registers offsets */
#define K2_SATA_TF_CMD_OFFSET 0x00
...
...
drivers/scsi/sata_sx4.c
View file @
fbf0e134
...
...
@@ -46,7 +46,7 @@
#include "sata_promise.h"
#define DRV_NAME "sata_sx4"
#define DRV_VERSION "0.
7
"
#define DRV_VERSION "0.
8
"
enum
{
...
...
drivers/scsi/sata_vsc.c
View file @
fbf0e134
...
...
@@ -47,7 +47,7 @@
#include <linux/libata.h>
#define DRV_NAME "sata_vsc"
#define DRV_VERSION "1.
0
"
#define DRV_VERSION "1.
1
"
/* Interrupt register offsets (from chip base address) */
#define VSC_SATA_INT_STAT_OFFSET 0x00
...
...
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