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
563cbaa6
Commit
563cbaa6
authored
Sep 11, 2002
by
Jens Axboe
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
cmd64x update
parent
6813194d
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
397 additions
and
683 deletions
+397
-683
drivers/ide/pci/cmd64x.c
drivers/ide/pci/cmd64x.c
+245
-683
drivers/ide/pci/cmd64x.h
drivers/ide/pci/cmd64x.h
+152
-0
No files found.
drivers/ide/pci/cmd64x.c
View file @
563cbaa6
...
@@ -25,73 +25,13 @@
...
@@ -25,73 +25,13 @@
#include <asm/io.h>
#include <asm/io.h>
#include "ide_modes.h"
#include "ide_modes.h"
#include "cmd64x.h"
#ifndef SPLIT_BYTE
#define SPLIT_BYTE(B,H,L) ((H)=(B>>4), (L)=(B-((B>>4)<<4)))
#endif
#define CMD_DEBUG 0
#if CMD_DEBUG
#define cmdprintk(x...) printk(x)
#else
#define cmdprintk(x...)
#endif
/*
* CMD64x specific registers definition.
*/
#define CFR 0x50
#define CFR_INTR_CH0 0x02
#define CNTRL 0x51
#define CNTRL_DIS_RA0 0x40
#define CNTRL_DIS_RA1 0x80
#define CNTRL_ENA_2ND 0x08
#define CMDTIM 0x52
#define ARTTIM0 0x53
#define DRWTIM0 0x54
#define ARTTIM1 0x55
#define DRWTIM1 0x56
#define ARTTIM23 0x57
#define ARTTIM23_DIS_RA2 0x04
#define ARTTIM23_DIS_RA3 0x08
#define ARTTIM23_INTR_CH1 0x10
#define ARTTIM2 0x57
#define ARTTIM3 0x57
#define DRWTIM23 0x58
#define DRWTIM2 0x58
#define BRST 0x59
#define DRWTIM3 0x5b
#define BMIDECR0 0x70
#define MRDMODE 0x71
#define MRDMODE_INTR_CH0 0x04
#define MRDMODE_INTR_CH1 0x08
#define MRDMODE_BLK_CH0 0x10
#define MRDMODE_BLK_CH1 0x20
#define BMIDESR0 0x72
#define UDIDETCR0 0x73
#define DTPR0 0x74
#define BMIDECR1 0x78
#define BMIDECSR 0x79
#define BMIDESR1 0x7A
#define UDIDETCR1 0x7B
#define DTPR1 0x7C
#define DISPLAY_CMD64X_TIMINGS
#if defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_PROC_FS)
#if defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_PROC_FS)
#include <linux/stat.h>
#include <linux/stat.h>
#include <linux/proc_fs.h>
#include <linux/proc_fs.h>
static
char
*
print_cmd64x_get_info
(
char
*
,
struct
pci_dev
*
,
int
);
static
u8
cmd64x_proc
=
0
;
static
char
*
print_sii_get_info
(
char
*
,
struct
pci_dev
*
,
int
);
static
int
cmd64x_get_info
(
char
*
,
char
**
,
off_t
,
int
);
extern
int
(
*
cmd64x_display_info
)(
char
*
,
char
**
,
off_t
,
int
);
/* ide-proc.c */
byte
cmd64x_proc
=
0
;
#define CMD_MAX_DEVS 5
#define CMD_MAX_DEVS 5
...
@@ -202,24 +142,6 @@ static char * print_cmd64x_get_info (char *buf, struct pci_dev *dev, int index)
...
@@ -202,24 +142,6 @@ static char * print_cmd64x_get_info (char *buf, struct pci_dev *dev, int index)
return
(
char
*
)
p
;
return
(
char
*
)
p
;
}
}
static
char
*
print_sii_get_info
(
char
*
buf
,
struct
pci_dev
*
dev
,
int
index
)
{
char
*
p
=
buf
;
p
+=
sprintf
(
p
,
"
\n
Controller: %d
\n
"
,
index
);
p
+=
sprintf
(
p
,
"SII%x Chipset.
\n
"
,
dev
->
device
);
p
+=
sprintf
(
p
,
"--------------- Primary Channel "
"---------------- Secondary Channel "
"-------------
\n
"
);
p
+=
sprintf
(
p
,
"--------------- drive0 --------- drive1 "
"-------- drive0 ---------- drive1 ------
\n
"
);
p
+=
sprintf
(
p
,
"PIO Mode: %s %s"
" %s %s
\n
"
,
"?"
,
"?"
,
"?"
,
"?"
);
return
(
char
*
)
p
;
}
static
int
cmd64x_get_info
(
char
*
buffer
,
char
**
addr
,
off_t
offset
,
int
count
)
static
int
cmd64x_get_info
(
char
*
buffer
,
char
**
addr
,
off_t
offset
,
int
count
)
{
{
char
*
p
=
buffer
;
char
*
p
=
buffer
;
...
@@ -228,11 +150,7 @@ static int cmd64x_get_info (char *buffer, char **addr, off_t offset, int count)
...
@@ -228,11 +150,7 @@ static int cmd64x_get_info (char *buffer, char **addr, off_t offset, int count)
p
+=
sprintf
(
p
,
"
\n
"
);
p
+=
sprintf
(
p
,
"
\n
"
);
for
(
i
=
0
;
i
<
n_cmd_devs
;
i
++
)
{
for
(
i
=
0
;
i
<
n_cmd_devs
;
i
++
)
{
struct
pci_dev
*
dev
=
cmd_devs
[
i
];
struct
pci_dev
*
dev
=
cmd_devs
[
i
];
if
(
dev
->
device
<=
PCI_DEVICE_ID_CMD_649
)
p
=
print_cmd64x_get_info
(
p
,
dev
,
i
);
p
=
print_cmd64x_get_info
(
p
,
dev
,
i
);
else
p
=
print_sii_get_info
(
p
,
dev
,
i
);
}
}
return
p
-
buffer
;
/* => must be less than 4k! */
return
p
-
buffer
;
/* => must be less than 4k! */
}
}
...
@@ -243,8 +161,8 @@ static int cmd64x_get_info (char *buffer, char **addr, off_t offset, int count)
...
@@ -243,8 +161,8 @@ static int cmd64x_get_info (char *buffer, char **addr, off_t offset, int count)
* Registers and masks for easy access by drive index:
* Registers and masks for easy access by drive index:
*/
*/
#if 0
#if 0
static
byte
prefetch_regs[4] = {CNTRL, CNTRL, ARTTIM23, ARTTIM23};
static
u8
prefetch_regs[4] = {CNTRL, CNTRL, ARTTIM23, ARTTIM23};
static
byte
prefetch_masks[4] = {CNTRL_DIS_RA0, CNTRL_DIS_RA1, ARTTIM23_DIS_RA2, ARTTIM23_DIS_RA3};
static
u8
prefetch_masks[4] = {CNTRL_DIS_RA0, CNTRL_DIS_RA1, ARTTIM23_DIS_RA2, ARTTIM23_DIS_RA3};
#endif
#endif
/*
/*
...
@@ -256,23 +174,23 @@ static void program_drive_counts (ide_drive_t *drive, int setup_count, int activ
...
@@ -256,23 +174,23 @@ static void program_drive_counts (ide_drive_t *drive, int setup_count, int activ
unsigned
long
flags
;
unsigned
long
flags
;
struct
pci_dev
*
dev
=
HWIF
(
drive
)
->
pci_dev
;
struct
pci_dev
*
dev
=
HWIF
(
drive
)
->
pci_dev
;
ide_drive_t
*
drives
=
HWIF
(
drive
)
->
drives
;
ide_drive_t
*
drives
=
HWIF
(
drive
)
->
drives
;
byte
temp_b
;
u8
temp_b
;
static
const
byte
setup_counts
[]
=
{
0x40
,
0x40
,
0x40
,
0x80
,
0
,
0xc0
};
static
const
u8
setup_counts
[]
=
{
0x40
,
0x40
,
0x40
,
0x80
,
0
,
0xc0
};
static
const
byte
recovery_counts
[]
=
static
const
u8
recovery_counts
[]
=
{
15
,
15
,
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
,
10
,
11
,
12
,
13
,
14
,
0
};
{
15
,
15
,
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
,
10
,
11
,
12
,
13
,
14
,
0
};
static
const
byte
arttim_regs
[
2
][
2
]
=
{
static
const
u8
arttim_regs
[
2
][
2
]
=
{
{
ARTTIM0
,
ARTTIM1
},
{
ARTTIM0
,
ARTTIM1
},
{
ARTTIM23
,
ARTTIM23
}
{
ARTTIM23
,
ARTTIM23
}
};
};
static
const
byte
drwtim_regs
[
2
][
2
]
=
{
static
const
u8
drwtim_regs
[
2
][
2
]
=
{
{
DRWTIM0
,
DRWTIM1
},
{
DRWTIM0
,
DRWTIM1
},
{
DRWTIM2
,
DRWTIM3
}
{
DRWTIM2
,
DRWTIM3
}
};
};
int
channel
=
(
int
)
HWIF
(
drive
)
->
channel
;
int
channel
=
(
int
)
HWIF
(
drive
)
->
channel
;
int
slave
=
(
drives
!=
drive
);
/* Is this really the best way to determine this?? */
int
slave
=
(
drives
!=
drive
);
/* Is this really the best way to determine this?? */
cmdprintk
(
"program_drive_count parameters = s(%d),a(%d),r(%d),p(%d)
\n
"
,
setup_count
,
cmdprintk
(
"program_drive_count parameters = s(%d),a(%d),r(%d),p(%d)
\n
"
,
active_count
,
recovery_count
,
drive
->
present
);
setup_count
,
active_count
,
recovery_count
,
drive
->
present
);
/*
/*
* Set up address setup count registers.
* Set up address setup count registers.
* Primary interface has individual count/timing registers for
* Primary interface has individual count/timing registers for
...
@@ -282,8 +200,10 @@ static void program_drive_counts (ide_drive_t *drive, int setup_count, int activ
...
@@ -282,8 +200,10 @@ static void program_drive_counts (ide_drive_t *drive, int setup_count, int activ
*/
*/
if
(
channel
)
{
if
(
channel
)
{
drive
->
drive_data
=
setup_count
;
drive
->
drive_data
=
setup_count
;
setup_count
=
IDE_MAX
(
drives
[
0
].
drive_data
,
drives
[
1
].
drive_data
);
setup_count
=
IDE_MAX
(
drives
[
0
].
drive_data
,
cmdprintk
(
"Secondary interface, setup_count = %d
\n
"
,
setup_count
);
drives
[
1
].
drive_data
);
cmdprintk
(
"Secondary interface, setup_count = %d
\n
"
,
setup_count
);
}
}
/*
/*
...
@@ -306,14 +226,14 @@ static void program_drive_counts (ide_drive_t *drive, int setup_count, int activ
...
@@ -306,14 +226,14 @@ static void program_drive_counts (ide_drive_t *drive, int setup_count, int activ
*/
*/
(
void
)
pci_read_config_byte
(
dev
,
arttim_regs
[
channel
][
slave
],
&
temp_b
);
(
void
)
pci_read_config_byte
(
dev
,
arttim_regs
[
channel
][
slave
],
&
temp_b
);
(
void
)
pci_write_config_byte
(
dev
,
arttim_regs
[
channel
][
slave
],
(
void
)
pci_write_config_byte
(
dev
,
arttim_regs
[
channel
][
slave
],
((
byte
)
setup_count
)
|
(
temp_b
&
0x3f
));
((
u8
)
setup_count
)
|
(
temp_b
&
0x3f
));
(
void
)
pci_write_config_byte
(
dev
,
drwtim_regs
[
channel
][
slave
],
(
void
)
pci_write_config_byte
(
dev
,
drwtim_regs
[
channel
][
slave
],
(
byte
)
((
active_count
<<
4
)
|
recovery_count
));
(
u8
)
((
active_count
<<
4
)
|
recovery_count
));
cmdprintk
(
"Write %x to %x
\n
"
,
cmdprintk
(
"Write %x to %x
\n
"
,
((
byte
)
setup_count
)
|
(
temp_b
&
0x3f
),
((
u8
)
setup_count
)
|
(
temp_b
&
0x3f
),
arttim_regs
[
channel
][
slave
]);
arttim_regs
[
channel
][
slave
]);
cmdprintk
(
"Write %x to %x
\n
"
,
cmdprintk
(
"Write %x to %x
\n
"
,
(
byte
)
((
active_count
<<
4
)
|
recovery_count
),
(
u8
)
((
active_count
<<
4
)
|
recovery_count
),
drwtim_regs
[
channel
][
slave
]);
drwtim_regs
[
channel
][
slave
]);
local_irq_restore
(
flags
);
local_irq_restore
(
flags
);
}
}
...
@@ -325,10 +245,12 @@ static void program_drive_counts (ide_drive_t *drive, int setup_count, int activ
...
@@ -325,10 +245,12 @@ static void program_drive_counts (ide_drive_t *drive, int setup_count, int activ
* 8: prefetch off, 9: prefetch on, 255: auto-select best mode.
* 8: prefetch off, 9: prefetch on, 255: auto-select best mode.
* Called with 255 at boot time.
* Called with 255 at boot time.
*/
*/
static
void
cmd64x_tuneproc
(
ide_drive_t
*
drive
,
byte
mode_wanted
)
static
void
cmd64x_tuneproc
(
ide_drive_t
*
drive
,
u8
mode_wanted
)
{
{
int
setup_time
,
active_time
,
recovery_time
,
clock_time
,
pio_mode
,
cycle_time
;
int
setup_time
,
active_time
,
recovery_time
;
byte
recovery_count2
,
cycle_count
;
int
clock_time
,
pio_mode
,
cycle_time
;
u8
recovery_count2
,
cycle_count
;
int
setup_count
,
active_count
,
recovery_count
;
int
setup_count
,
active_count
,
recovery_count
;
int
bus_speed
=
system_bus_clock
();
int
bus_speed
=
system_bus_clock
();
/*byte b;*/
/*byte b;*/
...
@@ -393,16 +315,20 @@ static void cmd64x_tuneproc (ide_drive_t *drive, byte mode_wanted)
...
@@ -393,16 +315,20 @@ static void cmd64x_tuneproc (ide_drive_t *drive, byte mode_wanted)
setup_count
,
active_count
,
recovery_count
);
setup_count
,
active_count
,
recovery_count
);
}
}
static
byte
cmd64x_ratemask
(
ide_drive_t
*
drive
)
static
u8
cmd64x_ratemask
(
ide_drive_t
*
drive
)
{
{
struct
pci_dev
*
dev
=
HWIF
(
drive
)
->
pci_dev
;
struct
pci_dev
*
dev
=
HWIF
(
drive
)
->
pci_dev
;
byte
mode
=
0x0
0
;
u8
mode
=
0
;
switch
(
dev
->
device
)
{
switch
(
dev
->
device
)
{
case
PCI_DEVICE_ID_CMD_680
:
{
mode
|=
0x04
;
break
;
}
case
PCI_DEVICE_ID_CMD_649
:
case
PCI_DEVICE_ID_CMD_649
:
{
mode
|=
0x03
;
break
;
}
mode
=
3
;
case
PCI_DEVICE_ID_CMD_648
:
{
mode
|=
0x02
;
break
;
}
break
;
case
PCI_DEVICE_ID_CMD_643
:
{
mode
|=
0x01
;
break
;
}
case
PCI_DEVICE_ID_CMD_648
:
mode
=
2
;
break
;
case
PCI_DEVICE_ID_CMD_643
:
return
0
;
case
PCI_DEVICE_ID_CMD_646
:
case
PCI_DEVICE_ID_CMD_646
:
{
{
...
@@ -424,155 +350,51 @@ static byte cmd64x_ratemask (ide_drive_t *drive)
...
@@ -424,155 +350,51 @@ static byte cmd64x_ratemask (ide_drive_t *drive)
*/
*/
switch
(
class_rev
)
{
switch
(
class_rev
)
{
case
0x07
:
case
0x07
:
case
0x05
:
{
mode
|=
0x01
;
break
;
}
case
0x05
:
return
1
;
case
0x03
:
case
0x03
:
case
0x01
:
case
0x01
:
default:
{
mode
|=
0x00
;
break
;
}
default:
}
return
0
;
}
}
if
(
!
eighty_ninty_three
(
drive
))
{
mode
&=
~
0xFE
;
mode
|=
0x01
;
}
return
(
mode
&=
~
0xF8
);
}
static
byte
cmd64x_ratefilter
(
ide_drive_t
*
drive
,
byte
speed
)
{
#ifdef CONFIG_BLK_DEV_IDEDMA
byte
mode
=
cmd64x_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
;
}
static
byte
cmd680_taskfile_timing
(
ide_hwif_t
*
hwif
)
{
struct
pci_dev
*
dev
=
hwif
->
pci_dev
;
byte
addr_mask
=
(
hwif
->
channel
)
?
0xB2
:
0xA2
;
unsigned
short
timing
;
pci_read_config_word
(
dev
,
addr_mask
,
&
timing
);
switch
(
timing
)
{
case
0x10c1
:
return
4
;
case
0x10c3
:
return
3
;
case
0x1281
:
return
2
;
case
0x2283
:
return
1
;
case
0x328a
:
default:
return
0
;
}
}
}
static
void
cmd680_tuneproc
(
ide_drive_t
*
drive
,
byte
mode_wanted
)
{
ide_hwif_t
*
hwif
=
HWIF
(
drive
);
struct
pci_dev
*
dev
=
hwif
->
pci_dev
;
byte
drive_pci
;
unsigned
short
speedt
;
switch
(
drive
->
dn
)
{
case
0
:
drive_pci
=
0xA4
;
break
;
case
1
:
drive_pci
=
0xA6
;
break
;
case
2
:
drive_pci
=
0xB4
;
break
;
case
3
:
drive_pci
=
0xB6
;
break
;
default:
return
;
}
}
pci_read_config_word
(
dev
,
drive_pci
,
&
speedt
);
/* cheat for now and use the docs */
// switch(cmd680_taskfile_timing(hwif)) {
switch
(
mode_wanted
)
{
case
4
:
speedt
=
0x10c1
;
break
;
case
3
:
speedt
=
0x10C3
;
break
;
case
2
:
speedt
=
0x1104
;
break
;
case
1
:
speedt
=
0x2283
;
break
;
case
0
:
default:
speedt
=
0x328A
;
break
;
}
}
pci_write_config_word
(
dev
,
drive_pci
,
speedt
);
if
(
!
eighty_ninty_three
(
drive
))
mode
=
min
(
mode
,
(
u8
)
1
);
return
mode
;
}
}
static
void
config_cmd64x_chipset_for_pio
(
ide_drive_t
*
drive
,
byte
set_speed
)
static
void
config_cmd64x_chipset_for_pio
(
ide_drive_t
*
drive
,
u8
set_speed
)
{
{
byte
speed
=
0x00
;
byte
set_pio
=
ide_get_best_pio_mode
(
drive
,
4
,
5
,
NULL
);
cmd64x_tuneproc
(
drive
,
set_pio
);
speed
=
XFER_PIO_0
+
set_pio
;
if
(
set_speed
)
(
void
)
ide_config_drive_speed
(
drive
,
speed
);
}
static
void
config_cmd680_chipset_for_pio
(
ide_drive_t
*
drive
,
byte
set_speed
)
{
ide_hwif_t
*
hwif
=
HWIF
(
drive
);
struct
pci_dev
*
dev
=
hwif
->
pci_dev
;
u8
unit
=
(
drive
->
select
.
b
.
unit
&
0x01
);
u8
addr_mask
=
(
hwif
->
channel
)
?
0x84
:
0x80
;
u8
speed
=
0x00
;
u8
speed
=
0x00
;
u8
mode_pci
=
0x00
;
u8
channel_timings
=
cmd680_taskfile_timing
(
hwif
);
u8
set_pio
=
ide_get_best_pio_mode
(
drive
,
4
,
5
,
NULL
);
u8
set_pio
=
ide_get_best_pio_mode
(
drive
,
4
,
5
,
NULL
);
pci_read_config_byte
(
dev
,
addr_mask
,
&
mode_pci
);
cmd64x_tuneproc
(
drive
,
set_pio
);
mode_pci
&=
~
((
unit
)
?
0x30
:
0x03
);
/* WARNING PIO timing mess is going to happen b/w devices, argh */
if
((
channel_timings
!=
set_pio
)
&&
(
set_pio
>
channel_timings
))
set_pio
=
channel_timings
;
cmd680_tuneproc
(
drive
,
set_pio
);
speed
=
XFER_PIO_0
+
set_pio
;
speed
=
XFER_PIO_0
+
set_pio
;
if
(
set_speed
)
if
(
set_speed
)
(
void
)
ide_config_drive_speed
(
drive
,
speed
);
(
void
)
ide_config_drive_speed
(
drive
,
speed
);
}
}
static
void
config_chipset_for_pio
(
ide_drive_t
*
drive
,
byte
set_speed
)
static
void
config_chipset_for_pio
(
ide_drive_t
*
drive
,
u8
set_speed
)
{
{
switch
(
HWIF
(
drive
)
->
pci_dev
->
device
)
{
case
PCI_DEVICE_ID_CMD_680
:
config_cmd680_chipset_for_pio
(
drive
,
set_speed
);
return
;
default:
break
;
}
config_cmd64x_chipset_for_pio
(
drive
,
set_speed
);
config_cmd64x_chipset_for_pio
(
drive
,
set_speed
);
}
}
static
int
cmd64x_tune_chipset
(
ide_drive_t
*
drive
,
byte
xferspeed
)
static
int
cmd64x_tune_chipset
(
ide_drive_t
*
drive
,
u8
xferspeed
)
{
{
#ifdef CONFIG_BLK_DEV_IDEDMA
#ifdef CONFIG_BLK_DEV_IDEDMA
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
;
u8
unit
=
(
drive
->
select
.
b
.
unit
&
0x01
);
u8
unit
=
(
drive
->
select
.
b
.
unit
&
0x01
);
u8
pciU
=
(
hwif
->
channel
)
?
UDIDETCR1
:
UDIDETCR0
;
u8
regU
=
0
,
pciU
=
(
hwif
->
channel
)
?
UDIDETCR1
:
UDIDETCR0
;
u8
pciD
=
(
hwif
->
channel
)
?
BMIDESR1
:
BMIDESR0
;
u8
regD
=
0
,
pciD
=
(
hwif
->
channel
)
?
BMIDESR1
:
BMIDESR0
;
u8
regU
=
0
;
u8
regD
=
0
;
#endif
/* CONFIG_BLK_DEV_IDEDMA */
#endif
/* CONFIG_BLK_DEV_IDEDMA */
u8
speed
=
cmd64x_ratefilter
(
drive
,
xferspeed
);
u8
speed
=
ide_rate_filter
(
cmd64x_ratemask
(
drive
)
,
xferspeed
);
#ifdef CONFIG_BLK_DEV_IDEDMA
#ifdef CONFIG_BLK_DEV_IDEDMA
if
((
drive
->
media
!=
ide_disk
)
&&
(
speed
<
XFER_SW_DMA_0
))
if
(
speed
>
XFER_PIO_4
)
{
return
1
;
(
void
)
pci_read_config_byte
(
dev
,
pciD
,
&
regD
);
(
void
)
pci_read_config_byte
(
dev
,
pciD
,
&
regD
);
(
void
)
pci_read_config_byte
(
dev
,
pciU
,
&
regU
);
(
void
)
pci_read_config_byte
(
dev
,
pciU
,
&
regU
);
regD
&=
~
(
unit
?
0x40
:
0x20
);
regD
&=
~
(
unit
?
0x40
:
0x20
);
...
@@ -581,6 +403,7 @@ static int cmd64x_tune_chipset (ide_drive_t *drive, byte xferspeed)
...
@@ -581,6 +403,7 @@ static int cmd64x_tune_chipset (ide_drive_t *drive, byte xferspeed)
(
void
)
pci_write_config_byte
(
dev
,
pciU
,
regU
);
(
void
)
pci_write_config_byte
(
dev
,
pciU
,
regU
);
(
void
)
pci_read_config_byte
(
dev
,
pciD
,
&
regD
);
(
void
)
pci_read_config_byte
(
dev
,
pciD
,
&
regD
);
(
void
)
pci_read_config_byte
(
dev
,
pciU
,
&
regU
);
(
void
)
pci_read_config_byte
(
dev
,
pciU
,
&
regU
);
}
#endif
/* CONFIG_BLK_DEV_IDEDMA */
#endif
/* CONFIG_BLK_DEV_IDEDMA */
switch
(
speed
)
{
switch
(
speed
)
{
...
@@ -609,127 +432,12 @@ static int cmd64x_tune_chipset (ide_drive_t *drive, byte xferspeed)
...
@@ -609,127 +432,12 @@ static int cmd64x_tune_chipset (ide_drive_t *drive, byte xferspeed)
}
}
#ifdef CONFIG_BLK_DEV_IDEDMA
#ifdef CONFIG_BLK_DEV_IDEDMA
if
(
speed
>
XFER_PIO_4
)
{
(
void
)
pci_write_config_byte
(
dev
,
pciU
,
regU
);
(
void
)
pci_write_config_byte
(
dev
,
pciU
,
regU
);
regD
|=
(
unit
?
0x40
:
0x20
);
regD
|=
(
unit
?
0x40
:
0x20
);
(
void
)
pci_write_config_byte
(
dev
,
pciD
,
regD
);
(
void
)
pci_write_config_byte
(
dev
,
pciD
,
regD
);
#endif
/* CONFIG_BLK_DEV_IDEDMA */
return
(
ide_config_drive_speed
(
drive
,
speed
));
}
static
int
cmd680_tune_chipset
(
ide_drive_t
*
drive
,
byte
xferspeed
)
{
ide_hwif_t
*
hwif
=
HWIF
(
drive
);
struct
pci_dev
*
dev
=
hwif
->
pci_dev
;
u8
addr_mask
=
(
hwif
->
channel
)
?
0x84
:
0x80
;
u8
unit
=
(
drive
->
select
.
b
.
unit
&
0x01
);
u8
speed
=
cmd64x_ratefilter
(
drive
,
xferspeed
);
u8
dma_pci
=
0
;
u8
udma_pci
=
0
;
u8
mode_pci
=
0
;
u8
scsc
=
0
;
u16
ultra
=
0
;
u16
multi
=
0
;
pci_read_config_byte
(
dev
,
addr_mask
,
&
mode_pci
);
pci_read_config_byte
(
dev
,
0x8A
,
&
scsc
);
switch
(
drive
->
dn
)
{
case
0
:
dma_pci
=
0xA8
;
udma_pci
=
0xAC
;
break
;
case
1
:
dma_pci
=
0xAA
;
udma_pci
=
0xAE
;
break
;
case
2
:
dma_pci
=
0xB8
;
udma_pci
=
0xBC
;
break
;
case
3
:
dma_pci
=
0xBA
;
udma_pci
=
0xBE
;
break
;
default:
return
1
;
}
}
pci_read_config_byte
(
dev
,
addr_mask
,
&
mode_pci
);
mode_pci
&=
~
((
unit
)
?
0x30
:
0x03
);
pci_read_config_word
(
dev
,
dma_pci
,
&
multi
);
pci_read_config_word
(
dev
,
udma_pci
,
&
ultra
);
if
((
speed
==
XFER_UDMA_6
)
&&
(
scsc
&
0x30
)
==
0x00
)
{
pci_write_config_byte
(
dev
,
0x8A
,
scsc
|
0x01
);
pci_read_config_byte
(
dev
,
0x8A
,
&
scsc
);
#if 0
/* if 133 clock fails, switch to 2xbus clock */
if (!(scsc & 0x01))
pci_write_config_byte(dev, 0x8A, scsc|0x10);
#endif
}
switch
(
speed
)
{
#ifdef CONFIG_BLK_DEV_IDEDMA
case
XFER_UDMA_6
:
if
((
scsc
&
0x30
)
==
0x00
)
goto
speed_break
;
multi
=
0x10C1
;
ultra
&=
~
0x3F
;
ultra
|=
0x01
;
break
;
speed_break
:
speed
=
XFER_UDMA_5
;
case
XFER_UDMA_5
:
multi
=
0x10C1
;
ultra
&=
~
0x3F
;
ultra
|=
(((
scsc
&
0x30
)
==
0x00
)
?
0x01
:
0x02
);
break
;
case
XFER_UDMA_4
:
multi
=
0x10C1
;
ultra
&=
~
0x3F
;
ultra
|=
(((
scsc
&
0x30
)
==
0x00
)
?
0x02
:
0x03
);
break
;
case
XFER_UDMA_3
:
multi
=
0x10C1
;
ultra
&=
~
0x3F
;
ultra
|=
(((
scsc
&
0x30
)
==
0x00
)
?
0x04
:
0x05
);
break
;
case
XFER_UDMA_2
:
multi
=
0x10C1
;
ultra
&=
~
0x3F
;
ultra
|=
(((
scsc
&
0x30
)
==
0x00
)
?
0x05
:
0x07
);
break
;
case
XFER_UDMA_1
:
multi
=
0x10C1
;
ultra
&=
~
0x3F
;
ultra
|=
(((
scsc
&
0x30
)
==
0x00
)
?
0x07
:
0x0B
);
break
;
case
XFER_UDMA_0
:
multi
=
0x10C1
;
ultra
&=
~
0x3F
;
ultra
|=
(((
scsc
&
0x30
)
==
0x00
)
?
0x0C
:
0x0F
);
break
;
case
XFER_MW_DMA_2
:
multi
=
0x10C1
;
break
;
case
XFER_MW_DMA_1
:
multi
=
0x10C2
;
break
;
case
XFER_MW_DMA_0
:
multi
=
0x2208
;
break
;
#endif
/* CONFIG_BLK_DEV_IDEDMA */
#endif
/* CONFIG_BLK_DEV_IDEDMA */
case
XFER_PIO_4
:
cmd680_tuneproc
(
drive
,
4
);
break
;
case
XFER_PIO_3
:
cmd680_tuneproc
(
drive
,
3
);
break
;
case
XFER_PIO_2
:
cmd680_tuneproc
(
drive
,
2
);
break
;
case
XFER_PIO_1
:
cmd680_tuneproc
(
drive
,
1
);
break
;
case
XFER_PIO_0
:
cmd680_tuneproc
(
drive
,
0
);
break
;
default:
return
1
;
}
if
(
speed
>=
XFER_MW_DMA_0
)
config_cmd680_chipset_for_pio
(
drive
,
0
);
if
(
speed
>=
XFER_UDMA_0
)
mode_pci
|=
((
unit
)
?
0x30
:
0x03
);
else
if
(
speed
>=
XFER_MW_DMA_0
)
mode_pci
|=
((
unit
)
?
0x20
:
0x02
);
else
mode_pci
|=
((
unit
)
?
0x10
:
0x01
);
pci_write_config_byte
(
dev
,
addr_mask
,
mode_pci
);
pci_write_config_word
(
dev
,
dma_pci
,
multi
);
pci_write_config_word
(
dev
,
udma_pci
,
ultra
);
return
(
ide_config_drive_speed
(
drive
,
speed
));
return
(
ide_config_drive_speed
(
drive
,
speed
));
}
}
...
@@ -737,137 +445,61 @@ speed_break :
...
@@ -737,137 +445,61 @@ speed_break :
#ifdef CONFIG_BLK_DEV_IDEDMA
#ifdef CONFIG_BLK_DEV_IDEDMA
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
,
cmd64x_ratemask
(
drive
));
ide_hwif_t
*
hwif
=
HWIF
(
drive
);
byte
mode
=
cmd64x_ratemask
(
drive
);
byte
speed
=
0x00
;
byte
set_pio
=
0x00
;
int
rval
;
if
(
drive
->
media
!=
ide_disk
)
{
cmdprintk
(
"CMD64X: drive->media != ide_disk at double check,"
" inital check failed!!
\n
"
);
return
((
int
)
ide_dma_off
);
}
switch
(
mode
)
{
config_chipset_for_pio
(
drive
,
(
!
(
speed
)));
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:
{
set_pio
=
1
;
break
;
}
}
if
(
!
drive
->
init_speed
)
if
((
!
(
speed
)))
drive
->
init_speed
=
speed
;
return
0
;
config_chipset_for_pio
(
drive
,
set_pio
);
if
(
set_pio
)
return
((
int
)
ide_dma_off_quietly
);
if
(
hwif
->
speedproc
(
drive
,
speed
))
if
(
HWIF
(
drive
)
->
speedproc
(
drive
,
speed
))
return
((
int
)
ide_dma_off
)
;
return
0
;
rval
=
(
int
)(
((
id
->
dma_ultra
>>
14
)
&
3
)
?
ide_dma_on
:
if
(
!
drive
->
init_speed
)
((
id
->
dma_ultra
>>
11
)
&
7
)
?
ide_dma_on
:
drive
->
init_speed
=
speed
;
((
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
rval
;
return
ide_dma_enable
(
drive
)
;
}
}
static
int
cmd64x_config_drive_for_dma
(
ide_drive_t
*
drive
)
static
int
cmd64x_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
);
ide_dma_action_t
dma_func
=
ide_dma_on
;
struct
hd_driveid
*
id
=
drive
->
id
;
if
((
id
!=
NULL
)
&&
((
id
->
capability
&
1
)
!=
0
)
&&
if
((
id
!=
NULL
)
&&
((
id
->
capability
&
1
)
!=
0
)
&&
drive
->
autodma
)
{
hwif
->
autodma
&&
(
drive
->
media
==
ide_disk
))
{
/* 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
)
&&
cmd64x_ratemask
(
drive
))
{
if
((
id
->
field_valid
&
4
)
&&
cmd64x_ratemask
(
drive
))
{
if
(
id
->
dma_ultra
&
0x007F
)
{
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
;
}
}
else
if
(
ide_dmaproc
(
ide_dma_good_drive
,
drive
))
{
if
(
id
->
eide_dma_time
>
150
)
{
goto
no_dma_set
;
goto
no_dma_set
;
}
}
}
else
if
(
hwif
->
ide_dma_good_drive
(
drive
)
&&
(
id
->
eide_dma_time
<
150
))
{
/* 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:
config_chipset_for_pio
(
drive
,
1
);
config_chipset_for_pio
(
drive
,
1
);
return
hwif
->
ide_dma_off_quietly
(
drive
);
}
}
return
HWIF
(
drive
)
->
dmaproc
(
dma_func
,
drive
);
return
hwif
->
ide_dma_on
(
drive
);
}
static
int
cmd680_dmaproc
(
ide_dma_action_t
func
,
ide_drive_t
*
drive
)
{
switch
(
func
)
{
case
ide_dma_check
:
return
cmd64x_config_drive_for_dma
(
drive
);
default:
break
;
}
/* Other cases are done by generic IDE-DMA code. */
return
ide_dmaproc
(
func
,
drive
);
}
}
static
int
cmd64x_alt_dma_status
(
struct
pci_dev
*
dev
)
static
int
cmd64x_alt_dma_status
(
struct
pci_dev
*
dev
)
...
@@ -882,31 +514,26 @@ static int cmd64x_alt_dma_status (struct pci_dev *dev)
...
@@ -882,31 +514,26 @@ static int cmd64x_alt_dma_status (struct pci_dev *dev)
return
0
;
return
0
;
}
}
static
int
cmd64x_
dmaproc
(
ide_dma_action_t
func
,
ide_drive_t
*
drive
)
static
int
cmd64x_
ide_dma_end
(
ide_drive_t
*
drive
)
{
{
byte
dma_stat
=
0
;
u8
dma_stat
=
0
,
dma_cmd
=
0
;
byte
dma_alt_stat
=
0
;
ide_hwif_t
*
hwif
=
HWIF
(
drive
);
ide_hwif_t
*
hwif
=
HWIF
(
drive
);
byte
mask
=
(
hwif
->
channel
)
?
MRDMODE_INTR_CH1
:
MRDMODE_INTR_CH0
;
unsigned
long
dma_base
=
hwif
->
dma_base
;
struct
pci_dev
*
dev
=
hwif
->
pci_dev
;
struct
pci_dev
*
dev
=
hwif
->
pci_dev
;
byte
alt_dma_stat
=
cmd64x_alt_dma_status
(
dev
);
switch
(
func
)
{
case
ide_dma_check
:
return
cmd64x_config_drive_for_dma
(
drive
);
case
ide_dma_end
:
/* returns 1 on error, 0 otherwise */
drive
->
waiting_for_dma
=
0
;
drive
->
waiting_for_dma
=
0
;
/* read DMA command state */
dma_cmd
=
hwif
->
INB
(
hwif
->
dma_command
);
/* stop DMA */
/* stop DMA */
OUT_BYTE
(
IN_BYTE
(
dma_base
)
&~
1
,
dma_base
);
hwif
->
OUTB
((
dma_cmd
&
~
1
),
hwif
->
dma_command
);
/* get DMA status */
/* get DMA status */
dma_stat
=
IN_BYTE
(
dma_base
+
2
);
dma_stat
=
hwif
->
INB
(
hwif
->
dma_status
);
/* clear the INTR & ERROR bits */
/* clear the INTR & ERROR bits */
OUT_BYTE
(
dma_stat
|
6
,
dma_base
+
2
);
hwif
->
OUTB
(
dma_stat
|
6
,
hwif
->
dma_status
);
if
(
alt_dma_stat
)
{
if
(
cmd64x_alt_dma_status
(
dev
))
{
byte
dma_intr
=
0
;
u8
dma_intr
=
0
;
byte
dma_mask
=
(
hwif
->
channel
)
?
ARTTIM23_INTR_CH1
:
CFR_INTR_CH0
;
u8
dma_mask
=
(
hwif
->
channel
)
?
ARTTIM23_INTR_CH1
:
byte
dma_reg
=
(
hwif
->
channel
)
?
ARTTIM2
:
CFR
;
CFR_INTR_CH0
;
u8
dma_reg
=
(
hwif
->
channel
)
?
ARTTIM2
:
CFR
;
(
void
)
pci_read_config_byte
(
dev
,
dma_reg
,
&
dma_intr
);
(
void
)
pci_read_config_byte
(
dev
,
dma_reg
,
&
dma_intr
);
/* clear the INTR bit */
/* clear the INTR bit */
(
void
)
pci_write_config_byte
(
dev
,
dma_reg
,
dma_intr
|
dma_mask
);
(
void
)
pci_write_config_byte
(
dev
,
dma_reg
,
dma_intr
|
dma_mask
);
...
@@ -915,144 +542,62 @@ static int cmd64x_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
...
@@ -915,144 +542,62 @@ static int cmd64x_dmaproc (ide_dma_action_t func, ide_drive_t *drive)
ide_destroy_dmatable
(
drive
);
ide_destroy_dmatable
(
drive
);
/* verify good DMA status */
/* verify good DMA status */
return
(
dma_stat
&
7
)
!=
4
;
return
(
dma_stat
&
7
)
!=
4
;
case
ide_dma_test_irq
:
/* returns 1 if dma irq issued, 0 otherwise */
}
dma_stat
=
IN_BYTE
(
dma_base
+
2
);
static
int
cmd64x_ide_dma_test_irq
(
ide_drive_t
*
drive
)
{
ide_hwif_t
*
hwif
=
HWIF
(
drive
);
struct
pci_dev
*
dev
=
hwif
->
pci_dev
;
u8
dma_alt_stat
=
0
,
mask
=
(
hwif
->
channel
)
?
MRDMODE_INTR_CH1
:
MRDMODE_INTR_CH0
;
u8
dma_stat
=
hwif
->
INB
(
hwif
->
dma_status
);
(
void
)
pci_read_config_byte
(
dev
,
MRDMODE
,
&
dma_alt_stat
);
(
void
)
pci_read_config_byte
(
dev
,
MRDMODE
,
&
dma_alt_stat
);
#ifdef DEBUG
#ifdef DEBUG
printk
(
"%s: dma_stat: 0x%02x dma_alt_stat: "
printk
(
"%s: dma_stat: 0x%02x dma_alt_stat: "
"0x%02x mask: 0x%02x
\n
"
,
drive
->
name
,
"0x%02x mask: 0x%02x
\n
"
,
drive
->
name
,
dma_stat
,
dma_alt_stat
,
mask
);
dma_stat
,
dma_alt_stat
,
mask
);
#endif
#endif
if
(
!
(
dma_alt_stat
&
mask
))
{
if
(
!
(
dma_alt_stat
&
mask
))
return
0
;
return
0
;
}
/* return 1 if INTR asserted */
/* return 1 if INTR asserted */
return
(
dma_stat
&
4
)
==
4
;
if
((
dma_stat
&
4
)
==
4
)
default:
return
1
;
break
;
}
return
0
;
/* Other cases are done by generic IDE-DMA code. */
return
ide_dmaproc
(
func
,
drive
);
}
}
/*
/*
* ASUS P55T2P4D with CMD646 chipset revision 0x01 requires the old
* ASUS P55T2P4D with CMD646 chipset revision 0x01 requires the old
* event order for DMA transfers.
* event order for DMA transfers.
*/
*/
static
int
cmd646_1_dmaproc
(
ide_dma_action_t
func
,
ide_drive_t
*
drive
)
static
int
cmd646_1_ide_dma_end
(
ide_drive_t
*
drive
)
{
{
ide_hwif_t
*
hwif
=
HWIF
(
drive
);
ide_hwif_t
*
hwif
=
HWIF
(
drive
);
unsigned
long
dma_base
=
hwif
->
dma_base
;
u8
dma_stat
=
0
,
dma_cmd
=
0
;
byte
dma_stat
;
switch
(
func
)
{
case
ide_dma_check
:
return
cmd64x_config_drive_for_dma
(
drive
);
case
ide_dma_end
:
drive
->
waiting_for_dma
=
0
;
drive
->
waiting_for_dma
=
0
;
/* get DMA status */
/* get DMA status */
dma_stat
=
IN_BYTE
(
dma_base
+
2
);
dma_stat
=
hwif
->
INB
(
hwif
->
dma_status
);
/* read DMA command state */
dma_cmd
=
hwif
->
INB
(
hwif
->
dma_command
);
/* stop DMA */
/* stop DMA */
OUT_BYTE
(
IN_BYTE
(
dma_base
)
&~
1
,
dma_base
);
hwif
->
OUTB
((
dma_cmd
&
~
1
),
hwif
->
dma_command
);
/* clear the INTR & ERROR bits */
/* clear the INTR & ERROR bits */
OUT_BYTE
(
dma_stat
|
6
,
dma_base
+
2
);
hwif
->
OUTB
(
dma_stat
|
6
,
hwif
->
dma_status
);
/* and free any DMA resources */
/* and free any DMA resources */
ide_destroy_dmatable
(
drive
);
ide_destroy_dmatable
(
drive
);
/* verify good DMA status */
/* verify good DMA status */
return
(
dma_stat
&
7
)
!=
4
;
return
(
dma_stat
&
7
)
!=
4
;
default:
break
;
}
/* Other cases are done by generic IDE-DMA code. */
return
ide_dmaproc
(
func
,
drive
);
}
}
#endif
/* CONFIG_BLK_DEV_IDEDMA */
#endif
/* CONFIG_BLK_DEV_IDEDMA */
static
int
cmd680_busproc
(
ide_drive_t
*
drive
,
int
state
)
static
unsigned
int
__init
init_chipset_cmd64x
(
struct
pci_dev
*
dev
,
const
char
*
name
)
{
#if 0
ide_hwif_t *hwif = HWIF(drive);
u8 addr_mask = (hwif->channel) ? 0xB0 : 0xA0;
u32 stat_config = 0;
pci_read_config_dword(hwif->pci_dev, addr_mask, &stat_config);
if (!hwif)
return -EINVAL;
switch (state) {
case BUSSTATE_ON:
hwif->drives[0].failures = 0;
hwif->drives[1].failures = 0;
break;
case BUSSTATE_OFF:
hwif->drives[0].failures = hwif->drives[0].max_failures + 1;
hwif->drives[1].failures = hwif->drives[1].max_failures + 1;
break;
case BUSSTATE_TRISTATE:
hwif->drives[0].failures = hwif->drives[0].max_failures + 1;
hwif->drives[1].failures = hwif->drives[1].max_failures + 1;
break;
default:
return 0;
}
hwif->bus_state = state;
#endif
return
0
;
}
void
cmd680_reset
(
ide_drive_t
*
drive
)
{
{
#if 0
u32
class_rev
=
0
;
ide_hwif_t *hwif = HWIF(drive);
u8
mrdmode
=
0
;
u8 addr_mask = (hwif->channel) ? 0xB0 : 0xA0;
byte reset = 0;
pci_read_config_byte(hwif->pci_dev, addr_mask, &reset);
pci_write_config_byte(hwif->pci_dev, addr_mask, reset|0x03);
#endif
}
unsigned
int
cmd680_pci_init
(
struct
pci_dev
*
dev
,
const
char
*
name
)
{
u8
tmpbyte
=
0
;
pci_write_config_byte
(
dev
,
0x80
,
0x00
);
pci_write_config_byte
(
dev
,
0x84
,
0x00
);
pci_read_config_byte
(
dev
,
0x8A
,
&
tmpbyte
);
pci_write_config_byte
(
dev
,
0x8A
,
tmpbyte
|
0x01
);
#if 0
/* if 133 clock fails, switch to 2xbus clock */
if (!(tmpbyte & 0x01)) {
pci_read_config_byte(dev, 0x8A, &tmpbyte);
pci_write_config_byte(dev, 0x8A, tmpbyte|0x10);
}
#endif
pci_write_config_word
(
dev
,
0xA2
,
0x328A
);
pci_write_config_dword
(
dev
,
0xA4
,
0x328A
);
pci_write_config_dword
(
dev
,
0xA8
,
0x4392
);
pci_write_config_dword
(
dev
,
0xAC
,
0x4009
);
pci_write_config_word
(
dev
,
0xB2
,
0x328A
);
pci_write_config_dword
(
dev
,
0xB4
,
0x328A
);
pci_write_config_dword
(
dev
,
0xB8
,
0x4392
);
pci_write_config_dword
(
dev
,
0xBC
,
0x4009
);
cmd_devs
[
n_cmd_devs
++
]
=
dev
;
#if defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_PROC_FS)
if
(
!
cmd64x_proc
)
{
cmd64x_proc
=
1
;
cmd64x_display_info
=
&
cmd64x_get_info
;
}
#endif
/* DISPLAY_CMD64X_TIMINGS && CONFIG_PROC_FS */
return
0
;
}
unsigned
int
cmd64x_pci_init
(
struct
pci_dev
*
dev
,
const
char
*
name
)
{
unsigned
char
mrdmode
;
unsigned
int
class_rev
;
pci_read_config_dword
(
dev
,
PCI_CLASS_REVISION
,
&
class_rev
);
pci_read_config_dword
(
dev
,
PCI_CLASS_REVISION
,
&
class_rev
);
class_rev
&=
0xff
;
class_rev
&=
0xff
;
...
@@ -1127,110 +672,127 @@ unsigned int cmd64x_pci_init (struct pci_dev *dev, const char *name)
...
@@ -1127,110 +672,127 @@ unsigned int cmd64x_pci_init (struct pci_dev *dev, const char *name)
(
void
)
pci_write_config_byte
(
dev
,
UDIDETCR0
,
0xf0
);
(
void
)
pci_write_config_byte
(
dev
,
UDIDETCR0
,
0xf0
);
#endif
/* CONFIG_PPC */
#endif
/* CONFIG_PPC */
#if defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_PROC_FS)
cmd_devs
[
n_cmd_devs
++
]
=
dev
;
cmd_devs
[
n_cmd_devs
++
]
=
dev
;
#if defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_PROC_FS)
if
(
!
cmd64x_proc
)
{
if
(
!
cmd64x_proc
)
{
cmd64x_proc
=
1
;
cmd64x_proc
=
1
;
cmd64x_display_info
=
&
cmd64x_get_info
;
ide_pci_register_host_proc
(
&
cmd64x_procs
[
0
])
;
}
}
#endif
/* DISPLAY_CMD64X_TIMINGS && CONFIG_PROC_FS */
#endif
/* DISPLAY_CMD64X_TIMINGS && CONFIG_PROC_FS */
return
0
;
return
0
;
}
}
unsigned
int
__init
pci_init_cmd64x
(
struct
pci_dev
*
dev
,
const
char
*
name
)
static
unsigned
int
__init
ata66_cmd64x
(
ide_hwif_t
*
hwif
)
{
switch
(
dev
->
device
)
{
case
PCI_DEVICE_ID_CMD_680
:
return
cmd680_pci_init
(
dev
,
name
);
default:
break
;
}
return
cmd64x_pci_init
(
dev
,
name
);
}
unsigned
int
cmd680_ata66
(
ide_hwif_t
*
hwif
)
{
{
byte
ata66
=
0
;
u8
ata66
=
0
,
mask
=
(
hwif
->
channel
)
?
0x02
:
0x01
;
byte
addr_mask
=
(
hwif
->
channel
)
?
0xB0
:
0xA0
;
pci_read_config_byte
(
hwif
->
pci_dev
,
addr_mask
,
&
ata66
);
return
(
ata66
&
0x01
)
?
1
:
0
;
}
unsigned
int
cmd64x_ata66
(
ide_hwif_t
*
hwif
)
{
byte
ata66
=
0
;
byte
mask
=
(
hwif
->
channel
)
?
0x02
:
0x01
;
pci_read_config_byte
(
hwif
->
pci_dev
,
BMIDECSR
,
&
ata66
);
return
(
ata66
&
mask
)
?
1
:
0
;
}
unsigned
int
__init
ata66_cmd64x
(
ide_hwif_t
*
hwif
)
{
switch
(
hwif
->
pci_dev
->
device
)
{
switch
(
hwif
->
pci_dev
->
device
)
{
case
PCI_DEVICE_ID_CMD_680
:
case
PCI_DEVICE_ID_CMD_643
:
return
cmd680_ata66
(
hwif
);
case
PCI_DEVICE_ID_CMD_646
:
return
ata66
;
default:
default:
break
;
break
;
}
}
return
cmd64x_ata66
(
hwif
);
pci_read_config_byte
(
hwif
->
pci_dev
,
BMIDECSR
,
&
ata66
);
return
(
ata66
&
mask
)
?
1
:
0
;
}
}
void
__init
ide_init
_cmd64x
(
ide_hwif_t
*
hwif
)
static
void
__init
init_hwif
_cmd64x
(
ide_hwif_t
*
hwif
)
{
{
struct
pci_dev
*
dev
=
hwif
->
pci_dev
;
struct
pci_dev
*
dev
=
hwif
->
pci_dev
;
unsigned
int
class_rev
;
unsigned
int
class_rev
;
hwif
->
autodma
=
0
;
pci_read_config_dword
(
dev
,
PCI_CLASS_REVISION
,
&
class_rev
);
pci_read_config_dword
(
dev
,
PCI_CLASS_REVISION
,
&
class_rev
);
class_rev
&=
0xff
;
class_rev
&=
0xff
;
hwif
->
tuneproc
=
&
cmd64x_tuneproc
;
hwif
->
speedproc
=
&
cmd64x_tune_chipset
;
if
(
!
hwif
->
dma_base
)
{
hwif
->
drives
[
0
].
autotune
=
1
;
hwif
->
drives
[
0
].
autotune
=
1
;
hwif
->
drives
[
1
].
autotune
=
1
;
hwif
->
drives
[
1
].
autotune
=
1
;
return
;
}
hwif
->
atapi_dma
=
1
;
hwif
->
ultra_mask
=
0x3f
;
hwif
->
mwdma_mask
=
0x07
;
hwif
->
swdma_mask
=
0x07
;
if
(
dev
->
device
==
PCI_DEVICE_ID_CMD_643
)
hwif
->
ultra_mask
=
0x80
;
if
(
dev
->
device
==
PCI_DEVICE_ID_CMD_646
)
if
(
class_rev
>
0x04
)
hwif
->
ultra_mask
=
0x07
;
else
hwif
->
ultra_mask
=
0x80
;
switch
(
dev
->
device
)
{
case
PCI_DEVICE_ID_CMD_680
:
hwif
->
busproc
=
&
cmd680_busproc
;
#ifdef CONFIG_BLK_DEV_IDEDMA
if
(
hwif
->
dma_base
)
hwif
->
dmaproc
=
&
cmd680_dmaproc
;
#endif
/* CONFIG_BLK_DEV_IDEDMA */
hwif
->
resetproc
=
&
cmd680_reset
;
hwif
->
speedproc
=
&
cmd680_tune_chipset
;
hwif
->
tuneproc
=
&
cmd680_tuneproc
;
break
;
case
PCI_DEVICE_ID_CMD_649
:
case
PCI_DEVICE_ID_CMD_648
:
case
PCI_DEVICE_ID_CMD_643
:
#ifdef CONFIG_BLK_DEV_IDEDMA
#ifdef CONFIG_BLK_DEV_IDEDMA
if
(
hwif
->
dma_base
)
hwif
->
ide_dma_check
=
&
cmd64x_config_drive_for_dma
;
hwif
->
dmaproc
=
&
cmd64x_dmaproc
;
if
(
!
(
hwif
->
udma_four
))
#endif
/* CONFIG_BLK_DEV_IDEDMA */
hwif
->
udma_four
=
ata66_cmd64x
(
hwif
);
hwif
->
tuneproc
=
&
cmd64x_tuneproc
;
hwif
->
speedproc
=
&
cmd64x_tune_chipset
;
if
(
dev
->
device
==
PCI_DEVICE_ID_CMD_646
)
{
break
;
case
PCI_DEVICE_ID_CMD_646
:
hwif
->
chipset
=
ide_cmd646
;
hwif
->
chipset
=
ide_cmd646
;
#ifdef CONFIG_BLK_DEV_IDEDMA
if
(
class_rev
==
0x01
)
{
if
(
hwif
->
dma_base
)
{
hwif
->
ide_dma_end
=
&
cmd646_1_ide_dma_end
;
if
(
class_rev
==
0x01
)
}
else
{
hwif
->
dmaproc
=
&
cmd646_1_dmaproc
;
hwif
->
ide_dma_end
=
&
cmd64x_ide_dma_end
;
else
hwif
->
ide_dma_test_irq
=
&
cmd64x_ide_dma_test_irq
;
hwif
->
dmaproc
=
&
cmd64x_dmaproc
;
}
}
#endif
/* CONFIG_BLK_DEV_IDEDMA */
}
else
{
hwif
->
tuneproc
=
&
cmd64x_tuneproc
;
hwif
->
ide_dma_end
=
&
cmd64x_ide_dma_end
;
hwif
->
speedproc
=
&
cmd64x_tune_chipset
;
hwif
->
ide_dma_test_irq
=
&
cmd64x_ide_dma_test_irq
;
break
;
default:
break
;
}
}
#if defined(CONFIG_BLK_DEV_IDEDMA) && defined(CONFIG_IDEDMA_AUTO)
if
(
hwif
->
dma_base
)
if
(
!
noautodma
)
if
(
!
noautodma
)
hwif
->
autodma
=
1
;
hwif
->
autodma
=
1
;
#endif
/* CONFIG_BLK_DEV_IDEDMA && CONFIG_IDEDMA_AUTO*/
hwif
->
drives
[
0
].
autodma
=
hwif
->
autodma
;
hwif
->
drives
[
1
].
autodma
=
hwif
->
autodma
;
#endif
/* CONFIG_BLK_DEV_IDEDMA */
}
/**
* FIXME: not required ?
*/
static
void
__init
init_dma_cmd64x
(
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
*
);
/**
* FIXME: not required either ?
*/
static
void
__init
init_setup_cmd64x
(
struct
pci_dev
*
dev
,
ide_pci_device_t
*
d
)
{
ide_setup_pci_device
(
dev
,
d
);
}
int
__init
cmd64x_scan_pcidev
(
struct
pci_dev
*
dev
)
{
ide_pci_device_t
*
d
;
if
(
dev
->
vendor
!=
PCI_VENDOR_ID_CMD
)
return
0
;
for
(
d
=
cmd64x_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/cmd64x.h
0 → 100644
View file @
563cbaa6
#ifndef CMD64X_H
#define CMD64X_H
#include <linux/config.h>
#include <linux/pci.h>
#include <linux/ide.h>
#define DISPLAY_CMD64X_TIMINGS
#define CMD_DEBUG 0
#if CMD_DEBUG
#define cmdprintk(x...) printk(x)
#else
#define cmdprintk(x...)
#endif
#ifndef SPLIT_BYTE
#define SPLIT_BYTE(B,H,L) ((H)=(B>>4), (L)=(B-((B>>4)<<4)))
#endif
/*
* CMD64x specific registers definition.
*/
#define CFR 0x50
#define CFR_INTR_CH0 0x02
#define CNTRL 0x51
#define CNTRL_DIS_RA0 0x40
#define CNTRL_DIS_RA1 0x80
#define CNTRL_ENA_2ND 0x08
#define CMDTIM 0x52
#define ARTTIM0 0x53
#define DRWTIM0 0x54
#define ARTTIM1 0x55
#define DRWTIM1 0x56
#define ARTTIM23 0x57
#define ARTTIM23_DIS_RA2 0x04
#define ARTTIM23_DIS_RA3 0x08
#define ARTTIM23_INTR_CH1 0x10
#define ARTTIM2 0x57
#define ARTTIM3 0x57
#define DRWTIM23 0x58
#define DRWTIM2 0x58
#define BRST 0x59
#define DRWTIM3 0x5b
#define BMIDECR0 0x70
#define MRDMODE 0x71
#define MRDMODE_INTR_CH0 0x04
#define MRDMODE_INTR_CH1 0x08
#define MRDMODE_BLK_CH0 0x10
#define MRDMODE_BLK_CH1 0x20
#define BMIDESR0 0x72
#define UDIDETCR0 0x73
#define DTPR0 0x74
#define BMIDECR1 0x78
#define BMIDECSR 0x79
#define BMIDESR1 0x7A
#define UDIDETCR1 0x7B
#define DTPR1 0x7C
#if defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_PROC_FS)
#include <linux/stat.h>
#include <linux/proc_fs.h>
static
u8
cmd64x_proc
;
static
char
*
print_cmd64x_get_info
(
char
*
,
struct
pci_dev
*
,
int
);
static
int
cmd64x_get_info
(
char
*
,
char
**
,
off_t
,
int
);
static
ide_pci_host_proc_t
cmd64x_procs
[]
__initdata
=
{
{
name:
"cmd64x"
,
set:
1
,
get_info:
cmd64x_get_info
,
parent:
NULL
,
},
};
#endif
/* defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_PROC_FS) */
static
void
init_setup_cmd64x
(
struct
pci_dev
*
,
ide_pci_device_t
*
);
static
unsigned
int
init_chipset_cmd64x
(
struct
pci_dev
*
,
const
char
*
);
static
void
init_hwif_cmd64x
(
ide_hwif_t
*
);
static
void
init_dma_cmd64x
(
ide_hwif_t
*
,
unsigned
long
);
static
ide_pci_device_t
cmd64x_chipsets
[]
__initdata
=
{
{
vendor:
PCI_VENDOR_ID_CMD
,
device:
PCI_DEVICE_ID_CMD_643
,
name:
"CMD643"
,
init_setup:
init_setup_cmd64x
,
init_chipset:
init_chipset_cmd64x
,
init_iops:
NULL
,
init_hwif:
init_hwif_cmd64x
,
init_dma:
init_dma_cmd64x
,
channels:
2
,
autodma:
AUTODMA
,
enablebits:
{{
0x00
,
0x00
,
0x00
},
{
0x00
,
0x00
,
0x00
}},
bootable:
ON_BOARD
,
extra:
0
,
},{
vendor:
PCI_VENDOR_ID_CMD
,
device:
PCI_DEVICE_ID_CMD_646
,
name:
"CMD646"
,
init_setup:
init_setup_cmd64x
,
init_chipset:
init_chipset_cmd64x
,
init_iops:
NULL
,
init_hwif:
init_hwif_cmd64x
,
init_dma:
init_dma_cmd64x
,
channels:
2
,
autodma:
AUTODMA
,
enablebits:
{{
0x00
,
0x00
,
0x00
},
{
0x51
,
0x80
,
0x80
}},
bootable:
ON_BOARD
,
extra:
0
,
},{
vendor:
PCI_VENDOR_ID_CMD
,
device:
PCI_DEVICE_ID_CMD_648
,
name:
"CMD648"
,
init_setup:
init_setup_cmd64x
,
init_chipset:
init_chipset_cmd64x
,
init_iops:
NULL
,
init_hwif:
init_hwif_cmd64x
,
init_dma:
init_dma_cmd64x
,
channels:
2
,
autodma:
AUTODMA
,
enablebits:
{{
0x00
,
0x00
,
0x00
},
{
0x00
,
0x00
,
0x00
}},
bootable:
ON_BOARD
,
extra:
0
,
},{
vendor:
PCI_VENDOR_ID_CMD
,
device:
PCI_DEVICE_ID_CMD_649
,
name:
"CMD649"
,
init_setup:
init_setup_cmd64x
,
init_chipset:
init_chipset_cmd64x
,
init_iops:
NULL
,
init_hwif:
init_hwif_cmd64x
,
init_dma:
init_dma_cmd64x
,
channels:
2
,
autodma:
AUTODMA
,
enablebits:
{{
0x00
,
0x00
,
0x00
},
{
0x00
,
0x00
,
0x00
}},
bootable:
ON_BOARD
,
extra:
0
,
},{
vendor:
0
,
device:
0
,
channels:
2
,
bootable:
EOL
,
}
};
#endif
/* CMD64X_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