Commit 563cbaa6 authored by Jens Axboe's avatar Jens Axboe

cmd64x update

parent 6813194d
...@@ -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, "\nController: %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 = 0x00; 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;
}
#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 */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment