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
e241138a
Commit
e241138a
authored
Dec 28, 2003
by
Linus Torvalds
Browse files
Options
Browse Files
Download
Plain Diff
Merge
bk://gkernel.bkbits.net/libata-2.5
into home.osdl.org:/home/torvalds/v2.5/linux
parents
7629bad2
a76a8a35
Changes
9
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
582 additions
and
102 deletions
+582
-102
drivers/scsi/ata_piix.c
drivers/scsi/ata_piix.c
+1
-0
drivers/scsi/libata-core.c
drivers/scsi/libata-core.c
+17
-19
drivers/scsi/libata-scsi.c
drivers/scsi/libata-scsi.c
+33
-10
drivers/scsi/libata.h
drivers/scsi/libata.h
+7
-7
drivers/scsi/sata_promise.c
drivers/scsi/sata_promise.c
+513
-61
drivers/scsi/sata_sil.c
drivers/scsi/sata_sil.c
+1
-0
drivers/scsi/sata_svw.c
drivers/scsi/sata_svw.c
+1
-0
drivers/scsi/sata_via.c
drivers/scsi/sata_via.c
+1
-0
include/linux/libata.h
include/linux/libata.h
+8
-5
No files found.
drivers/scsi/ata_piix.c
View file @
e241138a
...
...
@@ -97,6 +97,7 @@ static Scsi_Host_Template piix_sht = {
.
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
piix_pata_ops
=
{
...
...
drivers/scsi/libata-core.c
View file @
e241138a
...
...
@@ -1619,7 +1619,7 @@ static void ata_dev_set_pio(struct ata_port *ap, unsigned int device)
static
void
ata_sg_clean
(
struct
ata_queued_cmd
*
qc
)
{
struct
ata_port
*
ap
=
qc
->
ap
;
Scsi_C
mnd
*
cmd
=
qc
->
scsicmd
;
struct
scsi_c
mnd
*
cmd
=
qc
->
scsicmd
;
struct
scatterlist
*
sg
=
qc
->
sg
;
int
dir
=
scsi_to_pci_dma_dir
(
cmd
->
sc_data_direction
);
...
...
@@ -1635,8 +1635,8 @@ static void ata_sg_clean(struct ata_queued_cmd *qc)
if
(
cmd
->
use_sg
)
pci_unmap_sg
(
ap
->
host_set
->
pdev
,
sg
,
qc
->
n_elem
,
dir
);
else
pci_unmap_single
(
ap
->
host_set
->
pdev
,
sg
[
0
].
dma_address
,
sg
[
0
].
length
,
dir
);
pci_unmap_single
(
ap
->
host_set
->
pdev
,
sg
_dma_address
(
&
sg
[
0
])
,
sg
_dma_len
(
&
sg
[
0
])
,
dir
);
qc
->
flags
&=
~
ATA_QCFLAG_SG
;
qc
->
sg
=
NULL
;
...
...
@@ -1659,8 +1659,8 @@ void ata_fill_sg(struct ata_queued_cmd *qc)
assert
(
qc
->
n_elem
>
0
);
for
(
i
=
0
;
i
<
qc
->
n_elem
;
i
++
)
{
ap
->
prd
[
i
].
addr
=
cpu_to_le32
(
sg
[
i
].
dma_address
);
ap
->
prd
[
i
].
flags_len
=
cpu_to_le32
(
sg
[
i
].
length
);
ap
->
prd
[
i
].
addr
=
cpu_to_le32
(
sg
_dma_address
(
&
sg
[
i
])
);
ap
->
prd
[
i
].
flags_len
=
cpu_to_le32
(
sg
_dma_len
(
&
sg
[
i
])
);
VPRINTK
(
"PRD[%u] = (0x%X, 0x%X)
\n
"
,
i
,
le32_to_cpu
(
ap
->
prd
[
i
].
addr
),
le32_to_cpu
(
ap
->
prd
[
i
].
flags_len
));
}
...
...
@@ -1681,7 +1681,7 @@ void ata_fill_sg(struct ata_queued_cmd *qc)
static
int
ata_sg_setup_one
(
struct
ata_queued_cmd
*
qc
)
{
struct
ata_port
*
ap
=
qc
->
ap
;
Scsi_C
mnd
*
cmd
=
qc
->
scsicmd
;
struct
scsi_c
mnd
*
cmd
=
qc
->
scsicmd
;
int
dir
=
scsi_to_pci_dma_dir
(
cmd
->
sc_data_direction
);
struct
scatterlist
*
sg
=
qc
->
sg
;
unsigned
int
have_sg
=
(
qc
->
flags
&
ATA_QCFLAG_SG
);
...
...
@@ -1691,12 +1691,12 @@ static int ata_sg_setup_one(struct ata_queued_cmd *qc)
sg
->
page
=
virt_to_page
(
cmd
->
request_buffer
);
sg
->
offset
=
(
unsigned
long
)
cmd
->
request_buffer
&
~
PAGE_MASK
;
sg
->
length
=
cmd
->
request_bufflen
;
sg
_dma_len
(
sg
)
=
cmd
->
request_bufflen
;
if
(
!
have_sg
)
return
0
;
sg
->
dma_address
=
pci_map_single
(
ap
->
host_set
->
pdev
,
sg
_dma_address
(
sg
)
=
pci_map_single
(
ap
->
host_set
->
pdev
,
cmd
->
request_buffer
,
cmd
->
request_bufflen
,
dir
);
...
...
@@ -1720,7 +1720,7 @@ static int ata_sg_setup_one(struct ata_queued_cmd *qc)
static
int
ata_sg_setup
(
struct
ata_queued_cmd
*
qc
)
{
struct
ata_port
*
ap
=
qc
->
ap
;
Scsi_C
mnd
*
cmd
=
qc
->
scsicmd
;
struct
scsi_c
mnd
*
cmd
=
qc
->
scsicmd
;
struct
scatterlist
*
sg
;
int
n_elem
;
unsigned
int
have_sg
=
(
qc
->
flags
&
ATA_QCFLAG_SG
);
...
...
@@ -1872,7 +1872,7 @@ static void ata_pio_sector(struct ata_port *ap)
{
struct
ata_queued_cmd
*
qc
;
struct
scatterlist
*
sg
;
Scsi_C
mnd
*
cmd
;
struct
scsi_c
mnd
*
cmd
;
unsigned
char
*
buf
;
u8
status
;
...
...
@@ -1917,7 +1917,7 @@ static void ata_pio_sector(struct ata_port *ap)
qc
->
cursg_ofs
++
;
if
(
cmd
->
use_sg
)
if
((
qc
->
cursg_ofs
*
ATA_SECT_SIZE
)
==
sg
[
qc
->
cursg
].
length
)
{
if
((
qc
->
cursg_ofs
*
ATA_SECT_SIZE
)
==
sg
_dma_len
(
&
sg
[
qc
->
cursg
])
)
{
qc
->
cursg
++
;
qc
->
cursg_ofs
=
0
;
}
...
...
@@ -2092,7 +2092,7 @@ struct ata_queued_cmd *ata_qc_new_init(struct ata_port *ap,
void
ata_qc_complete
(
struct
ata_queued_cmd
*
qc
,
u8
drv_stat
,
unsigned
int
done_late
)
{
struct
ata_port
*
ap
=
qc
->
ap
;
Scsi_C
mnd
*
cmd
=
qc
->
scsicmd
;
struct
scsi_c
mnd
*
cmd
=
qc
->
scsicmd
;
unsigned
int
tag
,
do_clear
=
0
;
assert
(
qc
!=
NULL
);
/* ata_qc_from_tag _might_ return NULL */
...
...
@@ -2163,7 +2163,7 @@ static void ata_qc_push (struct ata_queued_cmd *qc, unsigned int append)
int
ata_qc_issue
(
struct
ata_queued_cmd
*
qc
)
{
struct
ata_port
*
ap
=
qc
->
ap
;
Scsi_C
mnd
*
cmd
=
qc
->
scsicmd
;
struct
scsi_c
mnd
*
cmd
=
qc
->
scsicmd
;
unsigned
int
dma
=
qc
->
flags
&
ATA_QCFLAG_DMA
;
ata_dev_select
(
ap
,
qc
->
dev
->
devno
,
1
,
0
);
...
...
@@ -2719,7 +2719,7 @@ static void ata_host_remove(struct ata_port *ap, unsigned int do_unregister)
DPRINTK
(
"ENTER
\n
"
);
if
(
do_unregister
)
scsi_remove_host
(
sh
);
/* FIXME: check return val */
scsi_remove_host
(
sh
);
ata_thread_kill
(
ap
);
/* FIXME: check return val */
...
...
@@ -3204,7 +3204,6 @@ void ata_pci_remove_one (struct pci_dev *pdev)
for
(
i
=
0
;
i
<
host_set
->
n_ports
;
i
++
)
{
ap
=
host_set
->
ports
[
i
];
/* FIXME: check return val */
scsi_remove_host
(
ap
->
host
);
}
...
...
@@ -3215,13 +3214,10 @@ void ata_pci_remove_one (struct pci_dev *pdev)
host_set
->
ports
[
0
]
->
ops
->
host_stop
(
host_set
);
for
(
i
=
0
;
i
<
host_set
->
n_ports
;
i
++
)
{
Scsi_Host_Template
*
sht
;
ap
=
host_set
->
ports
[
i
];
sht
=
ap
->
host
->
hostt
;
ata_scsi_release
(
ap
->
host
);
scsi_host_put
(
ap
->
host
);
/* FIXME: check return val */
scsi_host_put
(
ap
->
host
);
}
pci_release_regions
(
pdev
);
...
...
@@ -3279,6 +3275,7 @@ int pci_test_config_bits(struct pci_dev *pdev, struct pci_bits *bits)
return
(
tmp
==
bits
->
val
)
?
1
:
0
;
}
/**
* ata_init -
*
...
...
@@ -3304,6 +3301,7 @@ module_init(ata_init);
*/
EXPORT_SYMBOL_GPL
(
pci_test_config_bits
);
EXPORT_SYMBOL_GPL
(
ata_std_bios_param
);
EXPORT_SYMBOL_GPL
(
ata_std_ports
);
EXPORT_SYMBOL_GPL
(
ata_device_add
);
EXPORT_SYMBOL_GPL
(
ata_qc_complete
);
...
...
drivers/scsi/libata-scsi.c
View file @
e241138a
...
...
@@ -32,10 +32,33 @@
#include "libata.h"
/**
* ata_std_bios_param - generic bios head/sector/cylinder calculator
* used by sd. Most BIOSes nowadays expect a XXX/255/16 (CHS)
* mapping. Some situations may arise where the disk is not
* bootable if this is not used.
*
* LOCKING:
*
* RETURNS:
*
*/
int
ata_std_bios_param
(
struct
scsi_device
*
sdev
,
struct
block_device
*
bdev
,
sector_t
capacity
,
int
geom
[])
{
geom
[
0
]
=
255
;
geom
[
1
]
=
63
;
geom
[
2
]
=
capacity
/
(
geom
[
0
]
*
geom
[
1
]);
return
0
;
}
struct
ata_queued_cmd
*
ata_scsi_qc_new
(
struct
ata_port
*
ap
,
struct
ata_device
*
dev
,
Scsi_C
mnd
*
cmd
,
void
(
*
done
)(
Scsi_C
mnd
*
))
struct
scsi_c
mnd
*
cmd
,
void
(
*
done
)(
struct
scsi_c
mnd
*
))
{
struct
ata_queued_cmd
*
qc
;
...
...
@@ -69,7 +92,7 @@ struct ata_queued_cmd *ata_scsi_qc_new(struct ata_port *ap,
void
ata_to_sense_error
(
struct
ata_queued_cmd
*
qc
)
{
Scsi_C
mnd
*
cmd
=
qc
->
scsicmd
;
struct
scsi_c
mnd
*
cmd
=
qc
->
scsicmd
;
cmd
->
result
=
SAM_STAT_CHECK_CONDITION
;
...
...
@@ -282,7 +305,7 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, u8 *scsicmd,
*/
void
ata_scsi_rw_queue
(
struct
ata_port
*
ap
,
struct
ata_device
*
dev
,
Scsi_Cmnd
*
cmd
,
void
(
*
done
)(
Scsi_C
mnd
*
),
struct
scsi_cmnd
*
cmd
,
void
(
*
done
)(
struct
scsi_c
mnd
*
),
unsigned
int
cmd_size
)
{
struct
ata_queued_cmd
*
qc
;
...
...
@@ -332,7 +355,7 @@ void ata_scsi_rw_queue(struct ata_port *ap, struct ata_device *dev,
* Length of response buffer.
*/
static
unsigned
int
ata_scsi_rbuf_get
(
Scsi_C
mnd
*
cmd
,
u8
**
buf_out
)
static
unsigned
int
ata_scsi_rbuf_get
(
struct
scsi_c
mnd
*
cmd
,
u8
**
buf_out
)
{
u8
*
buf
;
unsigned
int
buflen
;
...
...
@@ -363,7 +386,7 @@ static unsigned int ata_scsi_rbuf_get(Scsi_Cmnd *cmd, u8 **buf_out)
* spin_lock_irqsave(host_set lock)
*/
static
inline
void
ata_scsi_rbuf_put
(
Scsi_C
mnd
*
cmd
)
static
inline
void
ata_scsi_rbuf_put
(
struct
scsi_c
mnd
*
cmd
)
{
if
(
cmd
->
use_sg
)
{
struct
scatterlist
*
sg
;
...
...
@@ -394,7 +417,7 @@ void ata_scsi_rbuf_fill(struct ata_scsi_args *args,
{
u8
*
rbuf
;
unsigned
int
buflen
,
rc
;
Scsi_C
mnd
*
cmd
=
args
->
cmd
;
struct
scsi_c
mnd
*
cmd
=
args
->
cmd
;
buflen
=
ata_scsi_rbuf_get
(
cmd
,
&
rbuf
);
rc
=
actor
(
args
,
rbuf
,
buflen
);
...
...
@@ -817,7 +840,7 @@ unsigned int ata_scsiop_report_luns(struct ata_scsi_args *args, u8 *rbuf,
* spin_lock_irqsave(host_set lock)
*/
void
ata_scsi_badcmd
(
Scsi_Cmnd
*
cmd
,
void
(
*
done
)(
Scsi_C
mnd
*
),
u8
asc
,
u8
ascq
)
void
ata_scsi_badcmd
(
struct
scsi_cmnd
*
cmd
,
void
(
*
done
)(
struct
scsi_c
mnd
*
),
u8
asc
,
u8
ascq
)
{
DPRINTK
(
"ENTER
\n
"
);
cmd
->
result
=
SAM_STAT_CHECK_CONDITION
;
...
...
@@ -847,7 +870,7 @@ void ata_scsi_badcmd(Scsi_Cmnd *cmd, void (*done)(Scsi_Cmnd *), u8 asc, u8 ascq)
*/
static
void
atapi_scsi_queuecmd
(
struct
ata_port
*
ap
,
struct
ata_device
*
dev
,
Scsi_Cmnd
*
cmd
,
void
(
*
done
)(
Scsi_C
mnd
*
))
struct
scsi_cmnd
*
cmd
,
void
(
*
done
)(
struct
scsi_c
mnd
*
))
{
struct
ata_queued_cmd
*
qc
;
u8
*
scsicmd
=
cmd
->
cmnd
,
status
;
...
...
@@ -958,7 +981,7 @@ static void atapi_scsi_queuecmd(struct ata_port *ap, struct ata_device *dev,
* Zero.
*/
int
ata_scsi_queuecmd
(
Scsi_Cmnd
*
cmd
,
void
(
*
done
)(
Scsi_C
mnd
*
))
int
ata_scsi_queuecmd
(
struct
scsi_cmnd
*
cmd
,
void
(
*
done
)(
struct
scsi_c
mnd
*
))
{
u8
*
scsicmd
=
cmd
->
cmnd
;
struct
ata_port
*
ap
;
...
...
drivers/scsi/libata.h
View file @
e241138a
...
...
@@ -31,8 +31,8 @@
struct
ata_scsi_args
{
struct
ata_port
*
ap
;
struct
ata_device
*
dev
;
Scsi_C
mnd
*
cmd
;
void
(
*
done
)(
Scsi_C
mnd
*
);
struct
scsi_c
mnd
*
cmd
;
void
(
*
done
)(
struct
scsi_c
mnd
*
);
};
...
...
@@ -51,7 +51,7 @@ extern void ata_thread_wake(struct ata_port *ap, unsigned int thr_state);
/* libata-scsi.c */
extern
void
ata_to_sense_error
(
struct
ata_queued_cmd
*
qc
);
extern
void
ata_scsi_rw_queue
(
struct
ata_port
*
ap
,
struct
ata_device
*
dev
,
Scsi_Cmnd
*
cmd
,
void
(
*
done
)(
Scsi_C
mnd
*
),
struct
scsi_cmnd
*
cmd
,
void
(
*
done
)(
struct
scsi_c
mnd
*
),
unsigned
int
cmd_size
);
extern
int
ata_scsi_error
(
struct
Scsi_Host
*
host
);
extern
unsigned
int
ata_scsiop_inq_std
(
struct
ata_scsi_args
*
args
,
u8
*
rbuf
,
...
...
@@ -74,19 +74,19 @@ extern unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf,
unsigned
int
buflen
);
extern
unsigned
int
ata_scsiop_report_luns
(
struct
ata_scsi_args
*
args
,
u8
*
rbuf
,
unsigned
int
buflen
);
extern
void
ata_scsi_badcmd
(
Scsi_C
mnd
*
cmd
,
void
(
*
done
)(
Scsi_C
mnd
*
),
extern
void
ata_scsi_badcmd
(
struct
scsi_c
mnd
*
cmd
,
void
(
*
done
)(
struct
scsi_c
mnd
*
),
u8
asc
,
u8
ascq
);
extern
void
ata_scsi_rbuf_fill
(
struct
ata_scsi_args
*
args
,
unsigned
int
(
*
actor
)
(
struct
ata_scsi_args
*
args
,
u8
*
rbuf
,
unsigned
int
buflen
));
static
inline
void
ata_bad_scsiop
(
Scsi_Cmnd
*
cmd
,
void
(
*
done
)(
Scsi_C
mnd
*
))
static
inline
void
ata_bad_scsiop
(
struct
scsi_cmnd
*
cmd
,
void
(
*
done
)(
struct
scsi_c
mnd
*
))
{
ata_scsi_badcmd
(
cmd
,
done
,
0x20
,
0x00
);
}
static
inline
void
ata_bad_cdb
(
Scsi_Cmnd
*
cmd
,
void
(
*
done
)(
Scsi_C
mnd
*
))
static
inline
void
ata_bad_cdb
(
struct
scsi_cmnd
*
cmd
,
void
(
*
done
)(
struct
scsi_c
mnd
*
))
{
ata_scsi_badcmd
(
cmd
,
done
,
0x24
,
0x00
);
}
...
...
drivers/scsi/sata_promise.c
View file @
e241138a
...
...
@@ -34,10 +34,8 @@
#include <linux/libata.h>
#include <asm/io.h>
#undef DIRECT_HDMA
#define DRV_NAME "sata_promise"
#define DRV_VERSION "0.8
6
"
#define DRV_VERSION "0.8
9
"
enum
{
...
...
@@ -82,6 +80,42 @@ enum {
PDC_FLAG_20621
=
(
1
<<
30
),
/* we have a 20621 */
PDC_HDMA_RESET
=
(
1
<<
11
),
/* HDMA reset */
PDC_MAX_HDMA
=
32
,
PDC_HDMA_Q_MASK
=
(
PDC_MAX_HDMA
-
1
),
PDC_DIMM0_SPD_DEV_ADDRESS
=
0x50
,
PDC_DIMM1_SPD_DEV_ADDRESS
=
0x51
,
PDC_MAX_DIMM_MODULE
=
0x02
,
PDC_I2C_CONTROL_OFFSET
=
0x48
,
PDC_I2C_ADDR_DATA_OFFSET
=
0x4C
,
PDC_DIMM0_CONTROL_OFFSET
=
0x80
,
PDC_DIMM1_CONTROL_OFFSET
=
0x84
,
PDC_SDRAM_CONTROL_OFFSET
=
0x88
,
PDC_I2C_WRITE
=
0x00000000
,
PDC_I2C_READ
=
0x00000040
,
PDC_I2C_START
=
0x00000080
,
PDC_I2C_MASK_INT
=
0x00000020
,
PDC_I2C_COMPLETE
=
0x00010000
,
PDC_I2C_NO_ACK
=
0x00100000
,
PDC_DIMM_SPD_SUBADDRESS_START
=
0x00
,
PDC_DIMM_SPD_SUBADDRESS_END
=
0x7F
,
PDC_DIMM_SPD_ROW_NUM
=
3
,
PDC_DIMM_SPD_COLUMN_NUM
=
4
,
PDC_DIMM_SPD_MODULE_ROW
=
5
,
PDC_DIMM_SPD_TYPE
=
11
,
PDC_DIMM_SPD_FRESH_RATE
=
12
,
PDC_DIMM_SPD_BANK_NUM
=
17
,
PDC_DIMM_SPD_CAS_LATENCY
=
18
,
PDC_DIMM_SPD_ATTRIBUTE
=
21
,
PDC_DIMM_SPD_ROW_PRE_CHARGE
=
27
,
PDC_DIMM_SPD_ROW_ACTIVE_DELAY
=
28
,
PDC_DIMM_SPD_RAS_CAS_DELAY
=
29
,
PDC_DIMM_SPD_ACTIVE_PRECHARGE
=
30
,
PDC_DIMM_SPD_SYSTEM_FREQ
=
126
,
PDC_CTL_STATUS
=
0x08
,
PDC_DIMM_WINDOW_CTLR
=
0x0C
,
PDC_GENERAL_CTLR
=
0x484
,
};
...
...
@@ -91,6 +125,19 @@ struct pdc_port_priv {
dma_addr_t
pkt_dma
;
};
struct
pdc_host_priv
{
void
*
dimm_mmio
;
unsigned
int
doing_hdma
;
unsigned
int
hdma_prod
;
unsigned
int
hdma_cons
;
struct
{
struct
ata_queued_cmd
*
qc
;
unsigned
int
seq
;
unsigned
long
pkt_ofs
;
}
hdma
[
32
];
};
static
u32
pdc_sata_scr_read
(
struct
ata_port
*
ap
,
unsigned
int
sc_reg
);
static
void
pdc_sata_scr_write
(
struct
ata_port
*
ap
,
unsigned
int
sc_reg
,
u32
val
);
...
...
@@ -114,6 +161,18 @@ static void pdc_exec_command_mmio(struct ata_port *ap, struct ata_taskfile *tf);
static
void
pdc20621_host_stop
(
struct
ata_host_set
*
host_set
);
static
inline
void
pdc_dma_complete
(
struct
ata_port
*
ap
,
struct
ata_queued_cmd
*
qc
);
static
unsigned
int
pdc20621_dimm_init
(
struct
ata_probe_ent
*
pe
);
static
int
pdc20621_detect_dimm
(
struct
ata_probe_ent
*
pe
);
static
unsigned
int
pdc20621_i2c_read
(
struct
ata_probe_ent
*
pe
,
u32
device
,
u32
subaddr
,
u32
*
pdata
);
static
int
pdc20621_prog_dimm0
(
struct
ata_probe_ent
*
pe
);
static
unsigned
int
pdc20621_prog_dimm_global
(
struct
ata_probe_ent
*
pe
);
#ifdef ATA_VERBOSE_DEBUG
static
void
pdc20621_get_from_dimm
(
struct
ata_probe_ent
*
pe
,
void
*
psource
,
u32
offset
,
u32
size
);
#endif
static
void
pdc20621_put_to_dimm
(
struct
ata_probe_ent
*
pe
,
void
*
psource
,
u32
offset
,
u32
size
);
static
Scsi_Host_Template
pdc_sata_sht
=
{
...
...
@@ -131,6 +190,7 @@ static Scsi_Host_Template pdc_sata_sht = {
.
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
pdc_sata_ops
=
{
...
...
@@ -235,10 +295,11 @@ static struct pci_driver pdc_sata_pci_driver = {
static
void
pdc20621_host_stop
(
struct
ata_host_set
*
host_set
)
{
void
*
mmio
=
host_set
->
private_data
;
struct
pdc_host_priv
*
hpriv
=
host_set
->
private_data
;
void
*
dimm_mmio
=
hpriv
->
dimm_mmio
;
assert
(
mmio
!=
NULL
);
iounmap
(
mmio
);
iounmap
(
dimm_mmio
);
kfree
(
hpriv
);
}
static
int
pdc_port_start
(
struct
ata_port
*
ap
)
...
...
@@ -256,6 +317,7 @@ static int pdc_port_start(struct ata_port *ap)
rc
=
-
ENOMEM
;
goto
err_out
;
}
memset
(
pp
,
0
,
sizeof
(
*
pp
));
pp
->
pkt
=
pci_alloc_consistent
(
pdev
,
128
,
&
pp
->
pkt_dma
);
if
(
!
pp
->
pkt
)
{
...
...
@@ -589,7 +651,8 @@ static void pdc20621_fill_sg(struct ata_queued_cmd *qc)
struct
ata_port
*
ap
=
qc
->
ap
;
struct
pdc_port_priv
*
pp
=
ap
->
private_data
;
void
*
mmio
=
ap
->
host_set
->
mmio_base
;
void
*
dimm_mmio
=
ap
->
host_set
->
private_data
;
struct
pdc_host_priv
*
hpriv
=
ap
->
host_set
->
private_data
;
void
*
dimm_mmio
=
hpriv
->
dimm_mmio
;
unsigned
int
portno
=
ap
->
port_no
;
unsigned
int
i
,
last
,
idx
,
total_len
=
0
,
sgt_len
;
u32
*
buf
=
(
u32
*
)
&
pp
->
dimm_buf
[
PDC_DIMM_HEADER_SZ
];
...
...
@@ -605,8 +668,8 @@ static void pdc20621_fill_sg(struct ata_queued_cmd *qc)
last
=
qc
->
n_elem
;
idx
=
0
;
for
(
i
=
0
;
i
<
last
;
i
++
)
{
buf
[
idx
++
]
=
cpu_to_le32
(
sg
[
i
].
dma_address
);
buf
[
idx
++
]
=
cpu_to_le32
(
sg
[
i
].
length
);
buf
[
idx
++
]
=
cpu_to_le32
(
sg
_dma_address
(
&
sg
[
i
])
);
buf
[
idx
++
]
=
cpu_to_le32
(
sg
_dma_len
(
&
sg
[
i
])
);
total_len
+=
sg
[
i
].
length
;
}
buf
[
idx
-
1
]
|=
cpu_to_le32
(
ATA_PRD_EOT
);
...
...
@@ -643,49 +706,68 @@ static void pdc20621_fill_sg(struct ata_queued_cmd *qc)
VPRINTK
(
"ata pkt buf ofs %u, prd size %u, mmio copied
\n
"
,
i
,
sgt_len
);
}
#ifdef DIRECT_HDMA
static
void
pdc20621_push_hdma
(
struct
ata_queued_cmd
*
qc
)
static
void
__pdc20621_push_hdma
(
struct
ata_queued_cmd
*
qc
,
unsigned
int
seq
,
u32
pkt_ofs
)
{
struct
ata_port
*
ap
=
qc
->
ap
;
struct
ata_host_set
*
host_set
=
ap
->
host_set
;
unsigned
int
port_no
=
ap
->
port_no
;
void
*
mmio
=
host_set
->
mmio_base
;
unsigned
int
rw
=
(
qc
->
flags
&
ATA_QCFLAG_WRITE
);
u32
tmp
;
unsigned
int
host_sg
=
PDC_20621_DIMM_BASE
+
(
PDC_DIMM_WINDOW_STEP
*
port_no
)
+
PDC_DIMM_HOST_PRD
;
unsigned
int
dimm_sg
=
PDC_20621_DIMM_BASE
+
(
PDC_DIMM_WINDOW_STEP
*
port_no
)
+
PDC_DIMM_HPKT_PRD
;
/* hard-code chip #0 */
mmio
+=
PDC_CHIP0_OFS
;
tmp
=
readl
(
mmio
+
PDC_HDMA_CTLSTAT
)
&
0xffffff00
;
tmp
|=
port_no
+
1
+
4
;
/* seq. ID */
if
(
!
rw
)
tmp
|=
(
1
<<
6
);
/* hdma data direction */
writel
(
tmp
,
mmio
+
PDC_HDMA_CTLSTAT
);
/* note: stops DMA, if active */
readl
(
mmio
+
PDC_HDMA_CTLSTAT
);
/* flush */
writel
(
0x00000001
,
mmio
+
PDC_20621_SEQCTL
+
(
seq
*
4
));
readl
(
mmio
+
PDC_20621_SEQCTL
+
(
seq
*
4
));
/* flush */
writel
(
host_sg
,
mmio
+
0x108
);
writel
(
dimm_sg
,
mmio
+
0x10C
);
writel
(
0
,
mmio
+
0x128
);
writel
(
pkt_ofs
,
mmio
+
PDC_HDMA_PKT_SUBMIT
);
readl
(
mmio
+
PDC_HDMA_PKT_SUBMIT
);
/* flush */
}
tmp
|=
(
1
<<
7
);
writel
(
tmp
,
mmio
+
PDC_HDMA_CTLSTAT
);
readl
(
mmio
+
PDC_HDMA_CTLSTAT
);
/* flush */
static
void
pdc20621_push_hdma
(
struct
ata_queued_cmd
*
qc
,
unsigned
int
seq
,
u32
pkt_ofs
)
{
struct
ata_port
*
ap
=
qc
->
ap
;
struct
pdc_host_priv
*
pp
=
ap
->
host_set
->
private_data
;
unsigned
int
idx
=
pp
->
hdma_prod
&
PDC_HDMA_Q_MASK
;
if
(
!
pp
->
doing_hdma
)
{
__pdc20621_push_hdma
(
qc
,
seq
,
pkt_ofs
);
pp
->
doing_hdma
=
1
;
return
;
}
pp
->
hdma
[
idx
].
qc
=
qc
;
pp
->
hdma
[
idx
].
seq
=
seq
;
pp
->
hdma
[
idx
].
pkt_ofs
=
pkt_ofs
;
pp
->
hdma_prod
++
;
}
static
void
pdc20621_pop_hdma
(
struct
ata_queued_cmd
*
qc
)
{
struct
ata_port
*
ap
=
qc
->
ap
;
struct
pdc_host_priv
*
pp
=
ap
->
host_set
->
private_data
;
unsigned
int
idx
=
pp
->
hdma_cons
&
PDC_HDMA_Q_MASK
;
/* if nothing on queue, we're done */
if
(
pp
->
hdma_prod
==
pp
->
hdma_cons
)
{
pp
->
doing_hdma
=
0
;
return
;
}
__pdc20621_push_hdma
(
pp
->
hdma
[
idx
].
qc
,
pp
->
hdma
[
idx
].
seq
,
pp
->
hdma
[
idx
].
pkt_ofs
);
pp
->
hdma_cons
++
;
}
#endif
#ifdef ATA_VERBOSE_DEBUG
static
void
pdc20621_dump_hdma
(
struct
ata_queued_cmd
*
qc
)
{
struct
ata_port
*
ap
=
qc
->
ap
;
unsigned
int
port_no
=
ap
->
port_no
;
void
*
dimm_mmio
=
ap
->
host_set
->
private_data
;
struct
pdc_host_priv
*
hpriv
=
ap
->
host_set
->
private_data
;
void
*
dimm_mmio
=
hpriv
->
dimm_mmio
;
dimm_mmio
+=
(
port_no
*
PDC_DIMM_WINDOW_STEP
);
dimm_mmio
+=
PDC_DIMM_HOST_PKT
;
...
...
@@ -724,23 +806,17 @@ static void pdc20621_dma_start(struct ata_queued_cmd *qc)
wmb
();
/* flush PRD, pkt writes */
writel
(
0x00000001
,
mmio
+
PDC_20621_SEQCTL
+
(
seq
*
4
));
readl
(
mmio
+
PDC_20621_SEQCTL
+
(
seq
*
4
));
/* flush */
if
(
doing_hdma
)
{
pdc20621_dump_hdma
(
qc
);
#ifdef DIRECT_HDMA
pdc20621_push_hdma
(
qc
);
#else
writel
(
port_ofs
+
PDC_DIMM_HOST_PKT
,
mmio
+
PDC_HDMA_PKT_SUBMIT
);
readl
(
mmio
+
PDC_HDMA_PKT_SUBMIT
);
/* flush */
#endif
VPRINTK
(
"submitted ofs 0x%x (%u), seq %u
\n
"
,
pdc20621_push_hdma
(
qc
,
seq
,
port_ofs
+
PDC_DIMM_HOST_PKT
);
VPRINTK
(
"queued ofs 0x%x (%u), seq %u
\n
"
,
port_ofs
+
PDC_DIMM_HOST_PKT
,
port_ofs
+
PDC_DIMM_HOST_PKT
,
seq
);
}
else
{
writel
(
0x00000001
,
mmio
+
PDC_20621_SEQCTL
+
(
seq
*
4
));
readl
(
mmio
+
PDC_20621_SEQCTL
+
(
seq
*
4
));
/* flush */
writel
(
port_ofs
+
PDC_DIMM_ATA_PKT
,
(
void
*
)
ap
->
ioaddr
.
cmd_addr
+
PDC_PKT_SUBMIT
);
readl
((
void
*
)
ap
->
ioaddr
.
cmd_addr
+
PDC_PKT_SUBMIT
);
...
...
@@ -771,6 +847,7 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap,
VPRINTK
(
"ata%u: read hdma, 0x%x 0x%x
\n
"
,
ap
->
id
,
readl
(
mmio
+
0x104
),
readl
(
mmio
+
PDC_HDMA_CTLSTAT
));
pdc_dma_complete
(
ap
,
qc
);
pdc20621_pop_hdma
(
qc
);
}
/* step one - exec ATA command */
...
...
@@ -781,15 +858,8 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap,
/* submit hdma pkt */
pdc20621_dump_hdma
(
qc
);
writel
(
0x00000001
,
mmio
+
PDC_20621_SEQCTL
+
(
seq
*
4
));
readl
(
mmio
+
PDC_20621_SEQCTL
+
(
seq
*
4
));
#ifdef DIRECT_HDMA
pdc20621_push_hdma
(
qc
);
#else
writel
(
port_ofs
+
PDC_DIMM_HOST_PKT
,
mmio
+
PDC_HDMA_PKT_SUBMIT
);
readl
(
mmio
+
PDC_HDMA_PKT_SUBMIT
);
#endif
pdc20621_push_hdma
(
qc
,
seq
,
port_ofs
+
PDC_DIMM_HOST_PKT
);
}
handled
=
1
;
break
;
...
...
@@ -814,6 +884,7 @@ static inline unsigned int pdc20621_host_intr( struct ata_port *ap,
VPRINTK
(
"ata%u: write ata, 0x%x 0x%x
\n
"
,
ap
->
id
,
readl
(
mmio
+
0x104
),
readl
(
mmio
+
PDC_HDMA_CTLSTAT
));
pdc_dma_complete
(
ap
,
qc
);
pdc20621_pop_hdma
(
qc
);
}
handled
=
1
;
break
;
...
...
@@ -1098,11 +1169,373 @@ static void pdc_sata_setup_port(struct ata_ioports *port, unsigned long base)
port
->
ctl_addr
=
base
+
0x38
;
}
#ifdef ATA_VERBOSE_DEBUG
static
void
pdc20621_get_from_dimm
(
struct
ata_probe_ent
*
pe
,
void
*
psource
,
u32
offset
,
u32
size
)
{
u32
window_size
;
u16
idx
;
u8
page_mask
;
long
dist
;
void
*
mmio
=
pe
->
mmio_base
;
struct
pdc_host_priv
*
hpriv
=
pe
->
private_data
;
void
*
dimm_mmio
=
hpriv
->
dimm_mmio
;
/* hard-code chip #0 */
mmio
+=
PDC_CHIP0_OFS
;
page_mask
=
0x00
;
window_size
=
0x2000
*
4
;
/* 32K byte uchar size */
idx
=
(
u16
)
(
offset
/
window_size
);
writel
(
0x01
,
mmio
+
PDC_GENERAL_CTLR
);
readl
(
mmio
+
PDC_GENERAL_CTLR
);
writel
(((
idx
)
<<
page_mask
),
mmio
+
PDC_DIMM_WINDOW_CTLR
);
readl
(
mmio
+
PDC_DIMM_WINDOW_CTLR
);
offset
-=
(
idx
*
window_size
);
idx
++
;
dist
=
((
long
)
(
window_size
-
(
offset
+
size
)))
>=
0
?
size
:
(
long
)
(
window_size
-
offset
);
memcpy_fromio
((
char
*
)
psource
,
(
char
*
)
(
dimm_mmio
+
offset
/
4
),
dist
);
psource
+=
dist
;
size
-=
dist
;
for
(;
(
long
)
size
>=
(
long
)
window_size
;)
{
writel
(
0x01
,
mmio
+
PDC_GENERAL_CTLR
);
readl
(
mmio
+
PDC_GENERAL_CTLR
);
writel
(((
idx
)
<<
page_mask
),
mmio
+
PDC_DIMM_WINDOW_CTLR
);
readl
(
mmio
+
PDC_DIMM_WINDOW_CTLR
);
memcpy_fromio
((
char
*
)
psource
,
(
char
*
)
(
dimm_mmio
),
window_size
/
4
);
psource
+=
window_size
;
size
-=
window_size
;
idx
++
;
}
if
(
size
)
{
writel
(
0x01
,
mmio
+
PDC_GENERAL_CTLR
);
readl
(
mmio
+
PDC_GENERAL_CTLR
);
writel
(((
idx
)
<<
page_mask
),
mmio
+
PDC_DIMM_WINDOW_CTLR
);
readl
(
mmio
+
PDC_DIMM_WINDOW_CTLR
);
memcpy_fromio
((
char
*
)
psource
,
(
char
*
)
(
dimm_mmio
),
size
/
4
);
}
}
#endif
static
void
pdc20621_put_to_dimm
(
struct
ata_probe_ent
*
pe
,
void
*
psource
,
u32
offset
,
u32
size
)
{
u32
window_size
;
u16
idx
;
u8
page_mask
;
long
dist
;
void
*
mmio
=
pe
->
mmio_base
;
struct
pdc_host_priv
*
hpriv
=
pe
->
private_data
;
void
*
dimm_mmio
=
hpriv
->
dimm_mmio
;
/* hard-code chip #0 */
mmio
+=
PDC_CHIP0_OFS
;
page_mask
=
0x00
;
window_size
=
0x2000
*
4
;
/* 32K byte uchar size */
idx
=
(
u16
)
(
offset
/
window_size
);
writel
(((
idx
)
<<
page_mask
),
mmio
+
PDC_DIMM_WINDOW_CTLR
);
readl
(
mmio
+
PDC_DIMM_WINDOW_CTLR
);
offset
-=
(
idx
*
window_size
);
idx
++
;
dist
=
((
long
)
(
window_size
-
(
offset
+
size
)))
>=
0
?
size
:
(
long
)
(
window_size
-
offset
);
memcpy_toio
((
char
*
)
(
dimm_mmio
+
offset
/
4
),
(
char
*
)
psource
,
dist
);
writel
(
0x01
,
mmio
+
PDC_GENERAL_CTLR
);
readl
(
mmio
+
PDC_GENERAL_CTLR
);
psource
+=
dist
;
size
-=
dist
;
for
(;
(
long
)
size
>=
(
long
)
window_size
;)
{
writel
(((
idx
)
<<
page_mask
),
mmio
+
PDC_DIMM_WINDOW_CTLR
);
readl
(
mmio
+
PDC_DIMM_WINDOW_CTLR
);
memcpy_toio
((
char
*
)
(
dimm_mmio
),
(
char
*
)
psource
,
window_size
/
4
);
writel
(
0x01
,
mmio
+
PDC_GENERAL_CTLR
);
readl
(
mmio
+
PDC_GENERAL_CTLR
);
psource
+=
window_size
;
size
-=
window_size
;
idx
++
;
}
if
(
size
)
{
writel
(((
idx
)
<<
page_mask
),
mmio
+
PDC_DIMM_WINDOW_CTLR
);
readl
(
mmio
+
PDC_DIMM_WINDOW_CTLR
);
memcpy_toio
((
char
*
)
(
dimm_mmio
),
(
char
*
)
psource
,
size
/
4
);
writel
(
0x01
,
mmio
+
PDC_GENERAL_CTLR
);
readl
(
mmio
+
PDC_GENERAL_CTLR
);
}
}
static
unsigned
int
pdc20621_i2c_read
(
struct
ata_probe_ent
*
pe
,
u32
device
,
u32
subaddr
,
u32
*
pdata
)
{
void
*
mmio
=
pe
->
mmio_base
;
u32
i2creg
=
0
;
u32
status
;
u32
count
=
0
;
/* hard-code chip #0 */
mmio
+=
PDC_CHIP0_OFS
;
i2creg
|=
device
<<
24
;
i2creg
|=
subaddr
<<
16
;
/* Set the device and subaddress */
writel
(
i2creg
,
mmio
+
PDC_I2C_ADDR_DATA_OFFSET
);
readl
(
mmio
+
PDC_I2C_ADDR_DATA_OFFSET
);
/* Write Control to perform read operation, mask int */
writel
(
PDC_I2C_READ
|
PDC_I2C_START
|
PDC_I2C_MASK_INT
,
mmio
+
PDC_I2C_CONTROL_OFFSET
);
for
(
count
=
0
;
count
<=
1000
;
count
++
)
{
status
=
readl
(
mmio
+
PDC_I2C_CONTROL_OFFSET
);
if
(
status
&
PDC_I2C_COMPLETE
)
{
status
=
readl
(
mmio
+
PDC_I2C_ADDR_DATA_OFFSET
);
break
;
}
else
if
(
count
==
1000
)
return
0
;
}
*
pdata
=
(
status
>>
8
)
&
0x000000ff
;
return
1
;
}
static
int
pdc20621_detect_dimm
(
struct
ata_probe_ent
*
pe
)
{
u32
data
=
0
;
if
(
pdc20621_i2c_read
(
pe
,
PDC_DIMM0_SPD_DEV_ADDRESS
,
PDC_DIMM_SPD_SYSTEM_FREQ
,
&
data
))
{
if
(
data
==
100
)
return
100
;
}
else
return
0
;
if
(
pdc20621_i2c_read
(
pe
,
PDC_DIMM0_SPD_DEV_ADDRESS
,
9
,
&
data
))
{
if
(
data
<=
0x75
)
return
133
;
}
else
return
0
;
return
0
;
}
static
int
pdc20621_prog_dimm0
(
struct
ata_probe_ent
*
pe
)
{
u32
spd0
[
50
];
u32
data
=
0
;
int
size
,
i
;
u8
bdimmsize
;
void
*
mmio
=
pe
->
mmio_base
;
static
const
struct
{
unsigned
int
reg
;
unsigned
int
ofs
;
}
pdc_i2c_read_data
[]
=
{
{
PDC_DIMM_SPD_TYPE
,
11
},
{
PDC_DIMM_SPD_FRESH_RATE
,
12
},
{
PDC_DIMM_SPD_COLUMN_NUM
,
4
},
{
PDC_DIMM_SPD_ATTRIBUTE
,
21
},
{
PDC_DIMM_SPD_ROW_NUM
,
3
},
{
PDC_DIMM_SPD_BANK_NUM
,
17
},
{
PDC_DIMM_SPD_MODULE_ROW
,
5
},
{
PDC_DIMM_SPD_ROW_PRE_CHARGE
,
27
},
{
PDC_DIMM_SPD_ROW_ACTIVE_DELAY
,
28
},
{
PDC_DIMM_SPD_RAS_CAS_DELAY
,
29
},
{
PDC_DIMM_SPD_ACTIVE_PRECHARGE
,
30
},
{
PDC_DIMM_SPD_CAS_LATENCY
,
18
},
};
/* hard-code chip #0 */
mmio
+=
PDC_CHIP0_OFS
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
pdc_i2c_read_data
);
i
++
)
pdc20621_i2c_read
(
pe
,
PDC_DIMM0_SPD_DEV_ADDRESS
,
pdc_i2c_read_data
[
i
].
reg
,
&
spd0
[
pdc_i2c_read_data
[
i
].
ofs
]);
data
|=
(
spd0
[
4
]
-
8
)
|
((
spd0
[
21
]
!=
0
)
<<
3
)
|
((
spd0
[
3
]
-
11
)
<<
4
);
data
|=
((
spd0
[
17
]
/
4
)
<<
6
)
|
((
spd0
[
5
]
/
2
)
<<
7
)
|
((((
spd0
[
27
]
+
9
)
/
10
)
-
1
)
<<
8
)
;
data
|=
(((((
spd0
[
29
]
>
spd0
[
28
])
?
spd0
[
29
]
:
spd0
[
28
])
+
9
)
/
10
)
-
1
)
<<
10
;
data
|=
((
spd0
[
30
]
-
spd0
[
29
]
+
9
)
/
10
-
2
)
<<
12
;
if
(
spd0
[
18
]
&
0x08
)
data
|=
((
0x03
)
<<
14
);
else
if
(
spd0
[
18
]
&
0x04
)
data
|=
((
0x02
)
<<
14
);
else
if
(
spd0
[
18
]
&
0x01
)
data
|=
((
0x01
)
<<
14
);
else
data
|=
(
0
<<
14
);
/*
Calculate the size of bDIMMSize (power of 2) and
merge the DIMM size by program start/end address.
*/
bdimmsize
=
spd0
[
4
]
+
(
spd0
[
5
]
/
2
)
+
spd0
[
3
]
+
(
spd0
[
17
]
/
2
)
+
3
;
size
=
(
1
<<
bdimmsize
)
>>
20
;
/* size = xxx(MB) */
data
|=
(((
size
/
16
)
-
1
)
<<
16
);
data
|=
(
0
<<
23
);
data
|=
8
;
writel
(
data
,
mmio
+
PDC_DIMM0_CONTROL_OFFSET
);
readl
(
mmio
+
PDC_DIMM0_CONTROL_OFFSET
);
return
size
;
}
static
unsigned
int
pdc20621_prog_dimm_global
(
struct
ata_probe_ent
*
pe
)
{
u32
data
,
spd0
;
int
error
,
i
;
void
*
mmio
=
pe
->
mmio_base
;
/* hard-code chip #0 */
mmio
+=
PDC_CHIP0_OFS
;
/*
Set To Default : DIMM Module Global Control Register (0x022259F1)
DIMM Arbitration Disable (bit 20)
DIMM Data/Control Output Driving Selection (bit12 - bit15)
Refresh Enable (bit 17)
*/
data
=
0x022259F1
;
writel
(
data
,
mmio
+
PDC_SDRAM_CONTROL_OFFSET
);
readl
(
mmio
+
PDC_SDRAM_CONTROL_OFFSET
);
/* Turn on for ECC */
pdc20621_i2c_read
(
pe
,
PDC_DIMM0_SPD_DEV_ADDRESS
,
PDC_DIMM_SPD_TYPE
,
&
spd0
);
if
(
spd0
==
0x02
)
{
data
|=
(
0x01
<<
16
);
writel
(
data
,
mmio
+
PDC_SDRAM_CONTROL_OFFSET
);
readl
(
mmio
+
PDC_SDRAM_CONTROL_OFFSET
);
printk
(
KERN_ERR
"Local DIMM ECC Enabled
\n
"
);
}
/* DIMM Initialization Select/Enable (bit 18/19) */
data
&=
(
~
(
1
<<
18
));
data
|=
(
1
<<
19
);
writel
(
data
,
mmio
+
PDC_SDRAM_CONTROL_OFFSET
);
error
=
1
;
for
(
i
=
1
;
i
<=
10
;
i
++
)
{
/* polling ~5 secs */
data
=
readl
(
mmio
+
PDC_SDRAM_CONTROL_OFFSET
);
if
(
!
(
data
&
(
1
<<
19
)))
{
error
=
0
;
break
;
}
set_current_state
(
TASK_INTERRUPTIBLE
);
schedule_timeout
((
i
*
100
)
*
HZ
/
1000
);
}
return
error
;
}
static
unsigned
int
pdc20621_dimm_init
(
struct
ata_probe_ent
*
pe
)
{
int
speed
,
size
,
length
;
u32
addr
,
spd0
,
pci_status
;
u32
tmp
=
0
;
void
*
mmio
=
pe
->
mmio_base
;
/* hard-code chip #0 */
mmio
+=
PDC_CHIP0_OFS
;
/* Initialize PLL. */
pci_status
=
0x8a531824
;
writel
(
pci_status
,
mmio
+
PDC_CTL_STATUS
);
readl
(
mmio
+
PDC_CTL_STATUS
);
/*
Read SPD of DIMM by I2C interface,
and program the DIMM Module Controller.
*/
if
(
!
(
speed
=
pdc20621_detect_dimm
(
pe
)))
{
printk
(
KERN_ERR
"Detect Local DIMM Fail
\n
"
);
return
1
;
/* DIMM error */
}
VPRINTK
(
"Local DIMM Speed = %d
\n
"
,
speed
);
/* Programming DIMM0 Module Control Register (index_CID0:80h) */
size
=
pdc20621_prog_dimm0
(
pe
);
VPRINTK
(
"Local DIMM Size = %dMB
\n
"
,
size
);
/* Programming DIMM Module Global Control Register (index_CID0:88h) */
if
(
pdc20621_prog_dimm_global
(
pe
))
{
printk
(
KERN_ERR
"Programming DIMM Module Global Control Register Fail
\n
"
);
return
1
;
}
#ifdef ATA_VERBOSE_DEBUG
{
u8
test_parttern1
[
40
]
=
{
0x55
,
0xAA
,
'P'
,
'r'
,
'o'
,
'm'
,
'i'
,
's'
,
'e'
,
' '
,
'N'
,
'o'
,
't'
,
' '
,
'Y'
,
'e'
,
't'
,
' '
,
'D'
,
'e'
,
'f'
,
'i'
,
'n'
,
'e'
,
'd'
,
' '
,
'1'
,
'.'
,
'1'
,
'0'
,
'9'
,
'8'
,
'0'
,
'3'
,
'1'
,
'6'
,
'1'
,
'2'
,
0
,
0
};
u8
test_parttern2
[
40
]
=
{
0
};
pdc20621_put_to_dimm
(
pe
,
(
void
*
)
test_parttern2
,
0x10040
,
40
);
pdc20621_put_to_dimm
(
pe
,
(
void
*
)
test_parttern2
,
0x40
,
40
);
pdc20621_put_to_dimm
(
pe
,
(
void
*
)
test_parttern1
,
0x10040
,
40
);
pdc20621_get_from_dimm
(
pe
,
(
void
*
)
test_parttern2
,
0x40
,
40
);
printk
(
KERN_ERR
"%x, %x, %s
\n
"
,
test_parttern2
[
0
],
test_parttern2
[
1
],
&
(
test_parttern2
[
2
]));
pdc20621_get_from_dimm
(
pe
,
(
void
*
)
test_parttern2
,
0x10040
,
40
);
printk
(
KERN_ERR
"%x, %x, %s
\n
"
,
test_parttern2
[
0
],
test_parttern2
[
1
],
&
(
test_parttern2
[
2
]));
pdc20621_put_to_dimm
(
pe
,
(
void
*
)
test_parttern1
,
0x40
,
40
);
pdc20621_get_from_dimm
(
pe
,
(
void
*
)
test_parttern2
,
0x40
,
40
);
printk
(
KERN_ERR
"%x, %x, %s
\n
"
,
test_parttern2
[
0
],
test_parttern2
[
1
],
&
(
test_parttern2
[
2
]));
}
#endif
/* ECC initiliazation. */
pdc20621_i2c_read
(
pe
,
PDC_DIMM0_SPD_DEV_ADDRESS
,
PDC_DIMM_SPD_TYPE
,
&
spd0
);
if
(
spd0
==
0x02
)
{
VPRINTK
(
"Start ECC initialization
\n
"
);
addr
=
0
;
length
=
size
*
1024
*
1024
;
while
(
addr
<
length
)
{
pdc20621_put_to_dimm
(
pe
,
(
void
*
)
&
tmp
,
addr
,
sizeof
(
u32
));
addr
+=
sizeof
(
u32
);
}
VPRINTK
(
"Finish ECC initialization
\n
"
);
}
return
0
;
}
static
void
pdc_20621_init
(
struct
ata_probe_ent
*
pe
)
{
u32
tmp
;
void
*
mmio
=
pe
->
mmio_base
;
/* hard-code chip #0 */
mmio
+=
PDC_CHIP0_OFS
;
/*
...
...
@@ -1170,6 +1603,7 @@ static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *
struct
ata_probe_ent
*
probe_ent
=
NULL
;
unsigned
long
base
;
void
*
mmio_base
,
*
dimm_mmio
=
NULL
;
struct
pdc_host_priv
*
hpriv
=
NULL
;
unsigned
int
board_idx
=
(
unsigned
int
)
ent
->
driver_data
;
unsigned
int
have_20621
=
(
board_idx
==
board_20621
);
int
rc
;
...
...
@@ -1212,12 +1646,22 @@ static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *
base
=
(
unsigned
long
)
mmio_base
;
if
(
have_20621
)
{
hpriv
=
kmalloc
(
sizeof
(
*
hpriv
),
GFP_KERNEL
);
if
(
!
hpriv
)
{
rc
=
-
ENOMEM
;
goto
err_out_iounmap
;
}
memset
(
hpriv
,
0
,
sizeof
(
*
hpriv
));
dimm_mmio
=
ioremap
(
pci_resource_start
(
pdev
,
4
),
pci_resource_len
(
pdev
,
4
));
if
(
!
dimm_mmio
)
{
kfree
(
hpriv
);
rc
=
-
ENOMEM
;
goto
err_out_iounmap
;
}
hpriv
->
dimm_mmio
=
dimm_mmio
;
}
probe_ent
->
sht
=
pdc_port_info
[
board_idx
].
sht
;
...
...
@@ -1231,7 +1675,7 @@ static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *
probe_ent
->
mmio_base
=
mmio_base
;
if
(
have_20621
)
{
probe_ent
->
private_data
=
dimm_mmio
;
probe_ent
->
private_data
=
hpriv
;
base
+=
PDC_CHIP0_OFS
;
}
...
...
@@ -1268,9 +1712,14 @@ static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *
pci_set_master
(
pdev
);
/* initialize adapter */
if
(
have_20621
)
if
(
have_20621
)
{
/* initialize local dimm */
if
(
pdc20621_dimm_init
(
probe_ent
))
{
rc
=
-
ENOMEM
;
goto
err_out_iounmap_dimm
;
}
pdc_20621_init
(
probe_ent
);
else
}
else
pdc_host_init
(
board_idx
,
probe_ent
);
/* FIXME: check ata_device_add return value */
...
...
@@ -1279,6 +1728,9 @@ static int pdc_sata_init_one (struct pci_dev *pdev, const struct pci_device_id *
return
0
;
err_out_iounmap_dimm:
/* only get to this label if 20621 */
kfree
(
hpriv
);
iounmap
(
dimm_mmio
);
err_out_iounmap:
iounmap
(
mmio_base
);
err_out_free_ent:
...
...
drivers/scsi/sata_sil.c
View file @
e241138a
...
...
@@ -87,6 +87,7 @@ static Scsi_Host_Template sil_sht = {
.
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
sil_ops
=
{
...
...
drivers/scsi/sata_svw.c
View file @
e241138a
...
...
@@ -219,6 +219,7 @@ static Scsi_Host_Template k2_sata_sht = {
#ifdef CONFIG_ALL_PPC
.
proc_info
=
k2_sata_proc_info
#endif
.
bios_param
=
ata_std_bios_param
,
};
...
...
drivers/scsi/sata_via.c
View file @
e241138a
...
...
@@ -78,6 +78,7 @@ static Scsi_Host_Template svia_sht = {
.
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
svia_sata_ops
=
{
...
...
include/linux/libata.h
View file @
e241138a
...
...
@@ -28,6 +28,7 @@
#include <asm/io.h>
#include <linux/ata.h>
/*
* compile-time options
*/
...
...
@@ -66,8 +67,6 @@
/* defines only for the constants which don't work well as enums */
#define ATA_TAG_POISON 0xfafbfcfdU
#define ATA_DMA_BOUNDARY 0xffffUL
#define ATA_DMA_MASK 0xffffffffULL
enum
{
/* various global constants */
...
...
@@ -171,6 +170,7 @@ enum {
};
/* forward declarations */
struct
scsi_device
;
struct
ata_port_operations
;
struct
ata_port
;
struct
ata_queued_cmd
;
...
...
@@ -247,8 +247,8 @@ struct ata_queued_cmd {
struct
ata_port
*
ap
;
struct
ata_device
*
dev
;
Scsi_C
mnd
*
scsicmd
;
void
(
*
scsidone
)(
Scsi_C
mnd
*
);
struct
scsi_c
mnd
*
scsicmd
;
void
(
*
scsidone
)(
struct
scsi_c
mnd
*
);
struct
list_head
node
;
unsigned
long
flags
;
/* ATA_QCFLAG_xxx */
...
...
@@ -403,7 +403,7 @@ extern int ata_pci_init_one (struct pci_dev *pdev, struct ata_port_info **port_i
extern
void
ata_pci_remove_one
(
struct
pci_dev
*
pdev
);
extern
int
ata_device_add
(
struct
ata_probe_ent
*
ent
);
extern
int
ata_scsi_detect
(
Scsi_Host_Template
*
sht
);
extern
int
ata_scsi_queuecmd
(
Scsi_Cmnd
*
cmd
,
void
(
*
done
)(
Scsi_C
mnd
*
));
extern
int
ata_scsi_queuecmd
(
struct
scsi_cmnd
*
cmd
,
void
(
*
done
)(
struct
scsi_c
mnd
*
));
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
);
...
...
@@ -427,6 +427,9 @@ extern void ata_bmdma_start_pio (struct ata_queued_cmd *qc);
extern
int
pci_test_config_bits
(
struct
pci_dev
*
pdev
,
struct
pci_bits
*
bits
);
extern
void
ata_qc_complete
(
struct
ata_queued_cmd
*
qc
,
u8
drv_stat
,
unsigned
int
done_late
);
extern
void
ata_eng_timeout
(
struct
ata_port
*
ap
);
extern
int
ata_std_bios_param
(
struct
scsi_device
*
sdev
,
struct
block_device
*
bdev
,
sector_t
capacity
,
int
geom
[]);
static
inline
unsigned
long
msecs_to_jiffies
(
unsigned
long
msecs
)
...
...
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