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
9382310f
Commit
9382310f
authored
Sep 11, 2002
by
Jens Axboe
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
sis5513 update
parent
49bbaa0c
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
482 additions
and
306 deletions
+482
-306
drivers/ide/pci/sis5513.c
drivers/ide/pci/sis5513.c
+426
-306
drivers/ide/pci/sis5513.h
drivers/ide/pci/sis5513.h
+56
-0
No files found.
drivers/ide/pci/sis5513.c
View file @
9382310f
/*
* linux/drivers/ide/sis5513.c Version 0.1
3 March 6
, 2002
* linux/drivers/ide/sis5513.c Version 0.1
4 July 24
, 2002
*
* Copyright (C) 1999-2000 Andre Hedrick <andre@linux-ide.org>
* Copyright (C) 2002 Lionel Bouton <Lionel.Bouton@inet6.fr>, Maintainer
...
...
@@ -16,13 +16,13 @@
*
* Original tests and design on the SiS620/5513 chipset.
* ATA100 tests and design on the SiS735/5513 chipset.
* ATA16/33 design from specs
* ATA16/33 support from specs
* ATA133 support for SiS961/962 by L.C. Chang <lcchang@sis.com.tw>
*/
/*
* TODO:
* - Get ridden of SisHostChipInfo[] completness dependancy.
* - Get ATA-133 datasheets, implement ATA-133 init code.
* - Study drivers/ide/ide-timing.h.
* - Are there pre-ATA_16 SiS5513 chips ? -> tune init code for them
* or remove ATA_00 define
...
...
@@ -51,14 +51,14 @@
#include <asm/irq.h>
#include "ide_modes.h"
#include "sis5513.h"
/* When DEBUG is defined it outputs initial PCI config register
values and changes made to them by the driver */
values and changes made to them by the driver */
// #define DEBUG
/* When BROKEN_LEVEL is defined it limits the DMA mode
at boot time to its value */
// #define BROKEN_LEVEL XFER_SW_DMA_0
#define DISPLAY_SIS_TIMINGS
/* Miscellaneaous flags */
#define SIS5513_LATENCY 0x01
...
...
@@ -71,44 +71,33 @@
#define ATA_66 0x03
#define ATA_100a 0x04 // SiS730 is ATA100 with ATA66 layout
#define ATA_100 0x05
#define ATA_133 0x06
#define ATA_133a 0x06 // SiS961b with 133 support
#define ATA_133 0x07 // SiS962
/* 2/ variable holding the controller chipset family value */
static
u
nsigned
char
chipset_family
;
static
u
8
chipset_family
;
/*
* Debug code: following IDE config registers' changes
*/
#ifdef DEBUG
/* Copy of IDE Config registers 0x00 -> 0x57
Fewer might be used depending on the actual chipset */
static
unsigned
char
ide_regs_copy
[
0x58
];
static
byte
sis5513_max_config_register
(
void
)
{
switch
(
chipset_family
)
{
case
ATA_00
:
case
ATA_16
:
return
0x4f
;
case
ATA_33
:
return
0x52
;
case
ATA_66
:
case
ATA_100a
:
case
ATA_100
:
case
ATA_133
:
default:
return
0x57
;
}
}
/* Copy of IDE Config registers fewer will be used
* Some odd chipsets hang if unused registers are accessed
* -> We only access them in #DEBUG code (then we'll see if SiS did
* it right from day one) */
static
u8
ide_regs_copy
[
0xff
];
/* Read config registers, print differences from previous read */
static
void
sis5513_load_verify_registers
(
struct
pci_dev
*
dev
,
char
*
info
)
{
int
i
;
byte
reg_val
;
byte
changed
=
0
;
byte
max
=
sis5513_max_config_register
();
u8
reg_val
;
u8
changed
=
0
;
printk
(
"SIS5513: %s, changed registers:
\n
"
,
info
);
for
(
i
=
0
;
i
<=
max
;
i
++
)
{
for
(
i
=
0
;
i
<=
0xff
;
i
++
)
{
pci_read_config_byte
(
dev
,
i
,
&
reg_val
);
if
(
reg_val
!=
ide_regs_copy
[
i
])
{
printk
(
"%0
#x: %0#x -> %0#
x
\n
"
,
printk
(
"%0
2x: %02x -> %02
x
\n
"
,
i
,
ide_regs_copy
[
i
],
reg_val
);
ide_regs_copy
[
i
]
=
reg_val
;
changed
=
1
;
...
...
@@ -123,39 +112,26 @@ static void sis5513_load_verify_registers(struct pci_dev* dev, char* info) {
/* Load config registers, no printing */
static
void
sis5513_load_registers
(
struct
pci_dev
*
dev
)
{
int
i
;
byte
max
=
sis5513_max_config_register
();
for
(
i
=
0
;
i
<=
max
;
i
++
)
{
for
(
i
=
0
;
i
<=
0xff
;
i
++
)
{
pci_read_config_byte
(
dev
,
i
,
&
(
ide_regs_copy
[
i
]));
}
}
/* Print a register */
static
void
sis5513_print_register
(
int
reg
)
{
printk
(
" %0#x:%0#x"
,
reg
,
ide_regs_copy
[
reg
]);
}
/* Print valuable registers */
/* Print config space registers a la "lspci -vxxx" */
static
void
sis5513_print_registers
(
struct
pci_dev
*
dev
,
char
*
marker
)
{
int
i
;
byte
max
=
sis5513_max_config_register
();
int
i
,
j
;
sis5513_load_registers
(
dev
);
printk
(
"SIS5513 %s
\n
"
,
marker
);
printk
(
"SIS5513 dump:"
);
for
(
i
=
0x00
;
i
<
0x40
;
i
++
)
{
if
((
i
%
0x10
)
==
0
)
printk
(
"
\n
"
);
sis5513_print_register
(
i
);
}
for
(;
i
<
49
;
i
++
)
{
sis5513_print_register
(
i
);
}
printk
(
"
\n
"
);
for
(;
i
<=
max
;
i
++
)
{
sis5513_print_register
(
i
);
for
(
i
=
0
;
i
<=
0xf
;
i
++
)
{
printk
(
"SIS5513 dump: %d"
"0:"
,
i
);
for
(
j
=
0
;
j
<=
0xf
;
j
++
)
{
printk
(
" %02x"
,
ide_regs_copy
[(
i
<<
16
)
+
j
]);
}
printk
(
"
\n
"
);
}
printk
(
"
\n
"
);
}
#endif
...
...
@@ -165,21 +141,30 @@ static void sis5513_print_registers(struct pci_dev* dev, char* marker) {
*/
static
const
struct
{
const
char
*
name
;
u
nsigned
short
host_id
;
u
nsigned
char
chipset_family
;
u
nsigned
char
flags
;
u
16
host_id
;
u
8
chipset_family
;
u
8
flags
;
}
SiSHostChipInfo
[]
=
{
{
"SiS750"
,
PCI_DEVICE_ID_SI_750
,
ATA_100
,
SIS5513_LATENCY
},
{
"SiS745"
,
PCI_DEVICE_ID_SI_745
,
ATA_100
,
SIS5513_LATENCY
},
{
"SiS740"
,
PCI_DEVICE_ID_SI_740
,
ATA_100
,
SIS5513_LATENCY
},
{
"SiS752"
,
PCI_DEVICE_ID_SI_752
,
ATA_133
,
0
},
{
"SiS751"
,
PCI_DEVICE_ID_SI_751
,
ATA_133
,
0
},
{
"SiS750"
,
PCI_DEVICE_ID_SI_750
,
ATA_133
,
0
},
{
"SiS748"
,
PCI_DEVICE_ID_SI_748
,
ATA_133
,
0
},
{
"SiS746"
,
PCI_DEVICE_ID_SI_746
,
ATA_133
,
0
},
{
"SiS745"
,
PCI_DEVICE_ID_SI_745
,
ATA_133
,
0
},
{
"SiS740"
,
PCI_DEVICE_ID_SI_740
,
ATA_100
,
0
},
{
"SiS735"
,
PCI_DEVICE_ID_SI_735
,
ATA_100
,
SIS5513_LATENCY
},
{
"SiS730"
,
PCI_DEVICE_ID_SI_730
,
ATA_100a
,
SIS5513_LATENCY
},
{
"SiS650"
,
PCI_DEVICE_ID_SI_650
,
ATA_100
,
SIS5513_LATENCY
},
{
"SiS645"
,
PCI_DEVICE_ID_SI_645
,
ATA_100
,
SIS5513_LATENCY
},
{
"SiS652"
,
PCI_DEVICE_ID_SI_652
,
ATA_133
,
0
},
{
"SiS651"
,
PCI_DEVICE_ID_SI_651
,
ATA_133
,
0
},
{
"SiS650"
,
PCI_DEVICE_ID_SI_650
,
ATA_133
,
0
},
{
"SiS648"
,
PCI_DEVICE_ID_SI_648
,
ATA_133
,
0
},
{
"SiS646"
,
PCI_DEVICE_ID_SI_646
,
ATA_133
,
0
},
{
"SiS645"
,
PCI_DEVICE_ID_SI_645
,
ATA_133
,
0
},
{
"SiS635"
,
PCI_DEVICE_ID_SI_635
,
ATA_100
,
SIS5513_LATENCY
},
{
"SiS640"
,
PCI_DEVICE_ID_SI_640
,
ATA_66
,
SIS5513_LATENCY
},
{
"SiS630"
,
PCI_DEVICE_ID_SI_630
,
ATA_66
,
SIS5513_LATENCY
},
{
"SiS620"
,
PCI_DEVICE_ID_SI_620
,
ATA_66
,
SIS5513_LATENCY
},
{
"SiS550"
,
PCI_DEVICE_ID_SI_550
,
ATA_100a
,
0
},
{
"SiS540"
,
PCI_DEVICE_ID_SI_540
,
ATA_66
,
0
},
{
"SiS530"
,
PCI_DEVICE_ID_SI_530
,
ATA_66
,
0
},
{
"SiS5600"
,
PCI_DEVICE_ID_SI_5600
,
ATA_33
,
0
},
...
...
@@ -193,21 +178,68 @@ static const struct {
/* Cycle time bits and values vary accross chip dma capabilities
These three arrays hold the register layout and the values to set.
Indexed by chipset_family and (dma_mode - XFER_UDMA_0) */
static
byte
cycle_time_offset
[]
=
{
0
,
0
,
5
,
4
,
4
,
0
,
0
};
static
byte
cycle_time_range
[]
=
{
0
,
0
,
2
,
3
,
3
,
4
,
4
};
static
byte
cycle_time_value
[][
XFER_UDMA_5
-
XFER_UDMA_0
+
1
]
=
{
{
0
,
0
,
0
,
0
,
0
,
0
},
/* no udma */
{
0
,
0
,
0
,
0
,
0
,
0
},
/* no udma */
{
3
,
2
,
1
,
0
,
0
,
0
},
{
7
,
5
,
3
,
2
,
1
,
0
},
{
7
,
5
,
3
,
2
,
1
,
0
},
{
11
,
7
,
5
,
4
,
2
,
1
},
{
0
,
0
,
0
,
0
,
0
,
0
}
/* not yet known, ask SiS */
/* {ATA_00, ATA_16, ATA_33, ATA_66, ATA_100a, ATA_100, ATA_133} */
static
u8
cycle_time_offset
[]
=
{
0
,
0
,
5
,
4
,
4
,
0
,
0
};
static
u8
cycle_time_range
[]
=
{
0
,
0
,
2
,
3
,
3
,
4
,
4
};
static
u8
cycle_time_value
[][
XFER_UDMA_6
-
XFER_UDMA_0
+
1
]
=
{
{
0
,
0
,
0
,
0
,
0
,
0
,
0
},
/* no udma */
{
0
,
0
,
0
,
0
,
0
,
0
,
0
},
/* no udma */
{
3
,
2
,
1
,
0
,
0
,
0
,
0
},
/* ATA_33 */
{
7
,
5
,
3
,
2
,
1
,
0
,
0
},
/* ATA_66 */
{
7
,
5
,
3
,
2
,
1
,
0
,
0
},
/* ATA_100a (730 specific), differences are on cycle_time range and offset */
{
11
,
7
,
5
,
4
,
2
,
1
,
0
},
/* ATA_100 */
{
15
,
10
,
7
,
5
,
3
,
2
,
1
},
/* ATA_133a (earliest 691 southbridges) */
{
15
,
10
,
7
,
5
,
3
,
2
,
1
},
/* ATA_133 */
};
/* CRC Valid Setup Time vary accross IDE clock setting 33/66/100/133
See SiS962 data sheet for more detail */
static
u8
cvs_time_value
[][
XFER_UDMA_6
-
XFER_UDMA_0
+
1
]
=
{
{
0
,
0
,
0
,
0
,
0
,
0
,
0
},
/* no udma */
{
0
,
0
,
0
,
0
,
0
,
0
,
0
},
/* no udma */
{
2
,
1
,
1
,
0
,
0
,
0
,
0
},
{
4
,
3
,
2
,
1
,
0
,
0
,
0
},
{
4
,
3
,
2
,
1
,
0
,
0
,
0
},
{
6
,
4
,
3
,
1
,
1
,
1
,
0
},
{
9
,
6
,
4
,
2
,
2
,
2
,
2
},
{
9
,
6
,
4
,
2
,
2
,
2
,
2
},
};
/* Initialize time, Active time, Recovery time vary accross
IDE clock settings. These 3 arrays hold the register value
for PIO0/1/2/3/4 and DMA0/1/2 mode in order */
static
u8
ini_time_value
[][
8
]
=
{
{
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
},
{
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
},
{
2
,
1
,
0
,
0
,
0
,
1
,
0
,
0
},
{
4
,
3
,
1
,
1
,
1
,
3
,
1
,
1
},
{
4
,
3
,
1
,
1
,
1
,
3
,
1
,
1
},
{
6
,
4
,
2
,
2
,
2
,
4
,
2
,
2
},
{
9
,
6
,
3
,
3
,
3
,
6
,
3
,
3
},
{
9
,
6
,
3
,
3
,
3
,
6
,
3
,
3
},
};
static
u8
act_time_value
[][
8
]
=
{
{
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
},
{
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
},
{
9
,
9
,
9
,
2
,
2
,
7
,
2
,
2
},
{
19
,
19
,
19
,
5
,
4
,
14
,
5
,
4
},
{
19
,
19
,
19
,
5
,
4
,
14
,
5
,
4
},
{
28
,
28
,
28
,
7
,
6
,
21
,
7
,
6
},
{
38
,
38
,
38
,
10
,
9
,
28
,
10
,
9
},
{
38
,
38
,
38
,
10
,
9
,
28
,
10
,
9
},
};
static
u8
rco_time_value
[][
8
]
=
{
{
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
},
{
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
},
{
9
,
2
,
0
,
2
,
0
,
7
,
1
,
1
},
{
19
,
5
,
1
,
5
,
2
,
16
,
3
,
2
},
{
19
,
5
,
1
,
5
,
2
,
16
,
3
,
2
},
{
30
,
9
,
3
,
9
,
4
,
25
,
6
,
4
},
{
40
,
12
,
4
,
12
,
5
,
34
,
12
,
5
},
{
40
,
12
,
4
,
12
,
5
,
34
,
12
,
5
},
};
static
struct
pci_dev
*
host_dev
=
NULL
;
/*
* Printing configuration
*/
...
...
@@ -215,8 +247,8 @@ static struct pci_dev *host_dev = NULL;
#include <linux/stat.h>
#include <linux/proc_fs.h>
static
int
sis_get_info
(
char
*
,
char
**
,
off_t
,
int
)
;
extern
int
(
*
sis_display_info
)(
char
*
,
char
**
,
off_t
,
int
);
/* ide-proc.c */
static
u8
sis_proc
=
0
;
static
struct
pci_dev
*
bmide_dev
;
static
char
*
cable_type
[]
=
{
...
...
@@ -249,29 +281,38 @@ static char* cycle_time[] = {
"7 CLK"
,
"8 CLK"
,
"9 CLK"
,
"10 CLK"
,
"11 CLK"
,
"12 CLK"
,
"Reserved"
,
"Reserved"
,
"Reserved"
,
"Reserved"
"13 CLK"
,
"14 CLK"
,
"15 CLK"
,
"16 CLK"
};
static
char
*
chipset_capability
[]
=
{
"ATA"
,
"ATA 16"
,
"ATA 33"
,
"ATA 66"
,
"ATA 100"
,
"ATA 100"
,
"ATA 133"
,
"ATA 133"
};
/* Generic add master or slave info function */
static
char
*
get_drives_info
(
char
*
buffer
,
byte
pos
)
static
char
*
get_drives_info
(
char
*
buffer
,
u8
pos
)
{
byte
reg00
,
reg01
,
reg10
,
reg11
;
/* timing registers */
u8
reg00
,
reg01
,
reg10
,
reg11
;
/* timing registers */
char
*
p
=
buffer
;
/* Postwrite/Prefetch */
pci_read_config_byte
(
bmide_dev
,
0x4b
,
&
reg00
);
p
+=
sprintf
(
p
,
"Drive %d: Postwrite %s
\t
\t
Postwrite %s
\n
"
,
pos
,
(
reg00
&
(
0x10
<<
pos
))
?
"Enabled"
:
"Disabled"
,
(
reg00
&
(
0x40
<<
pos
))
?
"Enabled"
:
"Disabled"
);
p
+=
sprintf
(
p
,
" Prefetch %s
\t
\t
Prefetch %s
\n
"
,
(
reg00
&
(
0x01
<<
pos
))
?
"Enabled"
:
"Disabled"
,
(
reg00
&
(
0x04
<<
pos
))
?
"Enabled"
:
"Disabled"
);
pci_read_config_byte
(
bmide_dev
,
0x40
+
2
*
pos
,
&
reg00
);
pci_read_config_byte
(
bmide_dev
,
0x41
+
2
*
pos
,
&
reg01
);
pci_read_config_byte
(
bmide_dev
,
0x44
+
2
*
pos
,
&
reg10
);
pci_read_config_byte
(
bmide_dev
,
0x45
+
2
*
pos
,
&
reg11
);
if
(
chipset_family
<
ATA_133
)
{
pci_read_config_byte
(
bmide_dev
,
0x4b
,
&
reg00
);
p
+=
sprintf
(
p
,
"Drive %d: Postwrite %s
\t
\t
Postwrite %s
\n
"
,
pos
,
(
reg00
&
(
0x10
<<
pos
))
?
"Enabled"
:
"Disabled"
,
(
reg00
&
(
0x40
<<
pos
))
?
"Enabled"
:
"Disabled"
);
p
+=
sprintf
(
p
,
" Prefetch %s
\t
\t
Prefetch %s
\n
"
,
(
reg00
&
(
0x01
<<
pos
))
?
"Enabled"
:
"Disabled"
,
(
reg00
&
(
0x04
<<
pos
))
?
"Enabled"
:
"Disabled"
);
pci_read_config_byte
(
bmide_dev
,
0x40
+
2
*
pos
,
&
reg00
);
pci_read_config_byte
(
bmide_dev
,
0x41
+
2
*
pos
,
&
reg01
);
pci_read_config_byte
(
bmide_dev
,
0x44
+
2
*
pos
,
&
reg10
);
pci_read_config_byte
(
bmide_dev
,
0x45
+
2
*
pos
,
&
reg11
);
}
/* UDMA */
if
(
chipset_family
>=
ATA_33
)
{
...
...
@@ -284,7 +325,8 @@ static char* get_drives_info (char *buffer, byte pos)
case
ATA_33
:
p
+=
sprintf
(
p
,
cycle_time
[(
reg01
&
0x60
)
>>
5
]);
break
;
case
ATA_66
:
case
ATA_100a
:
p
+=
sprintf
(
p
,
cycle_time
[(
reg01
&
0x70
)
>>
4
]);
break
;
case
ATA_100
:
p
+=
sprintf
(
p
,
cycle_time
[
reg01
&
0x0F
]);
break
;
case
ATA_100
:
case
ATA_133a
:
p
+=
sprintf
(
p
,
cycle_time
[
reg01
&
0x0F
]);
break
;
case
ATA_133
:
default:
p
+=
sprintf
(
p
,
"133+ ?"
);
break
;
}
...
...
@@ -293,7 +335,8 @@ static char* get_drives_info (char *buffer, byte pos)
case
ATA_33
:
p
+=
sprintf
(
p
,
cycle_time
[(
reg11
&
0x60
)
>>
5
]);
break
;
case
ATA_66
:
case
ATA_100a
:
p
+=
sprintf
(
p
,
cycle_time
[(
reg11
&
0x70
)
>>
4
]);
break
;
case
ATA_100
:
p
+=
sprintf
(
p
,
cycle_time
[
reg11
&
0x0F
]);
break
;
case
ATA_100
:
case
ATA_133a
:
p
+=
sprintf
(
p
,
cycle_time
[
reg11
&
0x0F
]);
break
;
case
ATA_133
:
default:
p
+=
sprintf
(
p
,
"133+ ?"
);
break
;
}
...
...
@@ -308,7 +351,8 @@ static char* get_drives_info (char *buffer, byte pos)
case
ATA_33
:
case
ATA_66
:
case
ATA_100a
:
p
+=
sprintf
(
p
,
active_time
[
reg01
&
0x07
]);
break
;
case
ATA_100
:
p
+=
sprintf
(
p
,
active_time
[(
reg00
&
0x70
)
>>
4
]);
break
;
case
ATA_100
:
case
ATA_133a
:
p
+=
sprintf
(
p
,
active_time
[(
reg00
&
0x70
)
>>
4
]);
break
;
case
ATA_133
:
default:
p
+=
sprintf
(
p
,
"133+ ?"
);
break
;
}
...
...
@@ -319,7 +363,8 @@ static char* get_drives_info (char *buffer, byte pos)
case
ATA_33
:
case
ATA_66
:
case
ATA_100a
:
p
+=
sprintf
(
p
,
active_time
[
reg11
&
0x07
]);
break
;
case
ATA_100
:
p
+=
sprintf
(
p
,
active_time
[(
reg10
&
0x70
)
>>
4
]);
break
;
case
ATA_100
:
case
ATA_133a
:
p
+=
sprintf
(
p
,
active_time
[(
reg10
&
0x70
)
>>
4
]);
break
;
case
ATA_133
:
default:
p
+=
sprintf
(
p
,
"133+ ?"
);
break
;
}
...
...
@@ -327,8 +372,10 @@ static char* get_drives_info (char *buffer, byte pos)
/* Data Recovery */
/* warning: may need (reg&0x07) for pre ATA66 chips */
p
+=
sprintf
(
p
,
" Data Recovery Time %s
\t
Data Recovery Time %s
\n
"
,
recovery_time
[
reg00
&
0x0f
],
recovery_time
[
reg10
&
0x0f
]);
if
(
chipset_family
<
ATA_133
)
{
p
+=
sprintf
(
p
,
" Data Recovery Time %s
\t
Data Recovery Time %s
\n
"
,
recovery_time
[
reg00
&
0x0f
],
recovery_time
[
reg10
&
0x0f
]);
}
return
p
;
}
...
...
@@ -347,7 +394,7 @@ static char* get_slaves_info(char* buffer)
static
int
sis_get_info
(
char
*
buffer
,
char
**
addr
,
off_t
offset
,
int
count
)
{
char
*
p
=
buffer
;
byte
reg
;
u8
reg
;
u16
reg2
,
reg3
;
p
+=
sprintf
(
p
,
"
\n
SiS 5513 "
);
...
...
@@ -358,25 +405,34 @@ static int sis_get_info (char *buffer, char **addr, off_t offset, int count)
case
ATA_66
:
p
+=
sprintf
(
p
,
"Ultra 66"
);
break
;
case
ATA_100a
:
case
ATA_100
:
p
+=
sprintf
(
p
,
"Ultra 100"
);
break
;
case
ATA_133
:
default:
p
+=
sprintf
(
p
,
"Ultra 133+"
);
break
;
case
ATA_133a
:
case
ATA_133
:
p
+=
sprintf
(
p
,
"Ultra 133"
);
break
;
default:
p
+=
sprintf
(
p
,
"Unknown???"
);
break
;
}
p
+=
sprintf
(
p
,
" chipset
\n
"
);
p
+=
sprintf
(
p
,
"--------------- Primary Channel "
"---------------- Secondary Channel "
"-------------
\n
"
);
"---------------- Secondary Channel "
"-------------
\n
"
);
/* Status */
pci_read_config_byte
(
bmide_dev
,
0x4a
,
&
reg
);
if
(
chipset_family
==
ATA_133
)
{
pci_read_config_word
(
bmide_dev
,
0x50
,
&
reg2
);
pci_read_config_word
(
bmide_dev
,
0x52
,
&
reg3
);
}
p
+=
sprintf
(
p
,
"Channel Status: "
);
if
(
chipset_family
<
ATA_66
)
{
p
+=
sprintf
(
p
,
"%s
\t
\t
\t
\t
%s
\n
"
,
(
reg
&
0x04
)
?
"On"
:
"Off"
,
(
reg
&
0x02
)
?
"On"
:
"Off"
);
}
else
{
}
else
if
(
chipset_family
<
ATA_133
)
{
p
+=
sprintf
(
p
,
"%s
\t
\t
\t
\t
%s
\n
"
,
(
reg
&
0x02
)
?
"On"
:
"Off"
,
(
reg
&
0x04
)
?
"On"
:
"Off"
);
}
else
{
/* ATA_133 */
p
+=
sprintf
(
p
,
"%s
\t
\t
\t
\t
%s
\n
"
,
(
reg2
&
0x02
)
?
"On"
:
"Off"
,
(
reg3
&
0x02
)
?
"On"
:
"Off"
);
}
/* Operation Mode */
...
...
@@ -386,7 +442,11 @@ static int sis_get_info (char *buffer, char **addr, off_t offset, int count)
(
reg
&
0x04
)
?
"Native"
:
"Compatible"
);
/* 80-pin cable ? */
if
(
chipset_family
>
ATA_33
)
{
if
(
chipset_family
>=
ATA_133
)
{
p
+=
sprintf
(
p
,
"Cable Type: %s
\t
\t
\t
%s
\n
"
,
(
reg2
&
0x01
)
?
cable_type
[
1
]
:
cable_type
[
0
],
(
reg3
&
0x01
)
?
cable_type
[
1
]
:
cable_type
[
0
]);
}
else
if
(
chipset_family
>
ATA_33
)
{
pci_read_config_byte
(
bmide_dev
,
0x48
,
&
reg
);
p
+=
sprintf
(
p
,
"Cable Type: %s
\t
\t
\t
%s
\n
"
,
(
reg
&
0x10
)
?
cable_type
[
1
]
:
cable_type
[
0
],
...
...
@@ -394,10 +454,12 @@ static int sis_get_info (char *buffer, char **addr, off_t offset, int count)
}
/* Prefetch Count */
pci_read_config_word
(
bmide_dev
,
0x4c
,
&
reg2
);
pci_read_config_word
(
bmide_dev
,
0x4e
,
&
reg3
);
p
+=
sprintf
(
p
,
"Prefetch Count: %d
\t
\t
\t
\t
%d
\n
"
,
reg2
,
reg3
);
if
(
chipset_family
<
ATA_133
)
{
pci_read_config_word
(
bmide_dev
,
0x4c
,
&
reg2
);
pci_read_config_word
(
bmide_dev
,
0x4e
,
&
reg3
);
p
+=
sprintf
(
p
,
"Prefetch Count: %d
\t
\t
\t
\t
%d
\n
"
,
reg2
,
reg3
);
}
p
=
get_masters_info
(
p
);
p
=
get_slaves_info
(
p
);
...
...
@@ -406,51 +468,37 @@ static int sis_get_info (char *buffer, char **addr, off_t offset, int count)
}
#endif
/* defined(DISPLAY_SIS_TIMINGS) && defined(CONFIG_PROC_FS) */
byte
sis_proc
=
0
;
static
byte
sis5513_ratemask
(
ide_drive_t
*
drive
)
static
u8
sis5513_ratemask
(
ide_drive_t
*
drive
)
{
// struct pci_dev *dev = HWIF(drive)->pci_dev;
byte
mode
=
0x00
;
#if 0
u8 rates[] = { 0, 0, 1, 2, 3, 3, 4, 4 };
u8 mode = rates[chipset_family];
#else
u8
mode
;
switch
(
chipset_family
)
{
case
ATA_133
:
// { mode |= 0x04; break; }
case
ATA_133
:
case
ATA_133a
:
mode
=
4
;
break
;
case
ATA_100
:
case
ATA_100a
:
{
mode
|=
0x03
;
break
;
}
case
ATA_66
:
{
mode
|=
0x02
;
break
;
}
case
ATA_33
:
{
mode
|=
0x01
;
break
;
}
case
ATA_100a
:
mode
=
3
;
break
;
case
ATA_66
:
mode
=
2
;
break
;
case
ATA_33
:
return
1
;
case
ATA_16
:
case
ATA_00
:
default:
return
(
mode
&=
~
0xF8
);
}
if
(
!
eighty_ninty_three
(
drive
))
{
mode
&=
~
0xFE
;
mode
|=
0x01
;
}
return
(
mode
&=
~
0xF8
);
}
static
byte
sis5513_ratefilter
(
ide_drive_t
*
drive
,
byte
speed
)
{
#ifdef CONFIG_BLK_DEV_IDEDMA
byte
mode
=
sis5513_ratemask
(
drive
);
switch
(
mode
)
{
case
0x04
:
while
(
speed
>
XFER_UDMA_6
)
speed
--
;
break
;
case
0x03
:
while
(
speed
>
XFER_UDMA_5
)
speed
--
;
break
;
case
0x02
:
while
(
speed
>
XFER_UDMA_4
)
speed
--
;
break
;
case
0x01
:
while
(
speed
>
XFER_UDMA_2
)
speed
--
;
break
;
case
0x00
:
default:
while
(
speed
>
XFER_MW_DMA_2
)
speed
--
;
break
;
break
;
return
0
;
}
#else
while
(
speed
>
XFER_PIO_4
)
speed
--
;
#endif
/* CONFIG_BLK_DEV_IDEDMA */
// printk("%s: mode == %02x speed == %02x\n", drive->name, mode, speed);
return
speed
;
#endif
if
(
!
eighty_ninty_three
(
drive
))
mode
=
min
(
mode
,
(
u8
)
1
);
return
mode
;
}
/*
...
...
@@ -462,8 +510,8 @@ static void config_drive_art_rwp (ide_drive_t *drive)
ide_hwif_t
*
hwif
=
HWIF
(
drive
);
struct
pci_dev
*
dev
=
hwif
->
pci_dev
;
byte
reg4bh
=
0
;
byte
rw_prefetch
=
(
0x11
<<
drive
->
dn
);
u8
reg4bh
=
0
;
u8
rw_prefetch
=
(
0x11
<<
drive
->
dn
);
#ifdef DEBUG
printk
(
"SIS5513: config_drive_art_rwp, drive %d
\n
"
,
drive
->
dn
);
...
...
@@ -483,15 +531,15 @@ static void config_drive_art_rwp (ide_drive_t *drive)
/* Set per-drive active and recovery time */
static
void
config_art_rwp_pio
(
ide_drive_t
*
drive
,
byte
pio
)
static
void
config_art_rwp_pio
(
ide_drive_t
*
drive
,
u8
pio
)
{
ide_hwif_t
*
hwif
=
HWIF
(
drive
);
struct
pci_dev
*
dev
=
hwif
->
pci_dev
;
byte
timing
,
drive_pci
,
test1
,
test2
;
u8
timing
,
drive_pci
,
test1
,
test2
;
u
nsigned
short
eide_pio_timing
[
6
]
=
{
600
,
390
,
240
,
180
,
120
,
90
};
u
nsigned
short
xfer_pio
=
drive
->
id
->
eide_pio_modes
;
u
16
eide_pio_timing
[
6
]
=
{
600
,
390
,
240
,
180
,
120
,
90
};
u
16
xfer_pio
=
drive
->
id
->
eide_pio_modes
;
#ifdef DEBUG
sis5513_load_verify_registers
(
dev
,
"config_drive_art_rwp_pio start"
);
...
...
@@ -517,16 +565,21 @@ static void config_art_rwp_pio (ide_drive_t *drive, byte pio)
timing
=
(
xfer_pio
>=
pio
)
?
xfer_pio
:
pio
;
#ifdef DEBUG
printk
(
"SIS5513: config_drive_art_rwp_pio, drive %d, pio %d, timing %d
\n
"
,
printk
(
"SIS5513: config_drive_art_rwp_pio, "
"drive %d, pio %d, timing %d
\n
"
,
drive
->
dn
,
pio
,
timing
);
#endif
switch
(
drive
->
dn
)
{
case
0
:
drive_pci
=
0x40
;
break
;
case
1
:
drive_pci
=
0x42
;
break
;
case
2
:
drive_pci
=
0x44
;
break
;
case
3
:
drive_pci
=
0x46
;
break
;
default:
return
;
/* In pre ATA_133 case, drives sit at 0x40 + 4*drive->dn */
drive_pci
=
0x40
;
/* In SiS962 case drives sit at (0x40 or 0x70) + 8*drive->dn) */
if
(
chipset_family
>=
ATA_133
)
{
u32
reg54h
;
pci_read_config_dword
(
dev
,
0x54
,
&
reg54h
);
if
(
reg54h
&
0x40000000
)
drive_pci
=
0x70
;
drive_pci
+=
((
drive
->
dn
)
*
0x4
);
}
else
{
drive_pci
+=
((
drive
->
dn
)
*
0x2
);
}
/* register layout changed with newer ATA100 chips */
...
...
@@ -547,9 +600,9 @@ static void config_art_rwp_pio (ide_drive_t *drive, byte pio)
}
pci_write_config_byte
(
dev
,
drive_pci
,
test1
);
pci_write_config_byte
(
dev
,
drive_pci
+
1
,
test2
);
}
else
{
switch
(
timing
)
{
/*
active recovery
v v */
}
else
if
(
chipset_family
<
ATA_133
)
{
switch
(
timing
)
{
/*
active recovery
v v */
case
4
:
test1
=
0x30
|
0x01
;
break
;
case
3
:
test1
=
0x30
|
0x03
;
break
;
case
2
:
test1
=
0x40
|
0x04
;
break
;
...
...
@@ -557,6 +610,20 @@ static void config_art_rwp_pio (ide_drive_t *drive, byte pio)
default:
break
;
}
pci_write_config_byte
(
dev
,
drive_pci
,
test1
);
}
else
{
/* ATA_133 */
u32
test3
;
pci_read_config_dword
(
dev
,
drive_pci
,
&
test3
);
test3
&=
0xc0c00fff
;
if
(
test3
&
0x08
)
{
test3
|=
(
unsigned
long
)
ini_time_value
[
ATA_133
-
ATA_00
][
timing
]
<<
12
;
test3
|=
(
unsigned
long
)
act_time_value
[
ATA_133
-
ATA_00
][
timing
]
<<
16
;
test3
|=
(
unsigned
long
)
rco_time_value
[
ATA_133
-
ATA_00
][
timing
]
<<
24
;
}
else
{
test3
|=
(
unsigned
long
)
ini_time_value
[
ATA_100
-
ATA_00
][
timing
]
<<
12
;
test3
|=
(
unsigned
long
)
act_time_value
[
ATA_100
-
ATA_00
][
timing
]
<<
16
;
test3
|=
(
unsigned
long
)
rco_time_value
[
ATA_100
-
ATA_00
][
timing
]
<<
24
;
}
pci_write_config_dword
(
dev
,
drive_pci
,
test3
);
}
#ifdef DEBUG
...
...
@@ -564,9 +631,13 @@ static void config_art_rwp_pio (ide_drive_t *drive, byte pio)
#endif
}
static
int
config_chipset_for_pio
(
ide_drive_t
*
drive
,
byte
pio
)
static
int
config_chipset_for_pio
(
ide_drive_t
*
drive
,
u8
pio
)
{
byte
speed
;
#if 0
config_art_rwp_pio(drive, pio);
return ide_config_drive_speed(drive, (XFER_PIO_0 + pio));
#else
u8
speed
;
switch
(
pio
)
{
case
4
:
speed
=
XFER_PIO_4
;
break
;
...
...
@@ -577,67 +648,93 @@ static int config_chipset_for_pio (ide_drive_t *drive, byte pio)
}
config_art_rwp_pio
(
drive
,
pio
);
return
(
ide_config_drive_speed
(
drive
,
speed
));
return
ide_config_drive_speed
(
drive
,
speed
);
#endif
}
static
int
sis5513_tune_chipset
(
ide_drive_t
*
drive
,
byte
xferspeed
)
static
int
sis5513_tune_chipset
(
ide_drive_t
*
drive
,
u8
xferspeed
)
{
ide_hwif_t
*
hwif
=
HWIF
(
drive
);
struct
pci_dev
*
dev
=
hwif
->
pci_dev
;
byte
speed
=
sis5513_ratefilter
(
drive
,
xferspeed
);
byte
drive_pci
,
reg
;
u8
drive_pci
,
reg
;
u32
regdw
;
#ifdef DEBUG
sis5513_load_verify_registers
(
dev
,
"sis5513_tune_chipset start"
);
printk
(
"SIS5513: sis5513_tune_chipset, drive %d, speed %d
\n
"
,
drive
->
dn
,
speed
);
#endif
#if 1
switch
(
drive
->
dn
)
{
case
0
:
drive_pci
=
0x40
;
break
;
case
1
:
drive_pci
=
0x42
;
break
;
case
2
:
drive_pci
=
0x44
;
break
;
case
3
:
drive_pci
=
0x46
;
break
;
default:
return
ide_dma_off
;
}
#else
// drive_pci = (0x40 + ((drive->dn) *2));
// drive_pci = 0x40;
// drive_pci |= ((drive->dn) << 1);
#endif
#ifdef BROKEN_LEVEL
#ifdef DEBUG
printk
(
"SIS5513: BROKEN_LEVEL activated, speed=%d -> speed=%d
\n
"
,
speed
,
BROKEN_LEVEL
);
printk
(
"SIS5513: BROKEN_LEVEL activated, speed=%d -> speed=%d
\n
"
,
xfer
speed
,
BROKEN_LEVEL
);
#endif
if
(
speed
>
BROKEN_LEVEL
)
speed
=
BROKEN_LEVEL
;
if
(
xferspeed
>
BROKEN_LEVEL
)
xfer
speed
=
BROKEN_LEVEL
;
#endif
pci_read_config_byte
(
dev
,
drive_pci
+
1
,
&
reg
);
/* Disable UDMA bit for non UDMA modes on UDMA chips */
if
((
speed
<
XFER_UDMA_0
)
&&
(
chipset_family
>
ATA_16
))
{
reg
&=
0x7F
;
pci_write_config_byte
(
dev
,
drive_pci
+
1
,
reg
);
u8
speed
=
ide_rate_filter
(
sis5513_ratemask
(
drive
),
xferspeed
);
/* See config_art_rwp_pio for drive pci config registers */
drive_pci
=
0x40
;
if
(
chipset_family
>=
ATA_133
)
{
u32
reg54h
;
pci_read_config_dword
(
dev
,
0x54
,
&
reg54h
);
if
(
reg54h
&
0x40000000
)
drive_pci
=
0x70
;
drive_pci
+=
((
drive
->
dn
)
*
0x4
);
pci_read_config_dword
(
dev
,
(
unsigned
long
)
drive_pci
,
&
regdw
);
/* Disable UDMA bit for non UDMA modes on UDMA chips */
if
(
speed
<
XFER_UDMA_0
)
{
regdw
&=
0xfffffffb
;
pci_write_config_dword
(
dev
,
(
unsigned
long
)
drive_pci
,
regdw
);
}
}
else
{
drive_pci
+=
((
drive
->
dn
)
*
0x2
);
pci_read_config_byte
(
dev
,
drive_pci
+
1
,
&
reg
);
/* Disable UDMA bit for non UDMA modes on UDMA chips */
if
((
speed
<
XFER_UDMA_0
)
&&
(
chipset_family
>
ATA_16
))
{
reg
&=
0x7F
;
pci_write_config_byte
(
dev
,
drive_pci
+
1
,
reg
);
}
}
/* Config chip for mode */
switch
(
speed
)
{
#ifdef CONFIG_BLK_DEV_IDEDMA
case
XFER_UDMA_6
:
case
XFER_UDMA_5
:
case
XFER_UDMA_4
:
case
XFER_UDMA_3
:
case
XFER_UDMA_2
:
case
XFER_UDMA_1
:
case
XFER_UDMA_0
:
/* Force the UDMA bit on if we want to use UDMA */
reg
|=
0x80
;
/* clean reg cycle time bits */
reg
&=
~
((
0xFF
>>
(
8
-
cycle_time_range
[
chipset_family
]))
<<
cycle_time_offset
[
chipset_family
]);
/* set reg cycle time bits */
reg
|=
cycle_time_value
[
chipset_family
-
ATA_00
][
speed
-
XFER_UDMA_0
]
<<
cycle_time_offset
[
chipset_family
];
pci_write_config_byte
(
dev
,
drive_pci
+
1
,
reg
);
if
(
chipset_family
>=
ATA_133
)
{
regdw
|=
0x04
;
regdw
&=
0xfffff00f
;
/* check if ATA133 enable */
if
(
regdw
&
0x08
)
{
regdw
|=
(
unsigned
long
)
cycle_time_value
[
ATA_133
-
ATA_00
][
speed
-
XFER_UDMA_0
]
<<
4
;
regdw
|=
(
unsigned
long
)
cvs_time_value
[
ATA_133
-
ATA_00
][
speed
-
XFER_UDMA_0
]
<<
8
;
}
else
{
/* if ATA133 disable, we should not set speed above UDMA5 */
if
(
speed
>
XFER_UDMA_5
)
speed
=
XFER_UDMA_5
;
regdw
|=
(
unsigned
long
)
cycle_time_value
[
ATA_100
-
ATA_00
][
speed
-
XFER_UDMA_0
]
<<
4
;
regdw
|=
(
unsigned
long
)
cvs_time_value
[
ATA_100
-
ATA_00
][
speed
-
XFER_UDMA_0
]
<<
8
;
}
pci_write_config_dword
(
dev
,
(
unsigned
long
)
drive_pci
,
regdw
);
}
else
{
/* Force the UDMA bit on if we want to use UDMA */
reg
|=
0x80
;
/* clean reg cycle time bits */
reg
&=
~
((
0xFF
>>
(
8
-
cycle_time_range
[
chipset_family
]))
<<
cycle_time_offset
[
chipset_family
]);
/* set reg cycle time bits */
reg
|=
cycle_time_value
[
chipset_family
-
ATA_00
][
speed
-
XFER_UDMA_0
]
<<
cycle_time_offset
[
chipset_family
];
pci_write_config_byte
(
dev
,
drive_pci
+
1
,
reg
);
}
break
;
case
XFER_MW_DMA_2
:
case
XFER_MW_DMA_1
:
...
...
@@ -660,7 +757,7 @@ static int sis5513_tune_chipset (ide_drive_t *drive, byte xferspeed)
return
((
int
)
ide_config_drive_speed
(
drive
,
speed
));
}
static
void
sis5513_tune_drive
(
ide_drive_t
*
drive
,
byte
pio
)
static
void
sis5513_tune_drive
(
ide_drive_t
*
drive
,
u8
pio
)
{
(
void
)
config_chipset_for_pio
(
drive
,
pio
);
}
...
...
@@ -671,127 +768,75 @@ static void sis5513_tune_drive (ide_drive_t *drive, byte pio)
*/
static
int
config_chipset_for_dma
(
ide_drive_t
*
drive
)
{
struct
hd_driveid
*
id
=
drive
->
id
;
byte
mode
=
sis5513_ratemask
(
drive
);
byte
speed
=
0
;
u8
speed
=
ide_dma_speed
(
drive
,
sis5513_ratemask
(
drive
));
#ifdef DEBUG
printk
(
"SIS5513: config_chipset_for_dma, drive %d
ultra %d
\n
"
,
drive
->
dn
,
mode
);
printk
(
"SIS5513: config_chipset_for_dma, drive %d
, ultra %x, udma_66 %x
\n
"
,
drive
->
dn
,
drive
->
id
->
dma_ultra
);
#endif
switch
(
mode
)
{
case
0x04
:
if
(
id
->
dma_ultra
&
0x0040
)
{
speed
=
XFER_UDMA_6
;
break
;
}
case
0x03
:
if
(
id
->
dma_ultra
&
0x0020
)
{
speed
=
XFER_UDMA_5
;
break
;
}
case
0x02
:
if
(
id
->
dma_ultra
&
0x0010
)
{
speed
=
XFER_UDMA_4
;
break
;
}
if
(
id
->
dma_ultra
&
0x0008
)
{
speed
=
XFER_UDMA_3
;
break
;
}
case
0x01
:
if
(
id
->
dma_ultra
&
0x0004
)
{
speed
=
XFER_UDMA_2
;
break
;
}
if
(
id
->
dma_ultra
&
0x0002
)
{
speed
=
XFER_UDMA_1
;
break
;
}
if
(
id
->
dma_ultra
&
0x0001
)
{
speed
=
XFER_UDMA_0
;
break
;
}
case
0x00
:
if
(
id
->
dma_mword
&
0x0004
)
{
speed
=
XFER_MW_DMA_2
;
break
;
}
if
(
id
->
dma_mword
&
0x0002
)
{
speed
=
XFER_MW_DMA_1
;
break
;
}
if
(
id
->
dma_mword
&
0x0001
)
{
speed
=
XFER_MW_DMA_0
;
break
;
}
if
(
id
->
dma_1word
&
0x0004
)
{
speed
=
XFER_SW_DMA_2
;
break
;
}
if
(
id
->
dma_1word
&
0x0002
)
{
speed
=
XFER_SW_DMA_1
;
break
;
}
if
(
id
->
dma_1word
&
0x0001
)
{
speed
=
XFER_SW_DMA_0
;
break
;
}
default:
return
((
int
)
ide_dma_off_quietly
);
}
if
(
!
(
speed
))
return
0
;
sis5513_tune_chipset
(
drive
,
speed
);
// return ((int) ide_dma_on);
return
((
int
)
((
id
->
dma_ultra
>>
14
)
&
3
)
?
ide_dma_on
:
((
id
->
dma_ultra
>>
11
)
&
7
)
?
ide_dma_on
:
((
id
->
dma_ultra
>>
8
)
&
7
)
?
ide_dma_on
:
((
id
->
dma_mword
>>
8
)
&
7
)
?
ide_dma_on
:
((
id
->
dma_1word
>>
8
)
&
7
)
?
ide_dma_on
:
ide_dma_off_quietly
);
return
ide_dma_enable
(
drive
);
}
static
int
config_drive_xfer_rate
(
ide_drive_t
*
drive
)
static
int
sis5513_
config_drive_xfer_rate
(
ide_drive_t
*
drive
)
{
struct
hd_driveid
*
id
=
drive
->
id
;
ide_dma_action_t
dma_func
=
ide_dma_off_quietly
;
ide_hwif_t
*
hwif
=
HWIF
(
drive
)
;
struct
hd_driveid
*
id
=
drive
->
id
;
drive
->
init_speed
=
0
;
if
(
id
&&
(
id
->
capability
&
1
)
&&
HWIF
(
drive
)
->
autodma
)
{
if
(
id
&&
(
id
->
capability
&
1
)
&&
drive
->
autodma
)
{
/* Consult the list of known "bad" drives */
if
(
ide_dmaproc
(
ide_dma_bad_drive
,
drive
))
{
dma_func
=
ide_dma_off
;
if
(
hwif
->
ide_dma_bad_drive
(
drive
))
goto
fast_ata_pio
;
}
dma_func
=
ide_dma_off_quietly
;
if
(
id
->
field_valid
&
4
)
{
if
(
id
->
dma_ultra
&
0x003F
)
{
if
(
id
->
dma_ultra
&
hwif
->
ultra_mask
)
{
/* Force if Capable UltraDMA */
dma_func
=
config_chipset_for_dma
(
drive
);
if
((
id
->
field_valid
&
2
)
&&
(
dma_func
!=
ide_dma_on
))
int
dma
=
config_chipset_for_dma
(
drive
);
if
((
id
->
field_valid
&
2
)
&&
!
dma
)
goto
try_dma_modes
;
}
}
else
if
(
id
->
field_valid
&
2
)
{
try_dma_modes:
if
((
id
->
dma_mword
&
0x0007
)
||
(
id
->
dma_1word
&
0x0007
))
{
if
((
id
->
dma_mword
&
hwif
->
mwdma_mask
)
||
(
id
->
dma_1word
&
hwif
->
swdma_mask
))
{
/* Force if Capable regular DMA modes */
dma_func
=
config_chipset_for_dma
(
drive
);
if
(
dma_func
!=
ide_dma_on
)
if
(
!
config_chipset_for_dma
(
drive
))
goto
no_dma_set
;
}
}
else
if
(
(
ide_dmaproc
(
ide_dma_good_drive
,
drive
)
)
&&
(
id
->
eide_dma_time
>
150
))
{
}
else
if
(
hwif
->
ide_dma_good_drive
(
drive
)
&&
(
id
->
eide_dma_time
<
150
))
{
/* Consult the list of known "good" drives */
dma_func
=
config_chipset_for_dma
(
drive
);
if
(
dma_func
!=
ide_dma_on
)
if
(
!
config_chipset_for_dma
(
drive
))
goto
no_dma_set
;
}
else
{
goto
fast_ata_pio
;
}
}
else
if
((
id
->
capability
&
8
)
||
(
id
->
field_valid
&
2
))
{
fast_ata_pio:
dma_func
=
ide_dma_off_quietly
;
no_dma_set:
sis5513_tune_drive
(
drive
,
5
);
return
hwif
->
ide_dma_off_quietly
(
drive
);
}
return
HWIF
(
drive
)
->
dmaproc
(
dma_func
,
drive
);
return
hwif
->
ide_dma_on
(
drive
);
}
/* initiates/aborts (U)DMA read/write operations on a drive. */
int
sis5513_dmaproc
(
ide_dma_action_t
func
,
ide_drive_t
*
drive
)
static
int
sis5513_config_xfer_rate
(
ide_drive_t
*
drive
)
{
switch
(
func
)
{
case
ide_dma_check
:
config_drive_art_rwp
(
drive
);
config_art_rwp_pio
(
drive
,
5
);
return
config_drive_xfer_rate
(
drive
);
default:
break
;
}
return
ide_dmaproc
(
func
,
drive
);
/* use standard DMA stuff */
config_drive_art_rwp
(
drive
);
config_art_rwp_pio
(
drive
,
5
);
return
sis5513_config_drive_xfer_rate
(
drive
);
}
#endif
/* CONFIG_BLK_DEV_IDEDMA */
/* Chip detection and general config */
unsigned
int
__init
pci_ini
t_sis5513
(
struct
pci_dev
*
dev
,
const
char
*
name
)
static
unsigned
int
__init
init_chipse
t_sis5513
(
struct
pci_dev
*
dev
,
const
char
*
name
)
{
struct
pci_dev
*
host
;
int
i
=
0
;
...
...
@@ -806,7 +851,37 @@ unsigned int __init pci_init_sis5513 (struct pci_dev *dev, const char *name)
host_dev
=
host
;
chipset_family
=
SiSHostChipInfo
[
i
].
chipset_family
;
/* check 100/133 chipset family */
if
(
chipset_family
==
ATA_133
)
{
u32
reg54h
;
u16
reg02h
;
pci_read_config_dword
(
dev
,
0x54
,
&
reg54h
);
pci_write_config_dword
(
dev
,
0x54
,
(
reg54h
&
0x7fffffff
));
pci_read_config_word
(
dev
,
0x02
,
&
reg02h
);
pci_write_config_dword
(
dev
,
0x54
,
reg54h
);
/* devid 5518 here means SiS962 or later
which supports ATA133 */
if
(
reg02h
!=
0x5518
)
{
u8
reg49h
;
unsigned
long
sbrev
;
/* SiS961 family */
/*
* FIXME !!! GAK!!!!!!!!!! PCI DIRECT POKING
*/
outl
(
0x80001008
,
0x0cf8
);
sbrev
=
inl
(
0x0cfc
);
pci_read_config_byte
(
dev
,
0x49
,
&
reg49h
);
if
(((
sbrev
&
0xff
)
==
0x10
)
&&
(
reg49h
&
0x80
))
chipset_family
=
ATA_133a
;
else
chipset_family
=
ATA_100
;
}
}
printk
(
SiSHostChipInfo
[
i
].
name
);
printk
(
" %s controller"
,
chipset_capability
[
chipset_family
]);
printk
(
"
\n
"
);
#ifdef DEBUG
...
...
@@ -814,7 +889,7 @@ unsigned int __init pci_init_sis5513 (struct pci_dev *dev, const char *name)
#endif
if
(
SiSHostChipInfo
[
i
].
flags
&
SIS5513_LATENCY
)
{
byte
latency
=
(
chipset_family
==
ATA_100
)
?
0x80
:
0x10
;
/* Lacking specs */
u8
latency
=
(
chipset_family
==
ATA_100
)
?
0x80
:
0x10
;
/* Lacking specs */
pci_write_config_byte
(
dev
,
PCI_LATENCY_TIMER
,
latency
);
}
}
...
...
@@ -823,9 +898,19 @@ unsigned int __init pci_init_sis5513 (struct pci_dev *dev, const char *name)
1/ tell IDE channels to operate in Compabitility mode only
2/ tell old chips to allow per drive IDE timings */
if
(
host_dev
)
{
byte
reg
;
u8
reg
;
u16
regw
;
switch
(
chipset_family
)
{
case
ATA_133
:
/* SiS962 operation mode */
pci_read_config_word
(
dev
,
0x50
,
&
regw
);
if
(
regw
&
0x08
)
pci_write_config_word
(
dev
,
0x50
,
regw
&
0xfff7
);
pci_read_config_word
(
dev
,
0x52
,
&
regw
);
if
(
regw
&
0x08
)
pci_write_config_word
(
dev
,
0x52
,
regw
&
0xfff7
);
break
;
case
ATA_133a
:
case
ATA_100
:
/* Set compatibility bit */
pci_read_config_byte
(
dev
,
0x49
,
&
reg
);
...
...
@@ -863,7 +948,7 @@ unsigned int __init pci_init_sis5513 (struct pci_dev *dev, const char *name)
if
(
!
sis_proc
)
{
sis_proc
=
1
;
bmide_dev
=
dev
;
sis_display_info
=
&
sis_get_info
;
ide_pci_register_host_proc
(
&
sis_procs
[
0
])
;
}
#endif
}
...
...
@@ -873,55 +958,90 @@ unsigned int __init pci_init_sis5513 (struct pci_dev *dev, const char *name)
return
0
;
}
unsigned
int
__init
ata66_sis5513
(
ide_hwif_t
*
hwif
)
static
unsigned
int
__init
ata66_sis5513
(
ide_hwif_t
*
hwif
)
{
byte
reg48h
=
0
,
ata66
=
0
;
byte
mask
=
hwif
->
channel
?
0x20
:
0x10
;
pci_read_config_byte
(
hwif
->
pci_dev
,
0x48
,
&
reg48h
);
if
(
chipset_family
>=
ATA_66
)
{
u8
ata66
=
0
;
if
(
chipset_family
>=
ATA_133
)
{
u16
regw
=
0
;
u16
reg_addr
=
hwif
->
channel
?
0x52
:
0x50
;
pci_read_config_word
(
hwif
->
pci_dev
,
reg_addr
,
&
regw
);
ata66
=
(
regw
&
0x8000
)
?
0
:
1
;
}
else
if
(
chipset_family
>=
ATA_66
)
{
u8
reg48h
=
0
;
u8
mask
=
hwif
->
channel
?
0x20
:
0x10
;
pci_read_config_byte
(
hwif
->
pci_dev
,
0x48
,
&
reg48h
);
ata66
=
(
reg48h
&
mask
)
?
0
:
1
;
}
return
ata66
;
}
void
__init
ide_init
_sis5513
(
ide_hwif_t
*
hwif
)
static
void
__init
init_hwif
_sis5513
(
ide_hwif_t
*
hwif
)
{
hwif
->
autodma
=
0
;
hwif
->
irq
=
hwif
->
channel
?
15
:
14
;
if
(
!
hwif
->
irq
)
hwif
->
irq
=
hwif
->
channel
?
15
:
14
;
hwif
->
tuneproc
=
&
sis5513_tune_drive
;
hwif
->
speedproc
=
&
sis5513_tune_chipset
;
hwif
->
drives
[
0
].
autotune
=
1
;
hwif
->
drives
[
1
].
autotune
=
1
;
hwif
->
autodma
=
0
;
if
(
!
(
hwif
->
dma_base
))
if
(
!
(
hwif
->
dma_base
))
{
hwif
->
drives
[
0
].
autotune
=
1
;
hwif
->
drives
[
1
].
autotune
=
1
;
return
;
}
hwif
->
atapi_dma
=
1
;
hwif
->
ultra_mask
=
0x7f
;
hwif
->
mwdma_mask
=
0x07
;
hwif
->
swdma_mask
=
0x07
;
#ifdef CONFIG_BLK_DEV_IDEDMA
if
(
host_dev
)
{
if
(
chipset_family
>
ATA_16
)
hwif
->
dmaproc
=
&
sis5513_dmaproc
;
else
hwif
->
autodma
=
0
;
if
(
!
host_dev
)
return
;
if
(
!
(
hwif
->
udma_four
))
hwif
->
udma_four
=
ata66_sis5513
(
hwif
);
if
(
chipset_family
>
ATA_16
)
{
hwif
->
ide_dma_check
=
&
sis5513_config_xfer_rate
;
if
(
!
noautodma
)
hwif
->
autodma
=
1
;
}
# ifdef CONFIG_IDEDMA_AUTO
if
(
!
noautodma
)
hwif
->
autodma
=
1
;
# endif
/* CONFIG_IDEDMA_AUTO */
#endif
/* CONFIG_BLK_DEV_IDEDMA */
hwif
->
drives
[
0
].
autodma
=
hwif
->
autodma
;
hwif
->
drives
[
1
].
autodma
=
hwif
->
autodma
;
#endif
return
;
}
extern
void
ide_setup_pci_device
(
struct
pci_dev
*
dev
,
ide_pci_device_t
*
d
);
void
__init
fixup_device_sis5513
(
struct
pci_dev
*
dev
,
ide_pci_device_t
*
d
)
static
void
__init
init_dma_sis5513
(
ide_hwif_t
*
hwif
,
unsigned
long
dmabase
)
{
if
(
dev
->
resource
[
0
].
start
!=
0x01F1
)
ide_register_xp_fix
(
dev
);
ide_setup_dma
(
hwif
,
dmabase
,
8
);
}
extern
void
ide_setup_pci_device
(
struct
pci_dev
*
,
ide_pci_device_t
*
);
printk
(
"%s: IDE controller on PCI bus %02x dev %02x
\n
"
,
d
->
name
,
dev
->
bus
->
number
,
dev
->
devfn
);
static
void
__init
init_setup_sis5513
(
struct
pci_dev
*
dev
,
ide_pci_device_t
*
d
)
{
ide_setup_pci_device
(
dev
,
d
);
}
int
__init
sis5513_scan_pcidev
(
struct
pci_dev
*
dev
)
{
ide_pci_device_t
*
d
;
if
(
dev
->
vendor
!=
PCI_VENDOR_ID_SI
)
return
0
;
for
(
d
=
sis5513_chipsets
;
d
&&
d
->
vendor
&&
d
->
device
;
++
d
)
{
if
(((
d
->
vendor
==
dev
->
vendor
)
&&
(
d
->
device
==
dev
->
device
))
&&
(
d
->
init_setup
))
{
d
->
init_setup
(
dev
,
d
);
return
1
;
}
}
return
0
;
}
drivers/ide/pci/sis5513.h
0 → 100644
View file @
9382310f
#ifndef SIS5513_H
#define SIS5513_H
#include <linux/config.h>
#include <linux/pci.h>
#include <linux/ide.h>
#define DISPLAY_SIS_TIMINGS
#if defined(DISPLAY_SIS_TIMINGS) && defined(CONFIG_PROC_FS)
#include <linux/stat.h>
#include <linux/proc_fs.h>
static
u8
sis_proc
;
static
int
sis_get_info
(
char
*
,
char
**
,
off_t
,
int
);
static
ide_pci_host_proc_t
sis_procs
[]
__initdata
=
{
{
name:
"sis"
,
set:
1
,
get_info:
sis_get_info
,
parent:
NULL
,
},
};
#endif
/* defined(DISPLAY_SIS_TIMINGS) && defined(CONFIG_PROC_FS) */
static
void
init_setup_sis5513
(
struct
pci_dev
*
,
ide_pci_device_t
*
);
static
unsigned
int
init_chipset_sis5513
(
struct
pci_dev
*
,
const
char
*
);
static
void
init_hwif_sis5513
(
ide_hwif_t
*
);
static
void
init_dma_sis5513
(
ide_hwif_t
*
,
unsigned
long
);
static
ide_pci_device_t
sis5513_chipsets
[]
__initdata
=
{
{
vendor:
PCI_VENDOR_ID_SI
,
device:
PCI_DEVICE_ID_SI_5513
,
name:
"SIS5513"
,
init_setup:
init_setup_sis5513
,
init_chipset:
init_chipset_sis5513
,
init_iops:
NULL
,
init_hwif:
init_hwif_sis5513
,
init_dma:
init_dma_sis5513
,
channels:
2
,
autodma:
NOAUTODMA
,
enablebits:
{{
0x4a
,
0x02
,
0x02
},
{
0x4a
,
0x04
,
0x04
}},
bootable:
ON_BOARD
,
extra:
0
},{
vendor:
0
,
device:
0
,
channels:
0
,
bootable:
EOL
,
}
};
#endif
/* SIS5513_H */
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