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
e686e408
Commit
e686e408
authored
Sep 11, 2002
by
Jens Axboe
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
slc90e66 update
parent
520da1fa
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
155 additions
and
178 deletions
+155
-178
drivers/ide/pci/slc90e66.c
drivers/ide/pci/slc90e66.c
+97
-178
drivers/ide/pci/slc90e66.h
drivers/ide/pci/slc90e66.h
+58
-0
No files found.
drivers/ide/pci/slc90e66.c
View file @
e686e408
/*
* linux/drivers/ide/slc90e66.c Version 0.10 October 4, 2000
*
* Copyright (C) 2000 Andre Hedrick <andre@linux-ide.org>
* May be copied or modified under the terms of the GNU General Public License
*
* 00:07.1 IDE interface: EFAR Microsystems:
* Unknown device 9130 (prog-if 8a [Master SecP PriP])
* Control: I/O+ Mem- BusMaster+ SpecCycle- MemWINV-
* VGASnoop- ParErr- Stepping- SERR- FastB2B-
* Status: Cap- 66Mhz- UDF- FastB2B- ParErr- DEVSEL=medium
* >TAbort- <TAbort- <MAbort- >SERR- <PERR-
* Latency: 64
* Interrupt: pin A routed to IRQ 255
* Region 4: I/O ports at 1050
*
* 00: 55 10 30 91 05 00 00 02 00 8a 01 01 00 40 00 00
* 10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
* 20: 51 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00
* 30: 00 00 00 00 00 00 00 00 00 00 00 00 ff 01 00 00
* 40: 37 e3 33 e3 b9 55 01 00 0d 00 04 22 00 00 00 00
* 50: 00 00 ff a0 00 00 00 08 40 00 00 00 00 00 00 00
* 60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
* 70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
* 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
* 90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
* a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
* b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
* c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
* d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
* e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
* f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
* Copyright (C) 2000-2002 Andre Hedrick <andre@linux-ide.org>
*
* This a look-a-like variation of the ICH0 PIIX4 Ultra-66,
* but this keeps the ISA-Bridge and slots alive.
...
...
@@ -49,17 +21,13 @@
#include <asm/io.h>
#include "ide_modes.h"
#define SLC90E66_DEBUG_DRIVE_INFO 0
#define DISPLAY_SLC90E66_TIMINGS
#include "slc90e66.h"
#if defined(DISPLAY_SLC90E66_TIMINGS) && defined(CONFIG_PROC_FS)
#include <linux/stat.h>
#include <linux/proc_fs.h>
static
int
slc90e66_get_info
(
char
*
,
char
**
,
off_t
,
int
);
extern
int
(
*
slc90e66_display_info
)(
char
*
,
char
**
,
off_t
,
int
);
/* ide-proc.c */
static
u8
slc90e66_proc
=
0
;
static
struct
pci_dev
*
bmide_dev
;
static
int
slc90e66_get_info
(
char
*
buffer
,
char
**
addr
,
off_t
offset
,
int
count
)
...
...
@@ -85,13 +53,8 @@ static int slc90e66_get_info (char *buffer, char **addr, off_t offset, int count
* at that point bibma+0x2 et bibma+0xa are byte registers
* to investigate:
*/
#ifdef __mips__
/* only for mips? */
c0
=
inb_p
(
bibma
+
0x02
);
c1
=
inb_p
(
bibma
+
0x0a
);
#else
c0
=
inb_p
((
unsigned
short
)
bibma
+
0x02
);
c1
=
inb_p
((
unsigned
short
)
bibma
+
0x0a
);
#endif
p
+=
sprintf
(
p
,
" SLC90E66 Chipset.
\n
"
);
p
+=
sprintf
(
p
,
"--------------- Primary Channel "
...
...
@@ -150,47 +113,16 @@ static int slc90e66_get_info (char *buffer, char **addr, off_t offset, int count
}
#endif
/* defined(DISPLAY_SLC90E66_TIMINGS) && defined(CONFIG_PROC_FS) */
/*
* Used to set Fifo configuration via kernel command line:
*/
byte
slc90e66_proc
=
0
;
static
byte
slc90e66_ratemask
(
ide_drive_t
*
drive
)
static
u8
slc90e66_ratemask
(
ide_drive_t
*
drive
)
{
byte
mode
=
0x00
;
mode
|=
0x02
;
u8
mode
=
2
;
if
(
!
eighty_ninty_three
(
drive
))
{
mode
&=
~
0xFE
;
mode
|=
0x01
;
}
return
(
mode
&=
~
0xF8
);
}
static
byte
slc90e66_ratefilter
(
ide_drive_t
*
drive
,
byte
speed
)
{
#ifdef CONFIG_BLK_DEV_IDEDMA
byte
mode
=
slc90e66_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
;
}
#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
;
if
(
!
eighty_ninty_three
(
drive
))
mode
=
min
(
mode
,
(
u8
)
1
);
return
mode
;
}
static
byte
slc90e66_dma_2_pio
(
byte
xfer_rate
)
{
static
u8
slc90e66_dma_2_pio
(
u8
xfer_rate
)
{
switch
(
xfer_rate
)
{
case
XFER_UDMA_4
:
case
XFER_UDMA_3
:
...
...
@@ -221,7 +153,7 @@ static byte slc90e66_dma_2_pio (byte xfer_rate) {
* Based on settings done by AMI BIOS
* (might be useful if drive is not registered in CMOS for any reason).
*/
static
void
slc90e66_tune_drive
(
ide_drive_t
*
drive
,
byte
pio
)
static
void
slc90e66_tune_drive
(
ide_drive_t
*
drive
,
u8
pio
)
{
ide_hwif_t
*
hwif
=
HWIF
(
drive
);
struct
pci_dev
*
dev
=
hwif
->
pci_dev
;
...
...
@@ -230,9 +162,9 @@ static void slc90e66_tune_drive (ide_drive_t *drive, byte pio)
int
slave_port
=
0x44
;
unsigned
long
flags
;
u16
master_data
;
byte
slave_data
;
u8
slave_data
;
/* ISP RTC */
byte
timings
[][
2
]
=
{
{
0
,
0
},
u8
timings
[][
2
]
=
{
{
0
,
0
},
{
0
,
0
},
{
1
,
0
},
{
2
,
1
},
...
...
@@ -262,17 +194,15 @@ static void slc90e66_tune_drive (ide_drive_t *drive, byte pio)
spin_unlock_irqrestore
(
&
ide_lock
,
flags
);
}
static
int
slc90e66_tune_chipset
(
ide_drive_t
*
drive
,
byte
xferspeed
)
static
int
slc90e66_tune_chipset
(
ide_drive_t
*
drive
,
u8
xferspeed
)
{
ide_hwif_t
*
hwif
=
HWIF
(
drive
);
struct
pci_dev
*
dev
=
hwif
->
pci_dev
;
byte
maslave
=
hwif
->
channel
?
0x42
:
0x40
;
byte
speed
=
slc90e66_ratefilter
(
drive
,
xferspeed
);
int
a_speed
=
7
<<
(
drive
->
dn
*
4
);
int
u_flag
=
1
<<
drive
->
dn
;
int
u_speed
=
0
;
int
sitre
;
short
reg4042
,
reg44
,
reg48
,
reg4a
;
u8
maslave
=
hwif
->
channel
?
0x42
:
0x40
;
u8
speed
=
ide_rate_filter
(
slc90e66_ratemask
(
drive
),
xferspeed
);
int
sitre
=
0
,
a_speed
=
7
<<
(
drive
->
dn
*
4
);
int
u_speed
=
0
,
u_flag
=
1
<<
drive
->
dn
;
u16
reg4042
,
reg44
,
reg48
,
reg4a
;
pci_read_config_word
(
dev
,
maslave
,
&
reg4042
);
sitre
=
(
reg4042
&
0x4000
)
?
1
:
0
;
...
...
@@ -320,151 +250,140 @@ static int slc90e66_tune_chipset (ide_drive_t *drive, byte xferspeed)
#ifdef CONFIG_BLK_DEV_IDEDMA
static
int
slc90e66_config_drive_for_dma
(
ide_drive_t
*
drive
)
{
struct
hd_driveid
*
id
=
drive
->
id
;
byte
mode
=
slc90e66_ratemask
(
drive
);
byte
speed
,
tspeed
,
dma
=
1
;
switch
(
mode
)
{
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_1word
&
0x0004
)
{
speed
=
XFER_SW_DMA_2
;
break
;
}
default:
tspeed
=
ide_get_best_pio_mode
(
drive
,
255
,
5
,
NULL
);
speed
=
slc90e66_dma_2_pio
(
XFER_PIO_0
+
tspeed
);
dma
=
0
;
break
;
u8
speed
=
ide_dma_speed
(
drive
,
slc90e66_ratemask
(
drive
));
if
(
!
(
speed
))
{
u8
tspeed
=
ide_get_best_pio_mode
(
drive
,
255
,
5
,
NULL
);
speed
=
slc90e66_dma_2_pio
(
XFER_PIO_0
+
tspeed
);
}
(
void
)
slc90e66_tune_chipset
(
drive
,
speed
);
// return ((int) (dma) ? ide_dma_on : ide_dma_off_quietly);
return
((
int
)
((
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
slc90e66_
config_drive_xfer_rate
(
ide_drive_t
*
drive
)
{
struct
hd_driveid
*
id
=
drive
->
id
;
ide_dma_action_t
dma_func
=
ide_dma_on
;
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
&
0x007F
)
{
if
(
id
->
dma_ultra
&
hwif
->
ultra_mask
)
{
/* Force if Capable UltraDMA */
dma_func
=
slc90e66_config_drive_for_dma
(
drive
);
if
((
id
->
field_valid
&
2
)
&&
(
dma_func
!=
ide_dma_on
))
int
dma
=
slc90e66_config_drive_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
&
0x007
))
{
if
((
id
->
dma_mword
&
hwif
->
mwdma_mask
)
||
(
id
->
dma_1word
&
hwif
->
swdma_mask
))
{
/* Force if Capable regular DMA modes */
dma_func
=
slc90e66_config_drive_for_dma
(
drive
);
if
(
dma_func
!=
ide_dma_on
)
if
(
!
slc90e66_config_drive_for_dma
(
drive
))
goto
no_dma_set
;
}
}
else
if
(
ide_dmaproc
(
ide_dma_good_drive
,
drive
))
{
if
(
id
->
eide_dma_time
>
150
)
{
goto
no_dma_set
;
}
}
else
if
(
hwif
->
ide_dma_good_drive
(
drive
)
&&
(
id
->
eide_dma_time
<
150
))
{
/* Consult the list of known "good" drives */
dma_func
=
slc90e66_config_drive_for_dma
(
drive
);
if
(
dma_func
!=
ide_dma_on
)
if
(
!
slc90e66_config_drive_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:
slc90e66_tune_drive
(
drive
,
5
);
hwif
->
tuneproc
(
drive
,
5
);
return
hwif
->
ide_dma_off_quietly
(
drive
);
}
return
HWIF
(
drive
)
->
dmaproc
(
dma_func
,
drive
);
}
static
int
slc90e66_dmaproc
(
ide_dma_action_t
func
,
ide_drive_t
*
drive
)
{
switch
(
func
)
{
case
ide_dma_check
:
return
config_drive_xfer_rate
(
drive
);
default
:
break
;
}
/* Other cases are done by generic IDE-DMA code. */
return
ide_dmaproc
(
func
,
drive
);
return
hwif
->
ide_dma_on
(
drive
);
}
#endif
/* CONFIG_BLK_DEV_IDEDMA */
unsigned
int
__init
pci_ini
t_slc90e66
(
struct
pci_dev
*
dev
,
const
char
*
name
)
static
unsigned
int
__init
init_chipse
t_slc90e66
(
struct
pci_dev
*
dev
,
const
char
*
name
)
{
#if defined(DISPLAY_SLC90E66_TIMINGS) && defined(CONFIG_PROC_FS)
if
(
!
slc90e66_proc
)
{
slc90e66_proc
=
1
;
bmide_dev
=
dev
;
slc90e66_display_info
=
&
slc90e66_get_info
;
ide_pci_register_host_proc
(
&
slc90e66_procs
[
0
])
;
}
#endif
/* DISPLAY_SLC90E66_TIMINGS && CONFIG_PROC_FS */
return
0
;
}
unsigned
int
__init
ata66
_slc90e66
(
ide_hwif_t
*
hwif
)
static
void
__init
init_hwif
_slc90e66
(
ide_hwif_t
*
hwif
)
{
byte
reg47
=
0
,
ata66
=
0
;
byte
mask
=
hwif
->
channel
?
0x01
:
0x02
;
/* bit0:Primary */
u8
reg47
=
0
;
u8
mask
=
hwif
->
channel
?
0x01
:
0x02
;
/* bit0:Primary */
pci_read_config_byte
(
hwif
->
pci_dev
,
0x47
,
&
reg47
);
ata66
=
(
reg47
&
mask
)
?
0
:
1
;
/* bit[0(1)]: 0:80, 1:40 */
return
ata66
;
}
hwif
->
autodma
=
0
;
void
__init
ide_init_slc90e66
(
ide_hwif_t
*
hwif
)
{
if
(
!
hwif
->
irq
)
hwif
->
irq
=
hwif
->
channel
?
15
:
14
;
hwif
->
autodma
=
0
;
hwif
->
speedproc
=
&
slc90e66_tune_chipset
;
hwif
->
tuneproc
=
&
slc90e66_tune_drive
;
hwif
->
drives
[
0
].
autotune
=
1
;
hwif
->
drives
[
1
].
autotune
=
1
;
if
(
!
hwif
->
dma_base
)
pci_read_config_byte
(
hwif
->
pci_dev
,
0x47
,
&
reg47
);
if
(
!
hwif
->
dma_base
)
{
hwif
->
drives
[
0
].
autotune
=
1
;
hwif
->
drives
[
1
].
autotune
=
1
;
return
;
}
hwif
->
atapi_dma
=
1
;
hwif
->
ultra_mask
=
0x1f
;
hwif
->
mwdma_mask
=
0x07
;
hwif
->
swdma_mask
=
0x07
;
#ifdef CONFIG_BLK_DEV_IDEDMA
hwif
->
dmaproc
=
&
slc90e66_dmaproc
;
#ifdef CONFIG_IDEDMA_AUTO
if
(
!
(
hwif
->
udma_four
))
/* bit[0(1)]: 0:80, 1:40 */
hwif
->
udma_four
=
(
reg47
&
mask
)
?
0
:
1
;
hwif
->
ide_dma_check
=
&
slc90e66_config_drive_xfer_rate
;
if
(
!
noautodma
)
hwif
->
autodma
=
1
;
#endif
/* CONFIG_IDEDMA_AUTO */
hwif
->
drives
[
0
].
autodma
=
hwif
->
autodma
;
hwif
->
drives
[
1
].
autodma
=
hwif
->
autodma
;
#endif
/* !CONFIG_BLK_DEV_IDEDMA */
}
static
void
__init
init_dma_slc90e66
(
ide_hwif_t
*
hwif
,
unsigned
long
dmabase
)
{
ide_setup_dma
(
hwif
,
dmabase
,
8
);
}
extern
void
ide_setup_pci_device
(
struct
pci_dev
*
,
ide_pci_device_t
*
);
static
void
__init
init_setup_slc90e66
(
struct
pci_dev
*
dev
,
ide_pci_device_t
*
d
)
{
ide_setup_pci_device
(
dev
,
d
);
}
int
__init
slc90e66_scan_pcidev
(
struct
pci_dev
*
dev
)
{
ide_pci_device_t
*
d
;
if
(
dev
->
vendor
!=
PCI_VENDOR_ID_EFAR
)
return
0
;
for
(
d
=
slc90e66_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/slc90e66.h
0 → 100644
View file @
e686e408
#ifndef SLC90E66_H
#define SLC90E66_H
#include <linux/config.h>
#include <linux/pci.h>
#include <linux/ide.h>
#define DISPLAY_SLC90E66_TIMINGS
#define SLC90E66_DEBUG_DRIVE_INFO 0
#if defined(DISPLAY_SLC90E66_TIMINGS) && defined(CONFIG_PROC_FS)
#include <linux/stat.h>
#include <linux/proc_fs.h>
static
u8
slc90e66_proc
;
static
int
slc90e66_get_info
(
char
*
,
char
**
,
off_t
,
int
);
static
ide_pci_host_proc_t
slc90e66_procs
[]
__initdata
=
{
{
name:
"slc90e66"
,
set:
1
,
get_info:
slc90e66_get_info
,
parent:
NULL
,
},
};
#endif
/* defined(DISPLAY_SLC90E66_TIMINGS) && defined(CONFIG_PROC_FS) */
static
void
init_setup_slc90e66
(
struct
pci_dev
*
,
ide_pci_device_t
*
);
static
unsigned
int
init_chipset_slc90e66
(
struct
pci_dev
*
,
const
char
*
);
static
void
init_hwif_slc90e66
(
ide_hwif_t
*
);
static
void
init_dma_slc90e66
(
ide_hwif_t
*
,
unsigned
long
);
static
ide_pci_device_t
slc90e66_chipsets
[]
__initdata
=
{
{
vendor:
PCI_VENDOR_ID_EFAR
,
device:
PCI_DEVICE_ID_EFAR_SLC90E66_1
,
name:
"SLC90E66"
,
init_setup:
init_setup_slc90e66
,
init_chipset:
init_chipset_slc90e66
,
init_iops:
NULL
,
init_hwif:
init_hwif_slc90e66
,
init_dma:
init_dma_slc90e66
,
channels:
2
,
autodma:
AUTODMA
,
enablebits:
{{
0x41
,
0x80
,
0x80
},
{
0x43
,
0x80
,
0x80
}},
bootable:
ON_BOARD
,
extra:
0
,
},{
vendor:
0
,
device:
0
,
channels:
0
,
bootable:
EOL
,
}
};
#endif
/* SLC90E66_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