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
dc22246b
Commit
dc22246b
authored
Mar 09, 2004
by
Jeff Garzik
Browse files
Options
Browse Files
Download
Plain Diff
Merge redhat.com:/spare/repo/linux-2.5
into redhat.com:/spare/repo/libata-2.5
parents
e88141bd
17049ac0
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
478 additions
and
29 deletions
+478
-29
drivers/scsi/Kconfig
drivers/scsi/Kconfig
+8
-0
drivers/scsi/Makefile
drivers/scsi/Makefile
+1
-0
drivers/scsi/libata-core.c
drivers/scsi/libata-core.c
+34
-20
drivers/scsi/sata_promise.c
drivers/scsi/sata_promise.c
+4
-1
drivers/scsi/sata_sil.c
drivers/scsi/sata_sil.c
+4
-0
drivers/scsi/sata_svw.c
drivers/scsi/sata_svw.c
+7
-4
drivers/scsi/sata_vsc.c
drivers/scsi/sata_vsc.c
+412
-0
include/linux/libata.h
include/linux/libata.h
+8
-4
No files found.
drivers/scsi/Kconfig
View file @
dc22246b
...
...
@@ -438,6 +438,14 @@ config SCSI_SATA_VIA
If unsure, say N.
config SCSI_SATA_VITESSE
tristate "VITESSE VSC-7174 SATA support"
depends on SCSI_SATA && PCI && EXPERIMENTAL
help
This option enables support for Vitesse VSC7174 Serial ATA.
If unsure, say N.
config SCSI_BUSLOGIC
tristate "BusLogic SCSI support"
depends on (PCI || ISA || MCA) && SCSI
...
...
drivers/scsi/Makefile
View file @
dc22246b
...
...
@@ -114,6 +114,7 @@ obj-$(CONFIG_SCSI_ATA_PIIX) += libata.o ata_piix.o
obj-$(CONFIG_SCSI_SATA_PROMISE)
+=
libata.o sata_promise.o
obj-$(CONFIG_SCSI_SATA_SIL)
+=
libata.o sata_sil.o
obj-$(CONFIG_SCSI_SATA_VIA)
+=
libata.o sata_via.o
obj-$(CONFIG_SCSI_SATA_VITESSE)
+=
libata.o sata_vsc.o
obj-$(CONFIG_ARM)
+=
arm/
...
...
drivers/scsi/libata-core.c
View file @
dc22246b
...
...
@@ -141,7 +141,7 @@ void ata_tf_load_pio(struct ata_port *ap, struct ata_taskfile *tf)
}
if
(
is_addr
&&
(
tf
->
flags
&
ATA_TFLAG_LBA48
))
{
outb
(
tf
->
hob_feature
,
ioaddr
->
error
_addr
);
outb
(
tf
->
hob_feature
,
ioaddr
->
feature
_addr
);
outb
(
tf
->
hob_nsect
,
ioaddr
->
nsect_addr
);
outb
(
tf
->
hob_lbal
,
ioaddr
->
lbal_addr
);
outb
(
tf
->
hob_lbam
,
ioaddr
->
lbam_addr
);
...
...
@@ -155,7 +155,7 @@ void ata_tf_load_pio(struct ata_port *ap, struct ata_taskfile *tf)
}
if
(
is_addr
)
{
outb
(
tf
->
feature
,
ioaddr
->
error
_addr
);
outb
(
tf
->
feature
,
ioaddr
->
feature
_addr
);
outb
(
tf
->
nsect
,
ioaddr
->
nsect_addr
);
outb
(
tf
->
lbal
,
ioaddr
->
lbal_addr
);
outb
(
tf
->
lbam
,
ioaddr
->
lbam_addr
);
...
...
@@ -199,7 +199,7 @@ void ata_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf)
}
if
(
is_addr
&&
(
tf
->
flags
&
ATA_TFLAG_LBA48
))
{
writeb
(
tf
->
hob_feature
,
(
void
*
)
ioaddr
->
error
_addr
);
writeb
(
tf
->
hob_feature
,
(
void
*
)
ioaddr
->
feature
_addr
);
writeb
(
tf
->
hob_nsect
,
(
void
*
)
ioaddr
->
nsect_addr
);
writeb
(
tf
->
hob_lbal
,
(
void
*
)
ioaddr
->
lbal_addr
);
writeb
(
tf
->
hob_lbam
,
(
void
*
)
ioaddr
->
lbam_addr
);
...
...
@@ -213,7 +213,7 @@ void ata_tf_load_mmio(struct ata_port *ap, struct ata_taskfile *tf)
}
if
(
is_addr
)
{
writeb
(
tf
->
feature
,
(
void
*
)
ioaddr
->
error
_addr
);
writeb
(
tf
->
feature
,
(
void
*
)
ioaddr
->
feature
_addr
);
writeb
(
tf
->
nsect
,
(
void
*
)
ioaddr
->
nsect_addr
);
writeb
(
tf
->
lbal
,
(
void
*
)
ioaddr
->
lbal_addr
);
writeb
(
tf
->
lbam
,
(
void
*
)
ioaddr
->
lbam_addr
);
...
...
@@ -250,7 +250,7 @@ void ata_exec_command_pio(struct ata_port *ap, struct ata_taskfile *tf)
{
DPRINTK
(
"ata%u: cmd 0x%X
\n
"
,
ap
->
id
,
tf
->
command
);
outb
(
tf
->
command
,
ap
->
ioaddr
.
c
mdstat
_addr
);
outb
(
tf
->
command
,
ap
->
ioaddr
.
c
ommand
_addr
);
ata_pause
(
ap
);
}
...
...
@@ -271,7 +271,7 @@ void ata_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf)
{
DPRINTK
(
"ata%u: cmd 0x%X
\n
"
,
ap
->
id
,
tf
->
command
);
writeb
(
tf
->
command
,
(
void
*
)
ap
->
ioaddr
.
c
mdstat
_addr
);
writeb
(
tf
->
command
,
(
void
*
)
ap
->
ioaddr
.
c
ommand
_addr
);
ata_pause
(
ap
);
}
...
...
@@ -417,7 +417,7 @@ void ata_tf_read_mmio(struct ata_port *ap, struct ata_taskfile *tf)
*/
u8
ata_check_status_pio
(
struct
ata_port
*
ap
)
{
return
inb
(
ap
->
ioaddr
.
cmdstat
_addr
);
return
inb
(
ap
->
ioaddr
.
status
_addr
);
}
/**
...
...
@@ -433,7 +433,7 @@ u8 ata_check_status_pio(struct ata_port *ap)
*/
u8
ata_check_status_mmio
(
struct
ata_port
*
ap
)
{
return
readb
((
void
*
)
ap
->
ioaddr
.
cmdstat
_addr
);
return
readb
((
void
*
)
ap
->
ioaddr
.
status
_addr
);
}
static
const
char
*
udma_str
[]
=
{
...
...
@@ -1346,12 +1346,6 @@ void ata_bus_reset(struct ata_port *ap)
DPRINTK
(
"ENTER, host %u, port %u
\n
"
,
ap
->
id
,
ap
->
port_no
);
/* set up device control */
if
(
ap
->
flags
&
ATA_FLAG_MMIO
)
writeb
(
ap
->
ctl
,
ioaddr
->
ctl_addr
);
else
outb
(
ap
->
ctl
,
ioaddr
->
ctl_addr
);
/* determine if device 0/1 are present */
if
(
ap
->
flags
&
ATA_FLAG_SATA_RESET
)
dev0
=
1
;
...
...
@@ -1372,8 +1366,14 @@ void ata_bus_reset(struct ata_port *ap)
/* issue bus reset */
if
(
ap
->
flags
&
ATA_FLAG_SRST
)
rc
=
ata_bus_softreset
(
ap
,
devmask
);
else
if
((
ap
->
flags
&
ATA_FLAG_SATA_RESET
)
==
0
)
else
if
((
ap
->
flags
&
ATA_FLAG_SATA_RESET
)
==
0
)
{
/* set up device control */
if
(
ap
->
flags
&
ATA_FLAG_MMIO
)
writeb
(
ap
->
ctl
,
ioaddr
->
ctl_addr
);
else
outb
(
ap
->
ctl
,
ioaddr
->
ctl_addr
);
rc
=
ata_bus_edd
(
ap
);
}
if
(
rc
)
goto
err_out
;
...
...
@@ -1399,6 +1399,14 @@ void ata_bus_reset(struct ata_port *ap)
(
ap
->
device
[
1
].
class
==
ATA_DEV_NONE
))
goto
err_out
;
if
(
ap
->
flags
&
(
ATA_FLAG_SATA_RESET
|
ATA_FLAG_SRST
))
{
/* set up device control for ATA_FLAG_SATA_RESET */
if
(
ap
->
flags
&
ATA_FLAG_MMIO
)
writeb
(
ap
->
ctl
,
ioaddr
->
ctl_addr
);
else
outb
(
ap
->
ctl
,
ioaddr
->
ctl_addr
);
}
DPRINTK
(
"EXIT
\n
"
);
return
;
...
...
@@ -2369,8 +2377,8 @@ static void ata_dma_complete(struct ata_port *ap, u8 host_stat,
* One if interrupt was handled, zero if not (shared irq).
*/
static
inline
unsigned
int
ata_host_intr
(
struct
ata_port
*
ap
,
struct
ata_queued_cmd
*
qc
)
inline
unsigned
int
ata_host_intr
(
struct
ata_port
*
ap
,
struct
ata_queued_cmd
*
qc
)
{
u8
status
,
host_stat
;
unsigned
int
handled
=
0
;
...
...
@@ -2728,7 +2736,7 @@ int ata_port_start (struct ata_port *ap)
if
(
!
ap
->
prd
)
return
-
ENOMEM
;
DPRINTK
(
"prd alloc, virt %p, dma %
x
\n
"
,
ap
->
prd
,
ap
->
prd_dma
);
DPRINTK
(
"prd alloc, virt %p, dma %
llx
\n
"
,
ap
->
prd
,
(
unsigned
long
long
)
ap
->
prd_dma
);
return
0
;
}
...
...
@@ -3026,12 +3034,14 @@ void ata_std_ports(struct ata_ioports *ioaddr)
{
ioaddr
->
data_addr
=
ioaddr
->
cmd_addr
+
ATA_REG_DATA
;
ioaddr
->
error_addr
=
ioaddr
->
cmd_addr
+
ATA_REG_ERR
;
ioaddr
->
feature_addr
=
ioaddr
->
cmd_addr
+
ATA_REG_FEATURE
;
ioaddr
->
nsect_addr
=
ioaddr
->
cmd_addr
+
ATA_REG_NSECT
;
ioaddr
->
lbal_addr
=
ioaddr
->
cmd_addr
+
ATA_REG_LBAL
;
ioaddr
->
lbam_addr
=
ioaddr
->
cmd_addr
+
ATA_REG_LBAM
;
ioaddr
->
lbah_addr
=
ioaddr
->
cmd_addr
+
ATA_REG_LBAH
;
ioaddr
->
device_addr
=
ioaddr
->
cmd_addr
+
ATA_REG_DEVICE
;
ioaddr
->
cmdstat_addr
=
ioaddr
->
cmd_addr
+
ATA_REG_CMD
;
ioaddr
->
status_addr
=
ioaddr
->
cmd_addr
+
ATA_REG_STATUS
;
ioaddr
->
command_addr
=
ioaddr
->
cmd_addr
+
ATA_REG_CMD
;
}
/**
...
...
@@ -3153,12 +3163,14 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
if
(
legacy_mode
)
{
probe_ent
->
port
[
0
].
cmd_addr
=
0x1f0
;
probe_ent
->
port
[
0
].
altstatus_addr
=
probe_ent
->
port
[
0
].
ctl_addr
=
0x3f6
;
probe_ent
->
n_ports
=
1
;
probe_ent
->
irq
=
14
;
ata_std_ports
(
&
probe_ent
->
port
[
0
]);
probe_ent2
->
port
[
0
].
cmd_addr
=
0x170
;
probe_ent2
->
port
[
0
].
altstatus_addr
=
probe_ent2
->
port
[
0
].
ctl_addr
=
0x376
;
probe_ent2
->
port
[
0
].
bmdma_addr
=
pci_resource_start
(
pdev
,
4
)
+
8
;
probe_ent2
->
n_ports
=
1
;
...
...
@@ -3173,11 +3185,13 @@ int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_info,
}
else
{
probe_ent
->
port
[
0
].
cmd_addr
=
pci_resource_start
(
pdev
,
0
);
ata_std_ports
(
&
probe_ent
->
port
[
0
]);
probe_ent
->
port
[
0
].
altstatus_addr
=
probe_ent
->
port
[
0
].
ctl_addr
=
pci_resource_start
(
pdev
,
1
)
|
ATA_PCI_CTL_OFS
;
probe_ent
->
port
[
1
].
cmd_addr
=
pci_resource_start
(
pdev
,
2
);
ata_std_ports
(
&
probe_ent
->
port
[
1
]);
probe_ent
->
port
[
1
].
altstatus_addr
=
probe_ent
->
port
[
1
].
ctl_addr
=
pci_resource_start
(
pdev
,
3
)
|
ATA_PCI_CTL_OFS
;
probe_ent
->
port
[
1
].
bmdma_addr
=
pci_resource_start
(
pdev
,
4
)
+
8
;
...
...
@@ -3367,4 +3381,4 @@ EXPORT_SYMBOL_GPL(ata_scsi_queuecmd);
EXPORT_SYMBOL_GPL
(
ata_scsi_error
);
EXPORT_SYMBOL_GPL
(
ata_scsi_slave_config
);
EXPORT_SYMBOL_GPL
(
ata_scsi_release
);
EXPORT_SYMBOL_GPL
(
ata_host_intr
);
drivers/scsi/sata_promise.c
View file @
dc22246b
...
...
@@ -1172,13 +1172,16 @@ static void pdc_sata_setup_port(struct ata_ioports *port, unsigned long base)
{
port
->
cmd_addr
=
base
;
port
->
data_addr
=
base
;
port
->
feature_addr
=
port
->
error_addr
=
base
+
0x4
;
port
->
nsect_addr
=
base
+
0x8
;
port
->
lbal_addr
=
base
+
0xc
;
port
->
lbam_addr
=
base
+
0x10
;
port
->
lbah_addr
=
base
+
0x14
;
port
->
device_addr
=
base
+
0x18
;
port
->
cmdstat_addr
=
base
+
0x1c
;
port
->
command_addr
=
port
->
status_addr
=
base
+
0x1c
;
port
->
altstatus_addr
=
port
->
ctl_addr
=
base
+
0x38
;
}
...
...
drivers/scsi/sata_sil.c
View file @
dc22246b
...
...
@@ -360,12 +360,14 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
base
=
(
unsigned
long
)
mmio_base
;
probe_ent
->
port
[
0
].
cmd_addr
=
base
+
SIL_IDE0_TF
;
probe_ent
->
port
[
0
].
altstatus_addr
=
probe_ent
->
port
[
0
].
ctl_addr
=
base
+
SIL_IDE0_CTL
;
probe_ent
->
port
[
0
].
bmdma_addr
=
base
+
SIL_IDE0_BMDMA
;
probe_ent
->
port
[
0
].
scr_addr
=
base
+
SIL_IDE0_SCR
;
ata_std_ports
(
&
probe_ent
->
port
[
0
]);
probe_ent
->
port
[
1
].
cmd_addr
=
base
+
SIL_IDE1_TF
;
probe_ent
->
port
[
1
].
altstatus_addr
=
probe_ent
->
port
[
1
].
ctl_addr
=
base
+
SIL_IDE1_CTL
;
probe_ent
->
port
[
1
].
bmdma_addr
=
base
+
SIL_IDE1_BMDMA
;
probe_ent
->
port
[
1
].
scr_addr
=
base
+
SIL_IDE1_SCR
;
...
...
@@ -373,12 +375,14 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
if
(
ent
->
driver_data
==
sil_3114
)
{
probe_ent
->
port
[
2
].
cmd_addr
=
base
+
SIL_IDE2_TF
;
probe_ent
->
port
[
2
].
altstatus_addr
=
probe_ent
->
port
[
2
].
ctl_addr
=
base
+
SIL_IDE2_CTL
;
probe_ent
->
port
[
2
].
bmdma_addr
=
base
+
SIL_IDE2_BMDMA
;
probe_ent
->
port
[
2
].
scr_addr
=
base
+
SIL_IDE2_SCR
;
ata_std_ports
(
&
probe_ent
->
port
[
2
]);
probe_ent
->
port
[
3
].
cmd_addr
=
base
+
SIL_IDE3_TF
;
probe_ent
->
port
[
3
].
altstatus_addr
=
probe_ent
->
port
[
3
].
ctl_addr
=
base
+
SIL_IDE3_CTL
;
probe_ent
->
port
[
3
].
bmdma_addr
=
base
+
SIL_IDE3_BMDMA
;
probe_ent
->
port
[
3
].
scr_addr
=
base
+
SIL_IDE3_SCR
;
...
...
drivers/scsi/sata_svw.c
View file @
dc22246b
...
...
@@ -103,13 +103,13 @@ static void k2_sata_tf_load(struct ata_port *ap, struct ata_taskfile *tf)
ata_wait_idle
(
ap
);
}
if
(
is_addr
&&
(
tf
->
flags
&
ATA_TFLAG_LBA48
))
{
writew
(
tf
->
feature
|
(((
u16
)
tf
->
hob_feature
)
<<
8
),
ioaddr
->
error
_addr
);
writew
(
tf
->
feature
|
(((
u16
)
tf
->
hob_feature
)
<<
8
),
ioaddr
->
feature
_addr
);
writew
(
tf
->
nsect
|
(((
u16
)
tf
->
hob_nsect
)
<<
8
),
ioaddr
->
nsect_addr
);
writew
(
tf
->
lbal
|
(((
u16
)
tf
->
hob_lbal
)
<<
8
),
ioaddr
->
lbal_addr
);
writew
(
tf
->
lbam
|
(((
u16
)
tf
->
hob_lbam
)
<<
8
),
ioaddr
->
lbam_addr
);
writew
(
tf
->
lbah
|
(((
u16
)
tf
->
hob_lbah
)
<<
8
),
ioaddr
->
lbah_addr
);
}
else
if
(
is_addr
)
{
writew
(
tf
->
feature
,
ioaddr
->
error
_addr
);
writew
(
tf
->
feature
,
ioaddr
->
feature
_addr
);
writew
(
tf
->
nsect
,
ioaddr
->
nsect_addr
);
writew
(
tf
->
lbal
,
ioaddr
->
lbal_addr
);
writew
(
tf
->
lbam
,
ioaddr
->
lbam_addr
);
...
...
@@ -146,7 +146,7 @@ static void k2_sata_tf_read(struct ata_port *ap, struct ata_taskfile *tf)
static
u8
k2_stat_check_status
(
struct
ata_port
*
ap
)
{
return
readl
((
void
*
)
ap
->
ioaddr
.
cmdstat
_addr
);
return
readl
((
void
*
)
ap
->
ioaddr
.
status
_addr
);
}
static
void
k2_sata_set_piomode
(
struct
ata_port
*
ap
,
struct
ata_device
*
adev
,
...
...
@@ -261,13 +261,16 @@ static void k2_sata_setup_port(struct ata_ioports *port, unsigned long base)
{
port
->
cmd_addr
=
base
+
K2_SATA_TF_CMD_OFFSET
;
port
->
data_addr
=
base
+
K2_SATA_TF_DATA_OFFSET
;
port
->
feature_addr
=
port
->
error_addr
=
base
+
K2_SATA_TF_ERROR_OFFSET
;
port
->
nsect_addr
=
base
+
K2_SATA_TF_NSECT_OFFSET
;
port
->
lbal_addr
=
base
+
K2_SATA_TF_LBAL_OFFSET
;
port
->
lbam_addr
=
base
+
K2_SATA_TF_LBAM_OFFSET
;
port
->
lbah_addr
=
base
+
K2_SATA_TF_LBAH_OFFSET
;
port
->
device_addr
=
base
+
K2_SATA_TF_DEVICE_OFFSET
;
port
->
cmdstat_addr
=
base
+
K2_SATA_TF_CMDSTAT_OFFSET
;
port
->
command_addr
=
port
->
status_addr
=
base
+
K2_SATA_TF_CMDSTAT_OFFSET
;
port
->
altstatus_addr
=
port
->
ctl_addr
=
base
+
K2_SATA_TF_CTL_OFFSET
;
port
->
bmdma_addr
=
base
+
K2_SATA_DMA_CMD_OFFSET
;
port
->
scr_addr
=
base
+
K2_SATA_SCR_STATUS_OFFSET
;
...
...
drivers/scsi/sata_vsc.c
0 → 100644
View file @
dc22246b
/*
* sata_vsc.c - Vitesse VSC7174 4 port DPA SATA
*
* Copyright 2004 SGI
*
* Bits from Jeff Garzik, Copyright RedHat, Inc.
*
* The contents of this file are subject to the Open
* Software License version 1.1 that can be found at
* http://www.opensource.org/licenses/osl-1.1.txt and is included herein
* by reference.
*
* Alternatively, the contents of this file may be used under the terms
* of the GNU General Public License version 2 (the "GPL") as distributed
* in the kernel source COPYING file, in which case the provisions of
* the GPL are applicable instead of the above. If you wish to allow
* the use of your version of this file only under the terms of the
* GPL and not to allow others to use your version of this file under
* the OSL, indicate your decision by deleting the provisions above and
* replace them with the notice and other provisions required by the GPL.
* If you do not delete the provisions above, a recipient may use your
* version of this file under either the OSL or the GPL.
*
*/
#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/blkdev.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include "scsi.h"
#include "hosts.h"
#include <linux/libata.h>
#define DRV_NAME "sata_vsc"
#define DRV_VERSION "0.01"
/* Interrupt register offsets (from chip base address) */
#define VSC_SATA_INT_STAT_OFFSET 0x00
#define VSC_SATA_INT_MASK_OFFSET 0x04
/* Taskfile registers offsets */
#define VSC_SATA_TF_CMD_OFFSET 0x00
#define VSC_SATA_TF_DATA_OFFSET 0x00
#define VSC_SATA_TF_ERROR_OFFSET 0x04
#define VSC_SATA_TF_FEATURE_OFFSET 0x06
#define VSC_SATA_TF_NSECT_OFFSET 0x08
#define VSC_SATA_TF_LBAL_OFFSET 0x0c
#define VSC_SATA_TF_LBAM_OFFSET 0x10
#define VSC_SATA_TF_LBAH_OFFSET 0x14
#define VSC_SATA_TF_DEVICE_OFFSET 0x18
#define VSC_SATA_TF_STATUS_OFFSET 0x1c
#define VSC_SATA_TF_COMMAND_OFFSET 0x1d
#define VSC_SATA_TF_ALTSTATUS_OFFSET 0x28
#define VSC_SATA_TF_CTL_OFFSET 0x29
/* DMA base */
#define VSC_SATA_DMA_CMD_OFFSET 0x70
/* SCRs base */
#define VSC_SATA_SCR_STATUS_OFFSET 0x100
#define VSC_SATA_SCR_ERROR_OFFSET 0x104
#define VSC_SATA_SCR_CONTROL_OFFSET 0x108
/* Port stride */
#define VSC_SATA_PORT_OFFSET 0x200
static
u32
vsc_sata_scr_read
(
struct
ata_port
*
ap
,
unsigned
int
sc_reg
)
{
if
(
sc_reg
>
SCR_CONTROL
)
return
0xffffffffU
;
return
readl
((
void
*
)
ap
->
ioaddr
.
scr_addr
+
(
sc_reg
*
4
));
}
static
void
vsc_sata_scr_write
(
struct
ata_port
*
ap
,
unsigned
int
sc_reg
,
u32
val
)
{
if
(
sc_reg
>
SCR_CONTROL
)
return
;
writel
(
val
,
(
void
*
)
ap
->
ioaddr
.
scr_addr
+
(
sc_reg
*
4
));
}
static
void
vsc_intr_mask_update
(
struct
ata_port
*
ap
,
u8
ctl
)
{
unsigned
long
mask_addr
;
u8
mask
;
mask_addr
=
(
unsigned
long
)
ap
->
host_set
->
mmio_base
+
VSC_SATA_INT_MASK_OFFSET
+
ap
->
port_no
;
mask
=
readb
(
mask_addr
);
if
(
ctl
&
ATA_NIEN
)
mask
|=
0x80
;
else
mask
&=
0x7F
;
writeb
(
mask
,
mask_addr
);
}
static
void
vsc_sata_tf_load
(
struct
ata_port
*
ap
,
struct
ata_taskfile
*
tf
)
{
struct
ata_ioports
*
ioaddr
=
&
ap
->
ioaddr
;
unsigned
int
is_addr
=
tf
->
flags
&
ATA_TFLAG_ISADDR
;
/*
* The only thing the ctl register is used for is SRST.
* That is not enabled or disabled via tf_load.
* However, if ATA_NIEN is changed, then we need to change the interrupt register.
*/
if
((
tf
->
ctl
&
ATA_NIEN
)
!=
(
ap
->
last_ctl
&
ATA_NIEN
))
{
ap
->
last_ctl
=
tf
->
ctl
;
vsc_intr_mask_update
(
ap
,
tf
->
ctl
&
ATA_NIEN
);
}
if
(
is_addr
&&
(
tf
->
flags
&
ATA_TFLAG_LBA48
))
{
writew
(
tf
->
feature
|
(((
u16
)
tf
->
hob_feature
)
<<
8
),
ioaddr
->
feature_addr
);
writew
(
tf
->
nsect
|
(((
u16
)
tf
->
hob_nsect
)
<<
8
),
ioaddr
->
nsect_addr
);
writew
(
tf
->
lbal
|
(((
u16
)
tf
->
hob_lbal
)
<<
8
),
ioaddr
->
lbal_addr
);
writew
(
tf
->
lbam
|
(((
u16
)
tf
->
hob_lbam
)
<<
8
),
ioaddr
->
lbam_addr
);
writew
(
tf
->
lbah
|
(((
u16
)
tf
->
hob_lbah
)
<<
8
),
ioaddr
->
lbah_addr
);
}
else
if
(
is_addr
)
{
writew
(
tf
->
feature
,
ioaddr
->
feature_addr
);
writew
(
tf
->
nsect
,
ioaddr
->
nsect_addr
);
writew
(
tf
->
lbal
,
ioaddr
->
lbal_addr
);
writew
(
tf
->
lbam
,
ioaddr
->
lbam_addr
);
writew
(
tf
->
lbah
,
ioaddr
->
lbah_addr
);
}
if
(
tf
->
flags
&
ATA_TFLAG_DEVICE
)
writeb
(
tf
->
device
,
ioaddr
->
device_addr
);
ata_wait_idle
(
ap
);
}
static
void
vsc_sata_tf_read
(
struct
ata_port
*
ap
,
struct
ata_taskfile
*
tf
)
{
struct
ata_ioports
*
ioaddr
=
&
ap
->
ioaddr
;
u16
nsect
,
lbal
,
lbam
,
lbah
;
nsect
=
tf
->
nsect
=
readw
(
ioaddr
->
nsect_addr
);
lbal
=
tf
->
lbal
=
readw
(
ioaddr
->
lbal_addr
);
lbam
=
tf
->
lbam
=
readw
(
ioaddr
->
lbam_addr
);
lbah
=
tf
->
lbah
=
readw
(
ioaddr
->
lbah_addr
);
tf
->
device
=
readw
(
ioaddr
->
device_addr
);
if
(
tf
->
flags
&
ATA_TFLAG_LBA48
)
{
tf
->
hob_feature
=
readb
(
ioaddr
->
error_addr
);
tf
->
hob_nsect
=
nsect
>>
8
;
tf
->
hob_lbal
=
lbal
>>
8
;
tf
->
hob_lbam
=
lbam
>>
8
;
tf
->
hob_lbah
=
lbah
>>
8
;
}
}
static
void
vsc_sata_set_piomode
(
struct
ata_port
*
ap
,
struct
ata_device
*
adev
,
unsigned
int
pio
)
{
/* We need empty implementation, the core doesn't test for NULL
* function pointer
*/
}
static
void
vsc_sata_set_udmamode
(
struct
ata_port
*
ap
,
struct
ata_device
*
adev
,
unsigned
int
udma
)
{
/* We need empty implementation, the core doesn't test for NULL
* function pointer
*/
}
/*
* vsc_sata_interrupt
*
* Read the interrupt register and process for the devices that have them pending.
*/
irqreturn_t
vsc_sata_interrupt
(
int
irq
,
void
*
dev_instance
,
struct
pt_regs
*
regs
)
{
struct
ata_host_set
*
host_set
=
dev_instance
;
unsigned
int
i
;
unsigned
int
handled
=
0
;
u32
int_status
;
spin_lock
(
&
host_set
->
lock
);
int_status
=
readl
(
host_set
->
mmio_base
+
VSC_SATA_INT_STAT_OFFSET
);
for
(
i
=
0
;
i
<
host_set
->
n_ports
;
i
++
)
{
if
(
int_status
&
((
u32
)
0xFF
<<
(
8
*
i
)))
{
struct
ata_port
*
ap
;
ap
=
host_set
->
ports
[
i
];
if
(
ap
&&
(
!
(
ap
->
flags
&
ATA_FLAG_PORT_DISABLED
)))
{
struct
ata_queued_cmd
*
qc
;
qc
=
ata_qc_from_tag
(
ap
,
ap
->
active_tag
);
if
(
qc
&&
((
qc
->
flags
&
ATA_QCFLAG_POLL
)
==
0
))
handled
+=
ata_host_intr
(
ap
,
qc
);
}
}
}
spin_unlock
(
&
host_set
->
lock
);
return
IRQ_RETVAL
(
handled
);
}
static
Scsi_Host_Template
vsc_sata_sht
=
{
.
module
=
THIS_MODULE
,
.
name
=
DRV_NAME
,
.
queuecommand
=
ata_scsi_queuecmd
,
.
eh_strategy_handler
=
ata_scsi_error
,
.
can_queue
=
ATA_DEF_QUEUE
,
.
this_id
=
ATA_SHT_THIS_ID
,
.
sg_tablesize
=
LIBATA_MAX_PRD
,
.
max_sectors
=
ATA_MAX_SECTORS
,
.
cmd_per_lun
=
ATA_SHT_CMD_PER_LUN
,
.
emulated
=
ATA_SHT_EMULATED
,
.
use_clustering
=
ATA_SHT_USE_CLUSTERING
,
.
proc_name
=
DRV_NAME
,
.
dma_boundary
=
ATA_DMA_BOUNDARY
,
.
slave_configure
=
ata_scsi_slave_config
,
.
bios_param
=
ata_std_bios_param
,
};
static
struct
ata_port_operations
vsc_sata_ops
=
{
.
port_disable
=
ata_port_disable
,
.
set_piomode
=
vsc_sata_set_piomode
,
.
set_udmamode
=
vsc_sata_set_udmamode
,
.
tf_load
=
vsc_sata_tf_load
,
.
tf_read
=
vsc_sata_tf_read
,
.
exec_command
=
ata_exec_command_mmio
,
.
check_status
=
ata_check_status_mmio
,
.
phy_reset
=
sata_phy_reset
,
.
phy_config
=
pata_phy_config
,
/* not a typo */
.
bmdma_start
=
ata_bmdma_start_mmio
,
.
fill_sg
=
ata_fill_sg
,
.
eng_timeout
=
ata_eng_timeout
,
.
irq_handler
=
vsc_sata_interrupt
,
.
scr_read
=
vsc_sata_scr_read
,
.
scr_write
=
vsc_sata_scr_write
,
.
port_start
=
ata_port_start
,
.
port_stop
=
ata_port_stop
,
};
static
void
vsc_sata_setup_port
(
struct
ata_ioports
*
port
,
unsigned
long
base
)
{
port
->
cmd_addr
=
base
+
VSC_SATA_TF_CMD_OFFSET
;
port
->
data_addr
=
base
+
VSC_SATA_TF_DATA_OFFSET
;
port
->
error_addr
=
base
+
VSC_SATA_TF_ERROR_OFFSET
;
port
->
feature_addr
=
base
+
VSC_SATA_TF_FEATURE_OFFSET
;
port
->
nsect_addr
=
base
+
VSC_SATA_TF_NSECT_OFFSET
;
port
->
lbal_addr
=
base
+
VSC_SATA_TF_LBAL_OFFSET
;
port
->
lbam_addr
=
base
+
VSC_SATA_TF_LBAM_OFFSET
;
port
->
lbah_addr
=
base
+
VSC_SATA_TF_LBAH_OFFSET
;
port
->
device_addr
=
base
+
VSC_SATA_TF_DEVICE_OFFSET
;
port
->
status_addr
=
base
+
VSC_SATA_TF_STATUS_OFFSET
;
port
->
command_addr
=
base
+
VSC_SATA_TF_COMMAND_OFFSET
;
port
->
altstatus_addr
=
base
+
VSC_SATA_TF_ALTSTATUS_OFFSET
;
port
->
ctl_addr
=
base
+
VSC_SATA_TF_CTL_OFFSET
;
port
->
bmdma_addr
=
base
+
VSC_SATA_DMA_CMD_OFFSET
;
port
->
scr_addr
=
base
+
VSC_SATA_SCR_STATUS_OFFSET
;
}
static
int
vsc_sata_init_one
(
struct
pci_dev
*
pdev
,
const
struct
pci_device_id
*
ent
)
{
static
int
printed_version
;
struct
ata_probe_ent
*
probe_ent
=
NULL
;
unsigned
long
base
;
void
*
mmio_base
;
int
rc
;
if
(
!
printed_version
++
)
printk
(
KERN_DEBUG
DRV_NAME
" version "
DRV_VERSION
"
\n
"
);
rc
=
pci_enable_device
(
pdev
);
if
(
rc
)
return
rc
;
/*
* Check if we have needed resource mapped.
*/
if
(
pci_resource_len
(
pdev
,
0
)
==
0
)
{
rc
=
-
ENODEV
;
goto
err_out
;
}
rc
=
pci_request_regions
(
pdev
,
DRV_NAME
);
if
(
rc
)
goto
err_out
;
/*
* Use 32 bit DMA mask, because 64 bit address support is poor.
*/
rc
=
pci_set_dma_mask
(
pdev
,
0xFFFFFFFF
);
if
(
rc
)
goto
err_out_regions
;
rc
=
pci_set_consistent_dma_mask
(
pdev
,
0xFFFFFFFF
);
if
(
rc
)
goto
err_out_regions
;
probe_ent
=
kmalloc
(
sizeof
(
*
probe_ent
),
GFP_KERNEL
);
if
(
probe_ent
==
NULL
)
{
rc
=
-
ENOMEM
;
goto
err_out_regions
;
}
memset
(
probe_ent
,
0
,
sizeof
(
*
probe_ent
));
probe_ent
->
pdev
=
pdev
;
INIT_LIST_HEAD
(
&
probe_ent
->
node
);
mmio_base
=
ioremap
(
pci_resource_start
(
pdev
,
0
),
pci_resource_len
(
pdev
,
0
));
if
(
mmio_base
==
NULL
)
{
rc
=
-
ENOMEM
;
goto
err_out_free_ent
;
}
base
=
(
unsigned
long
)
mmio_base
;
/*
* Due to a bug in the chip, the default cache line size can't be used
*/
pci_write_config_byte
(
pdev
,
PCI_CACHE_LINE_SIZE
,
0x80
);
probe_ent
->
sht
=
&
vsc_sata_sht
;
probe_ent
->
host_flags
=
ATA_FLAG_SATA
|
ATA_FLAG_NO_LEGACY
|
ATA_FLAG_MMIO
|
ATA_FLAG_SATA_RESET
;
probe_ent
->
port_ops
=
&
vsc_sata_ops
;
probe_ent
->
n_ports
=
4
;
probe_ent
->
irq
=
pdev
->
irq
;
probe_ent
->
irq_flags
=
SA_SHIRQ
;
probe_ent
->
mmio_base
=
mmio_base
;
/* We don't care much about the PIO/UDMA masks, but the core won't like us
* if we don't fill these
*/
probe_ent
->
pio_mask
=
0x1f
;
probe_ent
->
udma_mask
=
0x3f
;
/* We have 4 ports per PCI function */
vsc_sata_setup_port
(
&
probe_ent
->
port
[
0
],
base
+
1
*
VSC_SATA_PORT_OFFSET
);
vsc_sata_setup_port
(
&
probe_ent
->
port
[
1
],
base
+
2
*
VSC_SATA_PORT_OFFSET
);
vsc_sata_setup_port
(
&
probe_ent
->
port
[
2
],
base
+
3
*
VSC_SATA_PORT_OFFSET
);
vsc_sata_setup_port
(
&
probe_ent
->
port
[
3
],
base
+
4
*
VSC_SATA_PORT_OFFSET
);
pci_set_master
(
pdev
);
/* FIXME: check ata_device_add return value */
ata_device_add
(
probe_ent
);
kfree
(
probe_ent
);
return
0
;
err_out_free_ent:
kfree
(
probe_ent
);
err_out_regions:
pci_release_regions
(
pdev
);
err_out:
pci_disable_device
(
pdev
);
return
rc
;
}
static
struct
pci_device_id
vsc_sata_pci_tbl
[]
=
{
{
0x1725
,
0x7174
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0x10600
,
0xFFFFFF
,
0
},
{
0x8086
,
0x3200
,
PCI_ANY_ID
,
PCI_ANY_ID
,
0x10600
,
0xFFFFFF
,
0
},
{
}
};
static
struct
pci_driver
vsc_sata_pci_driver
=
{
.
name
=
DRV_NAME
,
.
id_table
=
vsc_sata_pci_tbl
,
.
probe
=
vsc_sata_init_one
,
.
remove
=
ata_pci_remove_one
,
};
static
int
__init
vsc_sata_init
(
void
)
{
int
rc
;
rc
=
pci_module_init
(
&
vsc_sata_pci_driver
);
if
(
rc
)
return
rc
;
return
0
;
}
static
void
__exit
vsc_sata_exit
(
void
)
{
pci_unregister_driver
(
&
vsc_sata_pci_driver
);
}
MODULE_AUTHOR
(
"Jeremy Higdon"
);
MODULE_DESCRIPTION
(
"low-level driver for Vitesse VSC7174 SATA controller"
);
MODULE_LICENSE
(
"GPL"
);
MODULE_DEVICE_TABLE
(
pci
,
vsc_sata_pci_tbl
);
module_init
(
vsc_sata_init
);
module_exit
(
vsc_sata_exit
);
include/linux/libata.h
View file @
dc22246b
...
...
@@ -183,12 +183,15 @@ struct ata_ioports {
unsigned
long
cmd_addr
;
unsigned
long
data_addr
;
unsigned
long
error_addr
;
unsigned
long
feature_addr
;
unsigned
long
nsect_addr
;
unsigned
long
lbal_addr
;
unsigned
long
lbam_addr
;
unsigned
long
lbah_addr
;
unsigned
long
device_addr
;
unsigned
long
cmdstat_addr
;
unsigned
long
status_addr
;
unsigned
long
command_addr
;
unsigned
long
altstatus_addr
;
unsigned
long
ctl_addr
;
unsigned
long
bmdma_addr
;
unsigned
long
scr_addr
;
...
...
@@ -408,6 +411,7 @@ extern int ata_scsi_queuecmd(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmn
extern
int
ata_scsi_error
(
struct
Scsi_Host
*
host
);
extern
int
ata_scsi_release
(
struct
Scsi_Host
*
host
);
extern
int
ata_scsi_slave_config
(
struct
scsi_device
*
sdev
);
extern
inline
unsigned
int
ata_host_intr
(
struct
ata_port
*
ap
,
struct
ata_queued_cmd
*
qc
);
/*
* Default driver ops implementations
*/
...
...
@@ -465,8 +469,8 @@ static inline u8 ata_chk_status(struct ata_port *ap)
static
inline
u8
ata_altstatus
(
struct
ata_port
*
ap
)
{
if
(
ap
->
flags
&
ATA_FLAG_MMIO
)
return
readb
(
ap
->
ioaddr
.
ctl
_addr
);
return
inb
(
ap
->
ioaddr
.
ctl
_addr
);
return
readb
(
ap
->
ioaddr
.
altstatus
_addr
);
return
inb
(
ap
->
ioaddr
.
altstatus
_addr
);
}
static
inline
void
ata_pause
(
struct
ata_port
*
ap
)
...
...
@@ -494,7 +498,7 @@ static inline u8 ata_wait_idle(struct ata_port *ap)
u8
status
=
ata_busy_wait
(
ap
,
ATA_BUSY
|
ATA_DRQ
,
1000
);
if
(
status
&
(
ATA_BUSY
|
ATA_DRQ
))
{
unsigned
long
l
=
ap
->
ioaddr
.
cmdstat
_addr
;
unsigned
long
l
=
ap
->
ioaddr
.
status
_addr
;
printk
(
KERN_WARNING
"ATA: abnormal status 0x%X on port 0x%lX
\n
"
,
status
,
l
);
...
...
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