- Adapt to the MI wdc driver changes which added the notion of
"shadow registers": http://mail-index.netbsd.org/source-changes/2004/05/25/0048.html - While here, also fix accesses to CTL regsters to use the correct address. Now the cobalt bootloader works again. XXX Maybe we should make this SA wdc driver MI...
This commit is contained in:
parent
175e99933e
commit
221c318874
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: pciide.c,v 1.3 2004/01/03 01:50:53 thorpej Exp $ */
|
||||
/* $NetBSD: pciide.c,v 1.4 2004/09/01 15:54:39 tsutsui Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2003 The NetBSD Foundation, Inc.
|
||||
|
@ -40,13 +40,15 @@
|
|||
#include "boot.h"
|
||||
#include "wdvar.h"
|
||||
|
||||
#define COBALT_IO_SPACE_BASE 0x10000000 /* XXX VT82C586 ISA I/O space */
|
||||
|
||||
int
|
||||
pciide_init(chp, unit)
|
||||
struct wdc_channel *chp;
|
||||
u_int *unit;
|
||||
{
|
||||
u_long bpa, addr;
|
||||
int compatchan = 0;
|
||||
u_int32_t cmdreg, ctlreg;
|
||||
int i, compatchan = 0;
|
||||
|
||||
/*
|
||||
* two channels per chip, two drives per channel
|
||||
|
@ -61,12 +63,21 @@ pciide_init(chp, unit)
|
|||
/*
|
||||
* XXX map?
|
||||
*/
|
||||
bpa = PCIIDE_COMPAT_CMD_BASE(compatchan);
|
||||
addr = MIPS_PHYS_TO_KSEG1(bpa);
|
||||
if (bpa < 0x10000000)
|
||||
addr += 0x10000000;
|
||||
cmdreg = MIPS_PHYS_TO_KSEG1(COBALT_IO_SPACE_BASE +
|
||||
PCIIDE_COMPAT_CMD_BASE(compatchan));
|
||||
ctlreg = MIPS_PHYS_TO_KSEG1(COBALT_IO_SPACE_BASE +
|
||||
PCIIDE_COMPAT_CTL_BASE(compatchan));
|
||||
|
||||
/* set up cmd regsiters */
|
||||
chp->c_cmdbase = (u_int8_t *)cmdreg;
|
||||
chp->c_data = (u_int16_t *)(cmdreg + wd_data);
|
||||
for (i = 0; i < WDC_NPORTS; i++)
|
||||
chp->c_cmdreg[i] = chp->c_cmdbase + i;
|
||||
/* set up shadow registers */
|
||||
chp->c_cmdreg[wd_status] = chp->c_cmdreg[wd_command];
|
||||
chp->c_cmdreg[wd_features] = chp->c_cmdreg[wd_precomp];
|
||||
/* set up ctl registers */
|
||||
chp->c_ctlbase = (u_int8_t *)ctlreg;
|
||||
|
||||
chp->c_base = (u_int8_t*)addr;
|
||||
chp->c_data = (u_int16_t*)(addr + wd_data);
|
||||
return (0);
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: wdc.c,v 1.5 2004/01/03 01:50:53 thorpej Exp $ */
|
||||
/* $NetBSD: wdc.c,v 1.6 2004/09/01 15:54:39 tsutsui Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2003 The NetBSD Foundation, Inc.
|
||||
|
@ -67,12 +67,12 @@ __wdcwait_reset(chp, drv_mask)
|
|||
|
||||
/* wait for BSY to deassert */
|
||||
for (timeout = 0; timeout < WDCNDELAY_RST; timeout++) {
|
||||
chp->c_base[wd_sdh] = WDSD_IBM; /* master */
|
||||
WDC_WRITE_REG(chp, wd_sdh, WDSD_IBM); /* master */
|
||||
delay(10);
|
||||
st0 = chp->c_base[wd_status];
|
||||
chp->c_base[wd_sdh] = WDSD_IBM | 0x10; /* slave */
|
||||
st0 = WDC_READ_REG(chp, wd_status);
|
||||
WDC_WRITE_REG(chp, wd_sdh, WDSD_IBM | 0x10); /* slave */
|
||||
delay(10);
|
||||
st1 = chp->c_base[wd_status];
|
||||
st1 = WDC_READ_REG(chp, wd_status);
|
||||
|
||||
if ((drv_mask & 0x01) == 0) {
|
||||
/* no master */
|
||||
|
@ -129,12 +129,12 @@ wdcprobe(chp)
|
|||
/*
|
||||
* Sanity check to see if the wdc channel responds at all.
|
||||
*/
|
||||
chp->c_base[wd_sdh] = WDSD_IBM;
|
||||
WDC_WRITE_REG(chp, wd_sdh, WDSD_IBM);
|
||||
delay(10);
|
||||
st0 = chp->c_base[wd_status];
|
||||
chp->c_base[wd_sdh] = WDSD_IBM | 0x10;
|
||||
st0 = WDC_READ_REG(chp, wd_status);
|
||||
WDC_WRITE_REG(chp, wd_sdh, WDSD_IBM | 0x10);
|
||||
delay(10);
|
||||
st1 = chp->c_base[wd_status];
|
||||
st1 = WDC_READ_REG(chp, wd_status);
|
||||
|
||||
if (st0 == 0xff || st0 == WDSD_IBM)
|
||||
ret_value &= ~0x01;
|
||||
|
@ -144,14 +144,14 @@ wdcprobe(chp)
|
|||
return (ENXIO);
|
||||
|
||||
/* assert SRST, wait for reset to complete */
|
||||
chp->c_base[wd_sdh] = WDSD_IBM;
|
||||
WDC_WRITE_REG(chp, wd_sdh, WDSD_IBM);
|
||||
delay(10);
|
||||
chp->c_base[wd_aux_ctlr] = WDCTL_RST | WDCTL_IDS;
|
||||
WDC_WRITE_CTLREG(chp, wd_aux_ctlr, WDCTL_RST | WDCTL_IDS);
|
||||
delay(1000);
|
||||
chp->c_base[wd_aux_ctlr] = WDCTL_IDS;
|
||||
WDC_WRITE_CTLREG(chp, wd_aux_ctlr, WDCTL_IDS);
|
||||
delay(1000);
|
||||
(void) chp->c_base[wd_error];
|
||||
chp->c_base[wd_aux_ctlr] = WDCTL_4BIT;
|
||||
(void) WDC_READ_REG(chp, wd_error);
|
||||
WDC_WRITE_CTLREG(chp, wd_aux_ctlr, WDCTL_4BIT);
|
||||
delay(10);
|
||||
|
||||
ret_value = __wdcwait_reset(chp, ret_value);
|
||||
|
@ -199,7 +199,7 @@ wdc_wait_for_ready(chp)
|
|||
{
|
||||
u_int timeout;
|
||||
for (timeout = WDC_TIMEOUT; timeout > 0; --timeout) {
|
||||
if ((chp->c_base[wd_status] & (WDCS_BSY | WDCS_DRDY))
|
||||
if ((WDC_READ_REG(chp, wd_status) & (WDCS_BSY | WDCS_DRDY))
|
||||
== WDCS_DRDY)
|
||||
return (0);
|
||||
}
|
||||
|
@ -222,7 +222,7 @@ wdc_read_block(sc, wd_c)
|
|||
return (0);
|
||||
|
||||
for (i = wd_c->bcount; i > 0; i -= sizeof(u_int16_t))
|
||||
*ptr++ = *chp->c_data;
|
||||
*ptr++ = WDC_READ_DATA(chp);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
@ -245,20 +245,21 @@ wdccommand(sc, wd_c)
|
|||
wd_c->r_precomp));
|
||||
#endif
|
||||
|
||||
chp->c_base[wd_precomp] = wd_c->r_precomp;
|
||||
chp->c_base[wd_seccnt] = wd_c->r_count;
|
||||
chp->c_base[wd_sector] = wd_c->r_sector;
|
||||
chp->c_base[wd_cyl_lo] = wd_c->r_cyl;
|
||||
chp->c_base[wd_cyl_hi] = wd_c->r_cyl >> 8;
|
||||
chp->c_base[wd_sdh] = WDSD_IBM | (wd_c->drive << 4) | wd_c->r_head;
|
||||
chp->c_base[wd_command] = wd_c->r_command;
|
||||
WDC_WRITE_REG(chp, wd_precomp, wd_c->r_precomp);
|
||||
WDC_WRITE_REG(chp, wd_seccnt, wd_c->r_count);
|
||||
WDC_WRITE_REG(chp, wd_sector, wd_c->r_sector);
|
||||
WDC_WRITE_REG(chp, wd_cyl_lo, wd_c->r_cyl);
|
||||
WDC_WRITE_REG(chp, wd_cyl_hi, wd_c->r_cyl >> 8);
|
||||
WDC_WRITE_REG(chp, wd_sdh,
|
||||
WDSD_IBM | (wd_c->drive << 4) | wd_c->r_head);
|
||||
WDC_WRITE_REG(chp, wd_command, wd_c->r_command);
|
||||
|
||||
if (wdc_wait_for_ready(chp) != 0)
|
||||
return (ENXIO);
|
||||
|
||||
if (chp->c_base[wd_status] & WDCS_ERR) {
|
||||
if (WDC_READ_REG(chp, wd_status) & WDCS_ERR) {
|
||||
printf("wd%d: error %x\n", chp->compatchan,
|
||||
chp->c_base[wd_error]);
|
||||
WDC_READ_REG(chp, wd_error));
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
|
@ -277,31 +278,31 @@ wdccommandext(wd, wd_c)
|
|||
struct wdc_channel *chp = &wd->sc_channel;
|
||||
|
||||
/* Select drive, head, and addressing mode. */
|
||||
chp->c_base[wd_sdh] = (wd_c->drive << 4) | WDSD_LBA;
|
||||
WDC_WRITE_REG(chp, wd_sdh, (wd_c->drive << 4) | WDSD_LBA);
|
||||
|
||||
/* previous */
|
||||
chp->c_base[wd_features] = 0;
|
||||
chp->c_base[wd_seccnt] = wd_c->r_count >> 8;
|
||||
chp->c_base[wd_lba_hi] = wd_c->r_blkno >> 40;
|
||||
chp->c_base[wd_lba_mi] = wd_c->r_blkno >> 32;
|
||||
chp->c_base[wd_lba_lo] = wd_c->r_blkno >> 24;
|
||||
WDC_WRITE_REG(chp, wd_features, 0);
|
||||
WDC_WRITE_REG(chp, wd_seccnt, wd_c->r_count >> 8);
|
||||
WDC_WRITE_REG(chp, wd_lba_hi, wd_c->r_blkno >> 40);
|
||||
WDC_WRITE_REG(chp, wd_lba_mi, wd_c->r_blkno >> 32);
|
||||
WDC_WRITE_REG(chp, wd_lba_lo, wd_c->r_blkno >> 24);
|
||||
|
||||
/* current */
|
||||
chp->c_base[wd_features] = 0;
|
||||
chp->c_base[wd_seccnt] = wd_c->r_count;
|
||||
chp->c_base[wd_lba_hi] = wd_c->r_blkno >> 16;
|
||||
chp->c_base[wd_lba_mi] = wd_c->r_blkno >> 8;
|
||||
chp->c_base[wd_lba_lo] = wd_c->r_blkno;
|
||||
WDC_WRITE_REG(chp, wd_features, 0);
|
||||
WDC_WRITE_REG(chp, wd_seccnt, wd_c->r_count);
|
||||
WDC_WRITE_REG(chp, wd_lba_hi, wd_c->r_blkno >> 16);
|
||||
WDC_WRITE_REG(chp, wd_lba_mi, wd_c->r_blkno >> 8);
|
||||
WDC_WRITE_REG(chp, wd_lba_lo, wd_c->r_blkno);
|
||||
|
||||
/* Send command. */
|
||||
chp->c_base[wd_command] = wd_c->r_command;
|
||||
WDC_WRITE_REG(chp, wd_command, wd_c->r_command);
|
||||
|
||||
if (wdc_wait_for_ready(chp) != 0)
|
||||
return (ENXIO);
|
||||
|
||||
if (chp->c_base[wd_status] & WDCS_ERR) {
|
||||
if (WDC_READ_REG(chp, wd_status) & WDCS_ERR) {
|
||||
printf("wd%d: error %x\n", chp->compatchan,
|
||||
chp->c_base[wd_error]);
|
||||
WDC_READ_REG(chp, wd_error));
|
||||
return (ENXIO);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* $NetBSD: wdvar.h,v 1.4 2004/01/03 01:50:53 thorpej Exp $ */
|
||||
/* $NetBSD: wdvar.h,v 1.5 2004/09/01 15:54:39 tsutsui Exp $ */
|
||||
|
||||
/*-
|
||||
* Copyright (c) 2003 The NetBSD Foundation, Inc.
|
||||
|
@ -45,14 +45,24 @@
|
|||
#define WDC_TIMEOUT 2000000
|
||||
#define PCIIDE_CHANNEL_NDEV 2
|
||||
#define NUNITS (PCIIDE_CHANNEL_NDEV * PCIIDE_NUM_CHANNELS)
|
||||
#define WDC_NPORTS 8 /* XXX */
|
||||
#define WDC_NSHADOWREG 2 /* XXX */
|
||||
|
||||
struct wdc_channel {
|
||||
volatile u_int8_t *c_base;
|
||||
volatile u_int8_t *c_cmdbase;
|
||||
volatile u_int8_t *c_ctlbase;
|
||||
volatile u_int8_t *c_cmdreg[WDC_NPORTS + WDC_NSHADOWREG];
|
||||
volatile u_int16_t *c_data;
|
||||
|
||||
u_int8_t compatchan;
|
||||
};
|
||||
|
||||
#define WDC_READ_REG(chp, reg) *(chp)->c_cmdreg[(reg)]
|
||||
#define WDC_WRITE_REG(chp, reg, val) *(chp)->c_cmdreg[(reg)] = (val)
|
||||
#define WDC_READ_CTLREG(chp, reg) (chp)->c_ctlbase[(reg)]
|
||||
#define WDC_WRITE_CTLREG(chp, reg, val) (chp)->c_ctlbase[(reg)] = (val)
|
||||
#define WDC_READ_DATA(chp) *(chp)->c_data
|
||||
|
||||
struct wd_softc {
|
||||
#define WDF_LBA 0x0001
|
||||
#define WDF_LBA48 0x0002
|
||||
|
|
Loading…
Reference in New Issue