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
737eac1e
Commit
737eac1e
authored
Sep 11, 2002
by
Jens Axboe
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
alim15x3 update
parent
2efec015
Changes
2
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
409 additions
and
292 deletions
+409
-292
drivers/ide/pci/alim15x3.c
drivers/ide/pci/alim15x3.c
+352
-292
drivers/ide/pci/alim15x3.h
drivers/ide/pci/alim15x3.h
+57
-0
No files found.
drivers/ide/pci/alim15x3.c
View file @
737eac1e
/*
/*
* linux/drivers/ide/alim15x3.c Version 0.1
0 Jun. 9, 2000
* linux/drivers/ide/alim15x3.c Version 0.1
5 2002/08/19
*
*
* Copyright (C) 1998-2000 Michel Aubry, Maintainer
* Copyright (C) 1998-2000 Michel Aubry, Maintainer
* Copyright (C) 1998-2000 Andrzej Krzysztofowicz, Maintainer
* Copyright (C) 1998-2000 Andrzej Krzysztofowicz, Maintainer
...
@@ -7,12 +7,18 @@
...
@@ -7,12 +7,18 @@
*
*
* Copyright (C) 1998-2000 Andre Hedrick (andre@linux-ide.org)
* Copyright (C) 1998-2000 Andre Hedrick (andre@linux-ide.org)
* May be copied or modified under the terms of the GNU General Public License
* May be copied or modified under the terms of the GNU General Public License
* Copyright (C) 2002 Alan Cox <alan@redhat.com>
*
*
* (U)DMA capable version of ali 1533/1543(C), 1535(D)
* (U)DMA capable version of ali 1533/1543(C), 1535(D)
*
*
**********************************************************************
**********************************************************************
* 9/7/99 --Parts from the above author are included and need to be
* 9/7/99 --Parts from the above author are included and need to be
* converted into standard interface, once I finish the thought.
* converted into standard interface, once I finish the thought.
*
* Recent changes
* Don't use LBA48 mode on ALi <= 0xC4
* Don't poke 0x79 with a non ALi northbridge
* Don't flip undefined bits on newer chipsets (fix Fujitsu laptop hang)
*/
*/
#include <linux/config.h>
#include <linux/config.h>
...
@@ -27,24 +33,32 @@
...
@@ -27,24 +33,32 @@
#include <asm/io.h>
#include <asm/io.h>
#include "ide_modes.h"
#include "ide_modes.h"
#include "alim15x3.h"
#define DISPLAY_ALI_TIMINGS
/*
* ALi devices are not plug in. Otherwise these static values would
* need to go. They ought to go away anyway
*/
static
u8
m5229_revision
;
static
u8
chip_is_1543c_e
;
static
struct
pci_dev
*
isa_dev
;
#if defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_PROC_FS)
#if defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_PROC_FS)
#include <linux/stat.h>
#include <linux/stat.h>
#include <linux/proc_fs.h>
#include <linux/proc_fs.h>
static
int
ali_get_info
(
char
*
buffer
,
char
**
addr
,
off_t
offset
,
int
count
)
;
static
u8
ali_proc
=
0
;
extern
int
(
*
ali_display_info
)(
char
*
,
char
**
,
off_t
,
int
);
/* ide-proc.c */
static
struct
pci_dev
*
bmide_dev
;
static
struct
pci_dev
*
bmide_dev
;
char
*
fifo
[
4
]
=
{
static
char
*
fifo
[
4
]
=
{
"FIFO Off"
,
"FIFO Off"
,
"FIFO On "
,
"FIFO On "
,
"DMA mode"
,
"DMA mode"
,
"PIO mode"
};
"PIO mode"
};
char
*
udmaT
[
8
]
=
{
static
char
*
udmaT
[
8
]
=
{
"1.5T"
,
"1.5T"
,
" 2T"
,
" 2T"
,
"2.5T"
,
"2.5T"
,
...
@@ -55,7 +69,7 @@ char *udmaT[8] = {
...
@@ -55,7 +69,7 @@ char *udmaT[8] = {
" 8T"
" 8T"
};
};
char
*
channel_status
[
8
]
=
{
static
char
*
channel_status
[
8
]
=
{
"OK "
,
"OK "
,
"busy "
,
"busy "
,
"DRQ "
,
"DRQ "
,
...
@@ -66,14 +80,22 @@ char *channel_status[8] = {
...
@@ -66,14 +80,22 @@ char *channel_status[8] = {
"error DRQ busy"
"error DRQ busy"
};
};
/**
* ali_get_info - generate proc file for ALi IDE
* @buffer: buffer to fill
* @addr: address of user start in buffer
* @offset: offset into 'file'
* @count: buffer count
*
* Walks the Ali devices and outputs summary data on the tuning and
* anything else that will help with debugging
*/
static
int
ali_get_info
(
char
*
buffer
,
char
**
addr
,
off_t
offset
,
int
count
)
static
int
ali_get_info
(
char
*
buffer
,
char
**
addr
,
off_t
offset
,
int
count
)
{
{
byte
reg53h
,
reg5xh
,
reg5yh
,
reg5xh1
,
reg5yh1
;
u32
bibma
;
unsigned
int
bibma
;
u8
reg53h
,
reg5xh
,
reg5yh
,
reg5xh1
,
reg5yh1
,
c0
,
c1
,
rev
,
tmp
;
byte
c0
,
c1
;
char
*
q
,
*
p
=
buffer
;
byte
rev
,
tmp
;
char
*
p
=
buffer
;
char
*
q
;
/* fetch rev. */
/* fetch rev. */
pci_read_config_byte
(
bmide_dev
,
0x08
,
&
rev
);
pci_read_config_byte
(
bmide_dev
,
0x08
,
&
rev
);
...
@@ -89,8 +111,8 @@ static int ali_get_info (char *buffer, char **addr, off_t offset, int count)
...
@@ -89,8 +111,8 @@ static int ali_get_info (char *buffer, char **addr, off_t offset, int count)
* at that point bibma+0x2 et bibma+0xa are byte
* at that point bibma+0x2 et bibma+0xa are byte
* registers to investigate:
* registers to investigate:
*/
*/
c0
=
IN_BYTE
((
unsigned
short
)
bibma
+
0x02
);
c0
=
inb
((
unsigned
short
)
bibma
+
0x02
);
c1
=
IN_BYTE
((
unsigned
short
)
bibma
+
0x0a
);
c1
=
inb
((
unsigned
short
)
bibma
+
0x0a
);
p
+=
sprintf
(
p
,
p
+=
sprintf
(
p
,
"
\n
Ali M15x3 Chipset.
\n
"
);
"
\n
Ali M15x3 Chipset.
\n
"
);
...
@@ -171,7 +193,8 @@ static int ali_get_info (char *buffer, char **addr, off_t offset, int count)
...
@@ -171,7 +193,8 @@ static int ali_get_info (char *buffer, char **addr, off_t offset, int count)
q
=
"FIFO threshold: %2d Words %2d Words"
q
=
"FIFO threshold: %2d Words %2d Words"
" %2d Words %2d Words
\n
"
;
" %2d Words %2d Words
\n
"
;
if
(
rev
<
0xc1
)
{
if
(
rev
<
0xc1
)
{
if
((
rev
==
0x20
)
&&
(
pci_read_config_byte
(
bmide_dev
,
0x4f
,
&
tmp
),
(
tmp
&=
0x20
)))
{
if
((
rev
==
0x20
)
&&
(
pci_read_config_byte
(
bmide_dev
,
0x4f
,
&
tmp
),
(
tmp
&=
0x20
)))
{
p
+=
sprintf
(
p
,
q
,
8
,
8
,
8
,
8
);
p
+=
sprintf
(
p
,
q
,
8
,
8
,
8
,
8
);
}
else
{
}
else
{
p
+=
sprintf
(
p
,
q
,
p
+=
sprintf
(
p
,
q
,
...
@@ -250,24 +273,27 @@ static int ali_get_info (char *buffer, char **addr, off_t offset, int count)
...
@@ -250,24 +273,27 @@ static int ali_get_info (char *buffer, char **addr, off_t offset, int count)
}
}
#endif
/* defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_PROC_FS) */
#endif
/* defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_PROC_FS) */
static
byte
m5229_revision
;
/**
static
byte
chip_is_1543c_e
;
* ali15x3_tune_drive - set up a drive
* @drive: drive to tune
byte
ali_proc
=
0
;
* @pio: unused
static
struct
pci_dev
*
isa_dev
;
*
* Select the best PIO timing for the drive in question. Then
static
void
ali15x3_tune_drive
(
ide_drive_t
*
drive
,
byte
pio
)
* program the controller for this drive set up
*/
static
void
ali15x3_tune_drive
(
ide_drive_t
*
drive
,
u8
pio
)
{
{
ide_pio_data_t
d
;
ide_pio_data_t
d
;
ide_hwif_t
*
hwif
=
HWIF
(
drive
);
ide_hwif_t
*
hwif
=
HWIF
(
drive
);
struct
pci_dev
*
dev
=
hwif
->
pci_dev
;
struct
pci_dev
*
dev
=
hwif
->
pci_dev
;
int
s_time
,
a_time
,
c_time
;
int
s_time
,
a_time
,
c_time
;
byte
s_clc
,
a_clc
,
r_clc
;
u8
s_clc
,
a_clc
,
r_clc
;
unsigned
long
flags
;
unsigned
long
flags
;
int
bus_speed
=
system_bus_clock
();
int
bus_speed
=
system_bus_clock
();
int
port
=
hwif
->
channel
?
0x5c
:
0x58
;
int
port
=
hwif
->
channel
?
0x5c
:
0x58
;
int
portFIFO
=
hwif
->
channel
?
0x55
:
0x54
;
int
portFIFO
=
hwif
->
channel
?
0x55
:
0x54
;
byte
cd_dma_fifo
=
0
;
u8
cd_dma_fifo
=
0
;
pio
=
ide_get_best_pio_mode
(
drive
,
pio
,
5
,
&
d
);
pio
=
ide_get_best_pio_mode
(
drive
,
pio
,
5
,
&
d
);
s_time
=
ide_pio_timings
[
pio
].
setup_time
;
s_time
=
ide_pio_timings
[
pio
].
setup_time
;
...
@@ -325,7 +351,21 @@ static void ali15x3_tune_drive (ide_drive_t *drive, byte pio)
...
@@ -325,7 +351,21 @@ static void ali15x3_tune_drive (ide_drive_t *drive, byte pio)
}
}
static
byte
ali15x3_can_ultra
(
ide_drive_t
*
drive
)
/**
* ali15x3_can_ultra - check for ultra DMA support
* @drive: drive to do the check
*
* Check the drive and controller revisions. Return 0 if UDMA is
* not available, or 1 if UDMA can be used. The actual rules for
* the ALi are
* No UDMA on revisions <= 0x20
* Disk only for revisions < 0xC2
* Not WDC drives for revisions < 0xC2
*
* FIXME: WDC ifdef needs to die
*/
static
u8
ali15x3_can_ultra
(
ide_drive_t
*
drive
)
{
{
#ifndef CONFIG_WDC_ALI15X3
#ifndef CONFIG_WDC_ALI15X3
struct
hd_driveid
*
id
=
drive
->
id
;
struct
hd_driveid
*
id
=
drive
->
id
;
...
@@ -346,61 +386,60 @@ static byte ali15x3_can_ultra (ide_drive_t *drive)
...
@@ -346,61 +386,60 @@ static byte ali15x3_can_ultra (ide_drive_t *drive)
}
}
}
}
static
byte
ali15x3_ratemask
(
ide_drive_t
*
drive
)
/**
* ali15x3_ratemask - generate DMA mode list
* @drive: drive to compute against
*
* Generate a list of the available DMA modes for the drive.
* FIXME: this function contains lots of bogus masking we can dump
*
* Return the highest available mode (UDMA33, UDMA66, UDMA100,..)
*/
static
u8
ali15x3_ratemask
(
ide_drive_t
*
drive
)
{
{
// struct pci_dev *dev = HWIF(drive)->pci_dev;
u8
mode
=
0
,
can_ultra
=
ali15x3_can_ultra
(
drive
);
byte
mode
=
0x00
;
byte
can_ultra
=
ali15x3_can_ultra
(
drive
);
if
(
m5229_revision
>=
0xC4
&&
can_ultra
)
{
mode
=
3
;
if
((
m5229_revision
>=
0xC4
)
&&
(
can_ultra
))
{
}
else
if
(
m5229_revision
>=
0xC2
&&
can_ultra
)
{
mode
|=
0x03
;
mode
=
2
;
}
else
if
((
m5229_revision
>=
0xC2
)
&&
(
can_ultra
))
{
mode
|=
0x02
;
}
else
if
(
can_ultra
)
{
}
else
if
(
can_ultra
)
{
mode
|=
0x0
1
;
return
1
;
}
else
{
}
else
{
return
(
mode
&=
~
0xFF
);
return
0
;
}
if
(
!
eighty_ninty_three
(
drive
))
{
mode
&=
~
0xFE
;
mode
|=
0x01
;
}
}
return
(
mode
&=
~
0xF8
);
}
static
byte
ali15x3_ratefilter
(
ide_drive_t
*
drive
,
byte
speed
)
/*
{
* If the drive sees no suitable cable then UDMA 33
#ifdef CONFIG_BLK_DEV_IDEDMA
* is the highest permitted mode
byte
mode
=
ali15x3_ratemask
(
drive
);
*/
switch
(
mode
)
{
if
(
!
eighty_ninty_three
(
drive
))
case
0x04
:
while
(
speed
>
XFER_UDMA_6
)
speed
--
;
break
;
mode
=
min
(
mode
,
(
u8
)
1
);
case
0x03
:
while
(
speed
>
XFER_UDMA_5
)
speed
--
;
break
;
return
mode
;
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
;
}
}
static
int
ali15x3_tune_chipset
(
ide_drive_t
*
drive
,
byte
xferspeed
)
/**
* ali15x3_tune_chipset - set up chiset for new speed
* @drive: drive to configure for
* @xferspeed: desired speed
*
* Configure the hardware for the desired IDE transfer mode.
* We also do the needed drive configuration through helpers
*/
static
int
ali15x3_tune_chipset
(
ide_drive_t
*
drive
,
u8
xferspeed
)
{
{
ide_hwif_t
*
hwif
=
HWIF
(
drive
);
ide_hwif_t
*
hwif
=
HWIF
(
drive
);
struct
pci_dev
*
dev
=
hwif
->
pci_dev
;
struct
pci_dev
*
dev
=
hwif
->
pci_dev
;
byte
speed
=
ali15x3_ratefilter
(
drive
,
xferspeed
);
u8
speed
=
ide_rate_filter
(
ali15x3_ratemask
(
drive
)
,
xferspeed
);
byte
unit
=
(
drive
->
select
.
b
.
unit
&
0x01
);
u8
unit
=
(
drive
->
select
.
b
.
unit
&
0x01
);
byte
tmpbyte
=
0x00
;
u8
tmpbyte
=
0x00
;
int
m5229_udma
=
(
hwif
->
channel
)
?
0x57
:
0x56
;
int
m5229_udma
=
(
hwif
->
channel
)
?
0x57
:
0x56
;
if
(
speed
<
XFER_UDMA_0
)
{
if
(
speed
<
XFER_UDMA_0
)
{
byte
ultra_enable
=
(
unit
)
?
0x7f
:
0xf7
;
u8
ultra_enable
=
(
unit
)
?
0x7f
:
0xf7
;
/*
/*
* clear "ultra enable" bit
* clear "ultra enable" bit
*/
*/
...
@@ -430,197 +469,130 @@ static int ali15x3_tune_chipset (ide_drive_t *drive, byte xferspeed)
...
@@ -430,197 +469,130 @@ static int ali15x3_tune_chipset (ide_drive_t *drive, byte xferspeed)
}
}
#ifdef CONFIG_BLK_DEV_IDEDMA
#ifdef CONFIG_BLK_DEV_IDEDMA
/**
* config_chipset_for_dma - set up DMA mode
* @drive: drive to configure for
*
* Place a drive into DMA mode and tune the chipset for
* the selected speed.
*
* Returns true if DMA mode can be used
*/
static
int
config_chipset_for_dma
(
ide_drive_t
*
drive
)
static
int
config_chipset_for_dma
(
ide_drive_t
*
drive
)
{
{
struct
hd_driveid
*
id
=
drive
->
id
;
u8
speed
=
ide_dma_speed
(
drive
,
ali15x3_ratemask
(
drive
));
byte
mode
=
ali15x3_ratemask
(
drive
);
byte
speed
=
0
;
if
(
!
(
speed
))
return
0
;
switch
(
mode
)
{
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
);
}
(
void
)
ali15x3_tune_chipset
(
drive
,
speed
);
(
void
)
ali15x3_tune_chipset
(
drive
,
speed
);
// return ((int) (dma) ? ide_dma_on : ide_dma_off_quietly);
return
ide_dma_enable
(
drive
);
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
);
}
}
/**
* ali15x3_config_drive_for_dma - configure for DMA
* @drive: drive to configure
*
* Configure a drive for DMA operation. If DMA is not possible we
* drop the drive into PIO mode instead.
*
* FIXME: exactly what are we trying to return here
*/
static
int
ali15x3_config_drive_for_dma
(
ide_drive_t
*
drive
)
static
int
ali15x3_config_drive_for_dma
(
ide_drive_t
*
drive
)
{
{
struct
hd_driveid
*
id
=
drive
->
id
;
ide_hwif_t
*
hwif
=
HWIF
(
drive
);
ide_hwif_t
*
hwif
=
HWIF
(
drive
);
struct
hd_driveid
*
id
=
drive
->
id
;
ide_dma_action_t
dma_func
=
ide_dma_on
;
if
((
m5229_revision
<=
0x20
)
&&
(
drive
->
media
!=
ide_disk
))
if
((
m5229_revision
<=
0x20
)
&&
(
drive
->
media
!=
ide_disk
))
return
hwif
->
dmaproc
(
ide_dma_off_quietly
,
drive
);
return
hwif
->
ide_dma_off_quietly
(
drive
);
drive
->
init_speed
=
0
;
drive
->
init_speed
=
0
;
if
((
id
!=
NULL
)
&&
((
id
->
capability
&
1
)
!=
0
)
&&
hwif
->
autodma
)
{
if
((
id
!=
NULL
)
&&
((
id
->
capability
&
1
)
!=
0
)
&&
drive
->
autodma
)
{
/* Consult the list of known "bad" drives */
/* Consult the list of known "bad" drives */
if
(
ide_dmaproc
(
ide_dma_bad_drive
,
drive
))
{
if
(
hwif
->
ide_dma_bad_drive
(
drive
))
dma_func
=
ide_dma_off
;
goto
fast_ata_pio
;
goto
fast_ata_pio
;
}
dma_func
=
ide_dma_off_quietly
;
if
((
id
->
field_valid
&
4
)
&&
(
m5229_revision
>=
0xC2
))
{
if
((
id
->
field_valid
&
4
)
&&
(
m5229_revision
>=
0xC2
))
{
if
(
id
->
dma_ultra
&
0x003F
)
{
if
(
id
->
dma_ultra
&
hwif
->
ultra_mask
)
{
/* Force if Capable UltraDMA */
/* Force if Capable UltraDMA */
dma_func
=
config_chipset_for_dma
(
drive
);
int
dma
=
config_chipset_for_dma
(
drive
);
if
((
id
->
field_valid
&
2
)
&&
if
((
id
->
field_valid
&
2
)
&&
!
dma
)
(
dma_func
!=
ide_dma_on
))
goto
try_dma_modes
;
goto
try_dma_modes
;
}
}
}
else
if
(
id
->
field_valid
&
2
)
{
}
else
if
(
id
->
field_valid
&
2
)
{
try_dma_modes:
try_dma_modes:
if
((
id
->
dma_mword
&
0x0007
)
||
if
((
id
->
dma_mword
&
hwif
->
mwdma_mask
)
||
(
id
->
dma_1word
&
0x0007
))
{
(
id
->
dma_1word
&
hwif
->
swdma_mask
))
{
/* Force if Capable regular DMA modes */
/* Force if Capable regular DMA modes */
dma_func
=
config_chipset_for_dma
(
drive
);
if
(
!
config_chipset_for_dma
(
drive
))
if
(
dma_func
!=
ide_dma_on
)
goto
no_dma_set
;
goto
no_dma_set
;
}
}
}
else
if
(
ide_dmaproc
(
ide_dma_good_drive
,
drive
))
{
}
else
if
(
hwif
->
ide_dma_good_drive
(
drive
)
&&
if
(
id
->
eide_dma_time
>
150
)
{
(
id
->
eide_dma_time
<
150
))
{
goto
no_dma_set
;
}
/* Consult the list of known "good" drives */
/* Consult the list of known "good" drives */
dma_func
=
config_chipset_for_dma
(
drive
);
if
(
!
config_chipset_for_dma
(
drive
))
if
(
dma_func
!=
ide_dma_on
)
goto
no_dma_set
;
goto
no_dma_set
;
}
else
{
}
else
{
goto
fast_ata_pio
;
goto
fast_ata_pio
;
}
}
}
else
if
((
id
->
capability
&
8
)
||
(
id
->
field_valid
&
2
))
{
}
else
if
((
id
->
capability
&
8
)
||
(
id
->
field_valid
&
2
))
{
fast_ata_pio:
fast_ata_pio:
dma_func
=
ide_dma_off_quietly
;
no_dma_set:
no_dma_set:
hwif
->
tuneproc
(
drive
,
5
);
hwif
->
tuneproc
(
drive
,
5
);
return
hwif
->
ide_dma_off_quietly
(
drive
);
}
}
return
hwif
->
dmaproc
(
dma_func
,
drive
);
return
hwif
->
ide_dma_on
(
drive
);
}
}
static
int
ali15x3_dmaproc
(
ide_dma_action_t
func
,
ide_drive_t
*
drive
)
/**
* ali15x3_dma_write - do a DMA IDE write
* @drive: drive to issue write for
*
* Returns 1 if the DMA write cannot be performed, zero on
* success.
*/
static
int
ali15x3_dma_write
(
ide_drive_t
*
drive
)
{
{
switch
(
func
)
{
if
((
m5229_revision
<
0xC2
)
&&
(
drive
->
media
!=
ide_disk
))
case
ide_dma_check
:
return
1
;
/* try PIO instead of DMA */
return
ali15x3_config_drive_for_dma
(
drive
);
return
__ide_dma_write
(
drive
);
case
ide_dma_write
:
if
((
m5229_revision
<
0xC2
)
&&
(
drive
->
media
!=
ide_disk
))
return
1
;
/* try PIO instead of DMA */
break
;
default:
break
;
}
return
ide_dmaproc
(
func
,
drive
);
/* use standard DMA stuff */
}
}
#endif
/* CONFIG_BLK_DEV_IDEDMA */
#endif
/* CONFIG_BLK_DEV_IDEDMA */
#define ALI_INIT_CODE_TEST
/**
* init_chipset_ali15x3 - Initialise an ALi IDE controller
unsigned
int
__init
pci_init_ali15x3
(
struct
pci_dev
*
dev
,
const
char
*
name
)
* @dev: PCI device
* @name: Name of the controller
*
* This function initializes the ALI IDE controller and where
* appropriate also sets up the 1533 southbridge.
*/
static
unsigned
int
__init
init_chipset_ali15x3
(
struct
pci_dev
*
dev
,
const
char
*
name
)
{
{
unsigned
long
fixdma_base
=
pci_resource_start
(
dev
,
4
);
#ifdef ALI_INIT_CODE_TEST
unsigned
long
flags
;
unsigned
long
flags
;
byte
tmpbyte
;
u8
tmpbyte
;
#endif
/* ALI_INIT_CODE_TEST */
struct
pci_dev
*
north
=
pci_find_slot
(
0
,
PCI_DEVFN
(
0
,
0
));
pci_read_config_byte
(
dev
,
PCI_REVISION_ID
,
&
m5229_revision
);
pci_read_config_byte
(
dev
,
PCI_REVISION_ID
,
&
m5229_revision
);
isa_dev
=
pci_find_device
(
PCI_VENDOR_ID_AL
,
PCI_DEVICE_ID_AL_M1533
,
NULL
);
isa_dev
=
pci_find_device
(
PCI_VENDOR_ID_AL
,
PCI_DEVICE_ID_AL_M1533
,
NULL
);
if
(
!
fixdma_base
)
{
/*
*
*/
}
else
{
/*
* enable DMA capable bit, and "not" simplex only
*/
OUT_BYTE
(
IN_BYTE
(
fixdma_base
+
2
)
&
0x60
,
fixdma_base
+
2
);
if
(
IN_BYTE
(
fixdma_base
+
2
)
&
0x80
)
printk
(
"%s: simplex device: DMA will fail!!
\n
"
,
name
);
}
#if defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_PROC_FS)
#if defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_PROC_FS)
if
(
!
ali_proc
)
{
if
(
!
ali_proc
)
{
ali_proc
=
1
;
ali_proc
=
1
;
bmide_dev
=
dev
;
bmide_dev
=
dev
;
ali_display_info
=
&
ali_get_info
;
ide_pci_register_host_proc
(
&
ali_procs
[
0
])
;
}
}
#endif
/* defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_PROC_FS) */
#endif
/* defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_PROC_FS) */
#ifdef ALI_INIT_CODE_TEST
local_irq_save
(
flags
);
local_irq_save
(
flags
);
if
(
m5229_revision
>=
0xC2
)
{
if
(
m5229_revision
<
0xC2
)
{
/*
* 1543C-B?, 1535, 1535D, 1553
* Note 1: not all "motherboard" support this detection
* Note 2: if no udma 66 device, the detection may "error".
* but in this case, we will not set the device to
* ultra 66, the detection result is not important
*/
/*
* enable "Cable Detection", m5229, 0x4b, bit3
*/
pci_read_config_byte
(
dev
,
0x4b
,
&
tmpbyte
);
pci_write_config_byte
(
dev
,
0x4b
,
tmpbyte
|
0x08
);
/*
* set south-bridge's enable bit, m1533, 0x79
*/
pci_read_config_byte
(
isa_dev
,
0x79
,
&
tmpbyte
);
if
(
m5229_revision
==
0xC2
)
{
/*
* 1543C-B0 (m1533, 0x79, bit 2)
*/
pci_write_config_byte
(
isa_dev
,
0x79
,
tmpbyte
|
0x04
);
}
else
if
(
m5229_revision
>=
0xC3
)
{
/*
* 1553/1535 (m1533, 0x79, bit 1)
*/
pci_write_config_byte
(
isa_dev
,
0x79
,
tmpbyte
|
0x02
);
}
}
else
{
/*
/*
* revision 0x20 (1543-E, 1543-F)
* revision 0x20 (1543-E, 1543-F)
* revision 0xC0, 0xC1 (1543C-C, 1543C-D, 1543C-E)
* revision 0xC0, 0xC1 (1543C-C, 1543C-D, 1543C-E)
...
@@ -631,62 +603,77 @@ unsigned int __init pci_init_ali15x3 (struct pci_dev *dev, const char *name)
...
@@ -631,62 +603,77 @@ unsigned int __init pci_init_ali15x3 (struct pci_dev *dev, const char *name)
* clear bit 7
* clear bit 7
*/
*/
pci_write_config_byte
(
dev
,
0x4b
,
tmpbyte
&
0x7F
);
pci_write_config_byte
(
dev
,
0x4b
,
tmpbyte
&
0x7F
);
local_irq_restore
(
flags
);
return
0
;
}
}
local_irq_save
(
flags
);
/*
#endif
/* ALI_INIT_CODE_TEST */
* 1543C-B?, 1535, 1535D, 1553
* Note 1: not all "motherboard" support this detection
* Note 2: if no udma 66 device, the detection may "error".
* but in this case, we will not set the device to
* ultra 66, the detection result is not important
*/
/*
* enable "Cable Detection", m5229, 0x4b, bit3
*/
pci_read_config_byte
(
dev
,
0x4b
,
&
tmpbyte
);
pci_write_config_byte
(
dev
,
0x4b
,
tmpbyte
|
0x08
);
/*
* We should only tune the 1533 enable if we are using an ALi
* North bridge
*/
if
(
north
->
vendor
!=
PCI_VENDOR_ID_AL
)
{
local_irq_restore
(
flags
);
return
0
;
}
/*
* set south-bridge's enable bit, m1533, 0x79
*/
pci_read_config_byte
(
isa_dev
,
0x79
,
&
tmpbyte
);
if
(
m5229_revision
==
0xC2
)
{
/*
* 1543C-B0 (m1533, 0x79, bit 2)
*/
pci_write_config_byte
(
isa_dev
,
0x79
,
tmpbyte
|
0x04
);
}
else
if
(
m5229_revision
>=
0xC3
)
{
/*
* 1553/1535 (m1533, 0x79, bit 1)
*/
pci_write_config_byte
(
isa_dev
,
0x79
,
tmpbyte
|
0x02
);
}
local_irq_restore
(
flags
);
return
0
;
return
0
;
}
}
/*
/**
* This checks if the controller and the cable are capable
* ata66_ali15x3 - check for UDMA 66 support
* of UDMA66 transfers. It doesn't check the drives.
* @hwif: IDE interface
* But see note 2 below!
*
* This checks if the controller and the cable are capable
* of UDMA66 transfers. It doesn't check the drives.
* But see note 2 below!
*
* FIXME: frobs bits that are not defined on newer ALi devicea
*/
*/
unsigned
int
__init
ata66_ali15x3
(
ide_hwif_t
*
hwif
)
static
unsigned
int
__init
ata66_ali15x3
(
ide_hwif_t
*
hwif
)
{
{
struct
pci_dev
*
dev
=
hwif
->
pci_dev
;
struct
pci_dev
*
dev
=
hwif
->
pci_dev
;
unsigned
int
ata66
=
0
;
unsigned
int
ata66
=
0
;
byte
cable_80_pin
[
2
]
=
{
0
,
0
};
u8
cable_80_pin
[
2
]
=
{
0
,
0
};
unsigned
long
flags
;
unsigned
long
flags
;
byte
tmpbyte
;
u8
tmpbyte
;
local_irq_save
(
flags
);
local_irq_save
(
flags
);
if
(
m5229_revision
>=
0xC2
)
{
if
(
m5229_revision
>=
0xC2
)
{
#ifndef ALI_INIT_CODE_TEST
/*
* 1543C-B?, 1535, 1535D, 1553
* Note 1: not all "motherboard" support this detection
* Note 2: if no udma 66 device, the detection may "error".
* but in this case, we will not set the device to
* ultra 66, the detection result is not important
*/
/*
* enable "Cable Detection", m5229, 0x4b, bit3
*/
pci_read_config_byte
(
dev
,
0x4b
,
&
tmpbyte
);
pci_write_config_byte
(
dev
,
0x4b
,
tmpbyte
|
0x08
);
/*
* set south-bridge's enable bit, m1533, 0x79
*/
pci_read_config_byte
(
isa_dev
,
0x79
,
&
tmpbyte
);
if
(
m5229_revision
==
0xC2
)
{
/*
* 1543C-B0 (m1533, 0x79, bit 2)
*/
pci_write_config_byte
(
isa_dev
,
0x79
,
tmpbyte
|
0x04
);
}
else
if
(
m5229_revision
>=
0xC3
)
{
/*
* 1553/1535 (m1533, 0x79, bit 1)
*/
pci_write_config_byte
(
isa_dev
,
0x79
,
tmpbyte
|
0x02
);
}
#endif
/* ALI_INIT_CODE_TEST */
/*
/*
* Ultra66 cable detection (from Host View)
* Ultra66 cable detection (from Host View)
* m5229, 0x4a, bit0: primary, bit1: secondary 80 pin
* m5229, 0x4a, bit0: primary, bit1: secondary 80 pin
...
@@ -707,18 +694,6 @@ unsigned int __init ata66_ali15x3 (ide_hwif_t *hwif)
...
@@ -707,18 +694,6 @@ unsigned int __init ata66_ali15x3 (ide_hwif_t *hwif)
*/
*/
ata66
=
(
hwif
->
channel
)
?
cable_80_pin
[
1
]
:
cable_80_pin
[
0
];
ata66
=
(
hwif
->
channel
)
?
cable_80_pin
[
1
]
:
cable_80_pin
[
0
];
}
else
{
}
else
{
#ifndef ALI_INIT_CODE_TEST
/*
* revision 0x20 (1543-E, 1543-F)
* revision 0xC0, 0xC1 (1543C-C, 1543C-D, 1543C-E)
* clear CD-ROM DMA write bit, m5229, 0x4b, bit 7
*/
pci_read_config_byte
(
dev
,
0x4b
,
&
tmpbyte
);
/*
* clear bit 7
*/
pci_write_config_byte
(
dev
,
0x4b
,
tmpbyte
&
0x7F
);
#endif
/* ALI_INIT_CODE_TEST */
/*
/*
* check m1533, 0x5e, bit 1~4 == 1001 => & 00011110 = 00010010
* check m1533, 0x5e, bit 1~4 == 1001 => & 00011110 = 00010010
*/
*/
...
@@ -731,9 +706,18 @@ unsigned int __init ata66_ali15x3 (ide_hwif_t *hwif)
...
@@ -731,9 +706,18 @@ unsigned int __init ata66_ali15x3 (ide_hwif_t *hwif)
* Enable this bit even if we want to use PIO
* Enable this bit even if we want to use PIO
* PIO FIFO off (m5229, 0x53, bit1)
* PIO FIFO off (m5229, 0x53, bit1)
* The hardware will use 0x54h and 0x55h to control PIO FIFO
* The hardware will use 0x54h and 0x55h to control PIO FIFO
* (Not on later devices it seems)
*
* 0x53 changes meaning on later revs - we must no touch
* bit 1 on them. Need to check if 0x20 is the right break
*/
*/
pci_read_config_byte
(
dev
,
0x53
,
&
tmpbyte
);
pci_read_config_byte
(
dev
,
0x53
,
&
tmpbyte
);
tmpbyte
=
(
tmpbyte
&
(
~
0x02
))
|
0x01
;
if
(
m5229_revision
<=
0x20
)
tmpbyte
=
(
tmpbyte
&
(
~
0x02
))
|
0x01
;
else
tmpbyte
|=
0x01
;
pci_write_config_byte
(
dev
,
0x53
,
tmpbyte
);
pci_write_config_byte
(
dev
,
0x53
,
tmpbyte
);
...
@@ -742,11 +726,63 @@ unsigned int __init ata66_ali15x3 (ide_hwif_t *hwif)
...
@@ -742,11 +726,63 @@ unsigned int __init ata66_ali15x3 (ide_hwif_t *hwif)
return
(
ata66
);
return
(
ata66
);
}
}
void
__init
ide_init_ali15x3
(
ide_hwif_t
*
hwif
)
/**
* init_hwif_common_ali15x3 - Set up ALI IDE hardware
* @hwif: IDE interface
*
* Initialize the IDE structure side of the ALi 15x3 driver.
*/
static
void
__init
init_hwif_common_ali15x3
(
ide_hwif_t
*
hwif
)
{
{
#ifndef CONFIG_SPARC64
hwif
->
autodma
=
0
;
byte
ideic
,
inmir
;
hwif
->
tuneproc
=
&
ali15x3_tune_drive
;
byte
irq_routing_table
[]
=
{
-
1
,
9
,
3
,
10
,
4
,
5
,
7
,
6
,
hwif
->
speedproc
=
&
ali15x3_tune_chipset
;
/* Don't use LBA48 on ALi devices before rev 0xC5 */
hwif
->
addressing
=
(
m5229_revision
<=
0xC4
)
?
1
:
0
;
if
(
!
hwif
->
dma_base
)
{
hwif
->
drives
[
0
].
autotune
=
1
;
hwif
->
drives
[
1
].
autotune
=
1
;
return
;
}
if
(
m5229_revision
>
0x20
)
hwif
->
ultra_mask
=
0x3f
;
hwif
->
mwdma_mask
=
0x07
;
hwif
->
swdma_mask
=
0x07
;
#ifdef CONFIG_BLK_DEV_IDEDMA
if
(
m5229_revision
>=
0x20
)
{
/*
* M1543C or newer for DMAing
*/
hwif
->
ide_dma_check
=
&
ali15x3_config_drive_for_dma
;
hwif
->
ide_dma_write
=
&
ali15x3_dma_write
;
if
(
!
noautodma
)
hwif
->
autodma
=
1
;
if
(
!
(
hwif
->
udma_four
))
hwif
->
udma_four
=
ata66_ali15x3
(
hwif
);
}
hwif
->
drives
[
0
].
autodma
=
hwif
->
autodma
;
hwif
->
drives
[
1
].
autodma
=
hwif
->
autodma
;
#endif
/* CONFIG_BLK_DEV_IDEDMA */
}
/**
* init_hwif_ali15x3 - Initialize the ALI IDE x86 stuff
* @hwif: interface to configure
*
* Obtain the IRQ tables for an ALi based IDE solution on the PC
* class platforms. This part of the code isn't applicable to the
* Sparc systems
*/
static
void
__init
init_hwif_ali15x3
(
ide_hwif_t
*
hwif
)
{
u8
ideic
,
inmir
;
u8
irq_routing_table
[]
=
{
-
1
,
9
,
3
,
10
,
4
,
5
,
7
,
6
,
1
,
11
,
0
,
12
,
0
,
14
,
0
,
15
};
1
,
11
,
0
,
12
,
0
,
14
,
0
,
15
};
hwif
->
irq
=
hwif
->
channel
?
15
:
14
;
hwif
->
irq
=
hwif
->
channel
?
15
:
14
;
...
@@ -778,48 +814,72 @@ void __init ide_init_ali15x3 (ide_hwif_t *hwif)
...
@@ -778,48 +814,72 @@ void __init ide_init_ali15x3 (ide_hwif_t *hwif)
hwif
->
irq
=
irq_routing_table
[
inmir
];
hwif
->
irq
=
irq_routing_table
[
inmir
];
}
}
}
}
#endif
/* CONFIG_SPARC64 */
hwif
->
autodma
=
0
;
hwif
->
tuneproc
=
&
ali15x3_tune_drive
;
hwif
->
drives
[
0
].
autotune
=
1
;
hwif
->
drives
[
1
].
autotune
=
1
;
hwif
->
speedproc
=
&
ali15x3_tune_chipset
;
if
(
!
hwif
->
dma_base
)
init_hwif_common_ali15x3
(
hwif
);
return
;
#ifdef CONFIG_BLK_DEV_IDEDMA
if
(
m5229_revision
>=
0x20
)
{
/*
* M1543C or newer for DMAing
*/
hwif
->
dmaproc
=
&
ali15x3_dmaproc
;
#ifdef CONFIG_IDEDMA_AUTO
if
(
!
noautodma
)
hwif
->
autodma
=
1
;
#endif
/* CONFIG_IDEDMA_AUTO */
}
#endif
/* CONFIG_BLK_DEV_IDEDMA */
}
}
void
__init
ide_dmacapable_ali15x3
(
ide_hwif_t
*
hwif
,
unsigned
long
dmabase
)
/**
* init_dma_ali15x3 - set up DMA on ALi15x3
* @hwif: IDE interface
* @dmabase: DMA interface base PCI address
*
* Set up the DMA functionality on the ALi 15x3. For the ALi
* controllers this is generic so we can let the generic code do
* the actual work.
*/
static
void
__init
init_dma_ali15x3
(
ide_hwif_t
*
hwif
,
unsigned
long
dmabase
)
{
{
if
(
(
dmabase
)
&&
(
m5229_revision
<
0x20
))
{
if
(
m5229_revision
<
0x20
)
return
;
return
;
}
if
(
!
(
hwif
->
channel
))
hwif
->
OUTB
(
hwif
->
INB
(
dmabase
+
2
)
&
0x60
,
dmabase
+
2
);
ide_setup_dma
(
hwif
,
dmabase
,
8
);
ide_setup_dma
(
hwif
,
dmabase
,
8
);
}
}
extern
void
ide_setup_pci_device
(
struct
pci_dev
*
dev
,
ide_pci_device_t
*
d
);
extern
void
ide_setup_pci_device
(
struct
pci_dev
*
,
ide_pci_device_t
*
);
void
__init
fixup_device_ali15x3
(
struct
pci_dev
*
dev
,
ide_pci_device_t
*
d
)
{
if
(
dev
->
resource
[
0
].
start
!=
0x01F1
)
ide_register_xp_fix
(
dev
);
printk
(
"%s: IDE controller on PCI bus %02x dev %02x
\n
"
,
/**
d
->
name
,
dev
->
bus
->
number
,
dev
->
devfn
);
* init_setup_ali15x3 - set up an ALi15x3 IDE controller
* @dev: PCI device to set up
* @d: IDE PCI structures
*
* Perform the actual set up for the ALi15x3.
*/
static
void
__init
init_setup_ali15x3
(
struct
pci_dev
*
dev
,
ide_pci_device_t
*
d
)
{
#if defined(CONFIG_SPARC64)
d
->
init_hwif
=
init_hwif_common_ali15x3
;
#endif
/* CONFIG_SPARC64 */
ide_setup_pci_device
(
dev
,
d
);
ide_setup_pci_device
(
dev
,
d
);
}
}
/**
* ali15x3_scan_pcidev - check for ali pci ide
* @dev: device found by IDE ordered scan
*
* If the device is a known ALi IDE controller we set it up and
* then return 1. If we do not know it, or set up fails we return 0
* and it will be offered to other drivers or taken generic
*/
int
__init
ali15x3_scan_pcidev
(
struct
pci_dev
*
dev
)
{
ide_pci_device_t
*
d
;
if
(
dev
->
vendor
!=
PCI_VENDOR_ID_AL
)
return
0
;
for
(
d
=
ali15x3_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/alim15x3.h
0 → 100644
View file @
737eac1e
#ifndef ALI15X3_H
#define ALI15X3_H
#include <linux/config.h>
#include <linux/pci.h>
#include <linux/ide.h>
#define DISPLAY_ALI_TIMINGS
#if defined(DISPLAY_ALI_TIMINGS) && defined(CONFIG_PROC_FS)
#include <linux/stat.h>
#include <linux/proc_fs.h>
static
u8
ali_proc
;
static
int
ali_get_info
(
char
*
,
char
**
,
off_t
,
int
);
static
ide_pci_host_proc_t
ali_procs
[]
__initdata
=
{
{
name:
"ali"
,
set:
1
,
get_info:
ali_get_info
,
parent:
NULL
,
},
};
#endif
/* DISPLAY_ALI_TIMINGS && CONFIG_PROC_FS */
static
void
init_setup_ali15x3
(
struct
pci_dev
*
,
ide_pci_device_t
*
);
static
unsigned
int
init_chipset_ali15x3
(
struct
pci_dev
*
,
const
char
*
);
static
void
init_hwif_common_ali15x3
(
ide_hwif_t
*
);
static
void
init_hwif_ali15x3
(
ide_hwif_t
*
);
static
void
init_dma_ali15x3
(
ide_hwif_t
*
,
unsigned
long
);
static
ide_pci_device_t
ali15x3_chipsets
[]
__initdata
=
{
{
vendor:
PCI_VENDOR_ID_AL
,
device:
PCI_DEVICE_ID_AL_M5229
,
name:
"ALI15X3"
,
init_setup:
init_setup_ali15x3
,
init_chipset:
init_chipset_ali15x3
,
init_iops:
NULL
,
init_hwif:
init_hwif_ali15x3
,
init_dma:
init_dma_ali15x3
,
channels:
2
,
autodma:
AUTODMA
,
enablebits:
{{
0x00
,
0x00
,
0x00
},
{
0x00
,
0x00
,
0x00
}},
bootable:
ON_BOARD
,
extra:
0
},{
vendor:
0
,
device:
0
,
channels:
0
,
bootable:
EOL
,
}
};
#endif
/* ALI15X3 */
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