Browse Source

Fix bug about linux kernel dump when using IDE and add a ENABLE_SATA option

master
TAI Yunfang 15 years ago
committed by LIU Qi
parent
commit
0d25d0b986
  1. 3
      Targets/Bonito3adawning/Bonito/tgt_machdep.c
  2. 1
      Targets/Bonito3adawning/conf/Bonito.3adawning
  3. 13
      Targets/Bonito3adawning/pci/amd_780e.c
  4. 3
      Targets/Bonito3adawning/pci/sb700.c
  5. 6
      Targets/Bonito3adawning/pci/sb700_sata.c
  6. 16
      sys/dev/ata/ata.c
  7. 95
      sys/dev/ata/ata_wdc.c
  8. 180
      sys/dev/ic/wdc.c
  9. 8
      sys/dev/ic/wdcreg.h
  10. 13
      sys/dev/ic/wdcvar.h
  11. 211
      sys/dev/pci/pciide.c

3
Targets/Bonito3adawning/Bonito/tgt_machdep.c

@ -784,7 +784,6 @@ tgt_devinit()
cs5536_init();
#endif
printf("rs780_early_setup\n");
rs780_early_setup();
@ -838,7 +837,7 @@ tgt_devinit()
#endif
#if 0
#ifndef ENABLE_SATA
//SBD_DISPLAY("disable data",0);
//disable sata
printf("disable sata\n");

1
Targets/Bonito3adawning/conf/Bonito.3adawning

@ -29,6 +29,7 @@ option LS3_HT # Enable the IO cache coherent of HT
#option MCP68_IDE # Enable the MCP68 IDE 0 channel
option USE_LPC_UART
option MULTI_CHIP
option ENABLE_SATA #Enable SATA ,when enable IDE can also use, when commended only IDE can use
select amd_780e

13
Targets/Bonito3adawning/pci/amd_780e.c

@ -312,7 +312,8 @@ void sb700_devices_por_init(void)
printk_info("IO Address Enable\n");
/*pci_write_config8(dev, 0x79, 0x4F); */
pci_write_config8(dev, 0x78, 0xFF);
#if 0
//#ifndef ENABLE_SATA
#if 1
/* TODO: set ide as primary, if you want to boot from IDE, you'd better set it.Or add a configuration line.*/
printk_info("set ide as primary\n");
byte = pci_read_config8(dev, 0xAD);
@ -419,7 +420,7 @@ void sb700_devices_por_init(void)
/* Enable PCIB_DUAL_EN_UP will fix potential problem with PCI cards. */
printk_info("enable pcib_dual_en_up\n");
pci_write_config8(dev, 0x50, 0x01);
#ifdef ENABLE_SATA
/* SATA Device, BDF:0-17-0, Non-Raid-5 SATA controller */
printk_info("sb700_devices_por_init(): SATA Device, BDF:0-17-0\n");
//dev = pci_locate_device(PCI_ID(0x1002, 0x4380), 0);
@ -429,7 +430,7 @@ void sb700_devices_por_init(void)
* 0x2c00 for ASIC revision A13 and above.*/
printk_info("PHY Global Control\n");
pci_write_config16(dev, 0x86, 0x2C00);
#endif
}
static void pmio_write(u8 reg, u8 value)
{
@ -598,7 +599,7 @@ static void sb700_pci_cfg()
byte = pci_read_config8(dev, 0x78);
byte &= 0xfd;
pci_write_config8(dev, 0x78, byte);
#ifdef ENABLE_SATA
/* SATA Device, BDF:0-18-0, Non-Raid-5 SATA controller */
//dev = pci_locate_device(PCI_ID(0x1002, 0x4380), 0);
dev = _pci_make_tag(0, 17, 0);
@ -613,7 +614,7 @@ static void sb700_pci_cfg()
pci_write_config8(dev, 0x34, 0x50);
byte &= ~(1 << 0);
pci_write_config8(dev, 0x40, byte);
#endif
/* TODO: There are several pairs of USB devices.
* Two 4396s, two 4397s, two 4398s.
* The code below only set one of each two. The other
@ -999,7 +1000,7 @@ void sb700_after_pci_fixup(void){
//sb700_enable();
//internal_gfx_pci_dev_init();
//vga_bios_init();
#if 1
#ifdef ENABLE_SATA
printk_info("sata init\n");
sata_init(_pci_make_tag(0, 0x11, 0));
#endif

3
Targets/Bonito3adawning/pci/sb700.c

@ -148,10 +148,11 @@ void sb700_enable()
* 0:14.3 LPC bit 20 of sm_dev 0x64 : 0 - disable, default + 32 * 1
* 0:14.4 PCI 4
*/
#if 1
#ifdef ENABLE_SATA
printk_info("enable_sata\n");
sb700_sata(1);
#endif
printk_info("enable usb0\n");
sb700_usb(_pci_make_tag(0, 0x12, 0), 1, 0);

6
Targets/Bonito3adawning/pci/sb700_sata.c

@ -13,7 +13,7 @@
extern struct southbridge_ati_sb700_config conf_info;
#if 1
#ifndef 1
static sata_drive_detect(int portnum, u32 iobar)
{
u8 byte, byte2;
@ -200,11 +200,11 @@ static void sata_init(device_t dev)
/* Use BAR5+0x1A8,BAR0 for Primary Slave */
/* Use BAR5+0x228,BAR2 for Secondary Master */
/* Use BAR5+0x2A8,BAR2 for Secondary Slave */
#ifdef EANBLE_SATA
sata_bar5 = sata_bar5 | 0xa0000000;
sata_bar0 = sata_bar0 | 0xb8000000;
sata_bar2 = sata_bar2 | 0xb8000000;
#if 1
for (i = 0; i < 4; i++) {
byte = READB(sata_bar5 + 0x128 + 0x80 * i);
printk_spew("SATA port %d status = %x\n", i, byte);
@ -256,7 +256,7 @@ static void sata_init(device_t dev)
}
#endif
#if 1
#ifdef 1
/* Below is CIM InitSataLateFar */
/* Enable interrupts from the HBA */
printk_info("Enable interrupts from the HBA\n");

16
sys/dev/ata/ata.c

@ -42,9 +42,6 @@
#include <dev/ata/atareg.h>
#include <dev/ata/atavar.h>
#include <machine/bus.h>
#include <dev/ic/wdcvar.h>
#define DEBUG_FUNCS 0x08
#define DEBUG_PROBE 0x10
#ifdef WDCDEBUG
@ -81,8 +78,7 @@ ata_get_params(drvp, flags, prms)
wdc_c.r_command = WDCC_IDENTIFY;
wdc_c.r_st_bmask = WDCS_DRDY;
wdc_c.r_st_pmask = WDCS_DRQ;
// wdc_c.timeout = 1000; /* 1s */
wdc_c.timeout = 10000; /* 10s */
wdc_c.timeout = 1000; /* 1s */
} else if (drvp->drive_flags & DRIVE_ATAPI) {
wdc_c.r_command = ATAPI_IDENTIFY_DEVICE;
wdc_c.r_st_bmask = 0;
@ -159,10 +155,6 @@ ata_set_mode(drvp, mode, flags)
u_int8_t flags;
{
struct wdc_command wdc_c;
#if 1
struct channel_softc *chp = drvp->chnl_softc;
struct wdc_softc *wdc = chp->wdc;
#endif
WDCDEBUG_PRINT(("ata_set_mode=0x%x\n", mode), DEBUG_FUNCS);
bzero(&wdc_c, sizeof(struct wdc_command));
@ -179,12 +171,6 @@ ata_set_mode(drvp, mode, flags)
if (wdc_c.flags & (AT_ERROR | AT_TIMEOU | AT_DF)) {
return CMD_ERR;
}
#if 1
printf("begin set mode\n");
if(wdc->set_modes)
wdc->set_modes(chp);
#endif
return CMD_OK;
}

95
sys/dev/ata/ata_wdc.c

@ -68,27 +68,6 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
/************************************************************************
Copyright (C)
File name: ata_wdc.c
Author: *** Version: *** Date: ***
Description:
Others:
Function List:
Revision History:
Note:LBA48 feature added, but for the less modification of the existed
struct, in fact, it only suport LBA31(I make this words^_^),that means
the biggest capicity of Hard disk which is supported here is
1T(2^(32-1+9))Bytes.
--------------------------------------------------------------------------
Date Author Activity ID Activity Headline
2008-03-13 QianYuli PMON00000001 Add LBA48 feature supporting
*************************************************************************/
#include <sys/param.h>
#include <sys/systm.h>
@ -145,9 +124,6 @@ int wdc_ata_err __P((struct ata_drive_datas *, struct ata_bio *));
#define WDC_ATA_RECOV 0x01 /* There was a recovered error */
#define WDC_ATA_ERR 0x02 /* Drive reports an error */
extern void wdccommand_lba48(struct channel_softc *, u_int8_t, u_int8_t, u_int32_t,u_int8_t, u_int8_t, u_int8_t);
/*
* Handle block I/O operation. Return WDC_COMPLETE, WDC_QUEUED, or
* WDC_TRY_AGAIN. Must be called at splio().
@ -165,9 +141,9 @@ wdc_ata_bio(drvp, ata_bio)
return WDC_TRY_AGAIN;
if (ata_bio->flags & ATA_POLL)
xfer->c_flags |= C_POLL;
#ifndef PMON
if ((drvp->drive_flags & (DRIVE_DMA | DRIVE_UDMA)) &&
(ata_bio->flags & ATA_SINGLE) == 0)
#if !defined(PMON)||defined(IDE_DMA)
/* if ((drvp->drive_flags & (DRIVE_DMA | DRIVE_UDMA)) &&
(ata_bio->flags & ATA_SINGLE) == 0)*/
xfer->c_flags |= C_DMA;
#endif
xfer->drive = drvp->drive;
@ -186,7 +162,7 @@ wdc_ata_bio_start(chp, xfer)
struct channel_softc *chp;
struct wdc_xfer *xfer;
{
#ifndef PMON
#if !defined(PMON)||defined(IDE_DMA)
struct ata_bio *ata_bio = xfer->cmd;
WDCDEBUG_PRINT(("wdc_ata_bio_start %s:%d:%d\n",
chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive),
@ -210,10 +186,10 @@ _wdc_ata_bio_start(chp, xfer)
u_int8_t head, sect, cmd = 0;
int nblks;
int ata_delay;
#ifndef PMON
#if !defined(PMON) || defined(IDE_DMA)
int dma_flags = 0;
#endif
WDCDEBUG_PRINT(("_wdc_ata_bio_start %s:%d:%d\n",
chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive),
DEBUG_INTR | DEBUG_XFERS);
@ -247,7 +223,7 @@ _wdc_ata_bio_start(chp, xfer)
return;
}
#ifndef PMON
#if !defined(PMON) || defined(IDE_DMA)
if (xfer->c_flags & C_DMA) {
dma_flags = (ata_bio->flags & ATA_READ) ? WDC_DMA_READ : 0;
dma_flags |= (ata_bio->flags & ATA_POLL) ? WDC_DMA_POLL : 0;
@ -307,7 +283,7 @@ _wdc_ata_bio_start(chp, xfer)
cyl = blkno;
head |= WDSD_CHS;
}
#ifndef PMON
#if !defined(PMON) || defined(IDE_DMA)
if (xfer->c_flags & C_DMA) {
ata_bio->nblks = nblks;
ata_bio->nbytes = xfer->c_bcount;
@ -340,41 +316,21 @@ _wdc_ata_bio_start(chp, xfer)
#endif
ata_bio->nblks = min(nblks, ata_bio->multi);
ata_bio->nbytes = ata_bio->nblks * ata_bio->lp->d_secsize;
//03-12
if (LBA28_MAX_SECTORS > ata_bio->blkno) {
if (ata_bio->nblks > 1 && (ata_bio->flags & ATA_SINGLE) == 0) {
cmd = (ata_bio->flags & ATA_READ) ?
WDCC_READMULTI : WDCC_WRITEMULTI;
} else {
cmd = (ata_bio->flags & ATA_READ) ?
WDCC_READ : WDCC_WRITE;
}
} else {
if (ata_bio->nblks > 1 && (ata_bio->flags & ATA_SINGLE) == 0) {
cmd = (ata_bio->flags & ATA_READ) ?
WDCC_READMULTI_EXT : WDCC_WRITEMULTI_EXT;
} else {
cmd = (ata_bio->flags & ATA_READ) ?
WDCC_READ_SECTORS_EXT : WDCC_WRITE_SECTORS_EXT;
}
}
if (ata_bio->nblks > 1 && (ata_bio->flags & ATA_SINGLE) == 0) {
cmd = (ata_bio->flags & ATA_READ) ?
WDCC_READMULTI : WDCC_WRITEMULTI;
} else {
cmd = (ata_bio->flags & ATA_READ) ?
WDCC_READ : WDCC_WRITE;
}
/* Initiate command! */
CHP_WRITE_REG(chp, wdr_sdh, WDSD_IBM | (xfer->drive << 4));
if (wait_for_ready(chp, ata_delay) < 0)
goto timeout;
//03-12
if (LBA28_MAX_SECTORS > ata_bio->blkno) {
wdccommand(chp, xfer->drive, cmd, cyl,
wdccommand(chp, xfer->drive, cmd, cyl,
head, sect, nblks,
(ata_bio->lp->d_type == DTYPE_ST506) ?
ata_bio->lp->d_precompcyl / 4 : 0);
} else {
wdccommand_lba48(chp, xfer->drive, cmd, ata_bio->blkno, head,nblks, (ata_bio->lp->d_type == DTYPE_ST506) ?
ata_bio->lp->d_precompcyl / 4 : 0);
}
} else if (ata_bio->nblks > 1) {
/* The number of blocks in the last stretch may be smaller. */
nblks = xfer->c_bcount / ata_bio->lp->d_secsize;
@ -403,7 +359,7 @@ _wdc_ata_bio_start(chp, xfer)
ata_bio->nbytes);
}
#ifndef PMON
#if !defined(PMON) || defined(IDE_DMA)
intr: /* Wait for IRQ (either real or polled) */
#endif
if ((ata_bio->flags & ATA_POLL) == 0) {
@ -435,7 +391,7 @@ wdc_ata_bio_intr(chp, xfer, irq)
struct ata_bio *ata_bio = xfer->cmd;
struct ata_drive_datas *drvp = &chp->ch_drive[xfer->drive];
int drv_err;
#ifndef PMON
#if !defined(PMON) || defined(IDE_DMA)
int dma_flags = 0;
#endif
@ -452,7 +408,7 @@ wdc_ata_bio_intr(chp, xfer, irq)
panic("wdc_ata_bio_intr: bad state\n");
}
#ifndef PMON
#if !defined(PMON)||defined(IDE_DMA)
if (xfer->c_flags & C_DMA) {
dma_flags = (ata_bio->flags & ATA_READ) ? WDC_DMA_READ : 0;
dma_flags |= (ata_bio->flags & ATA_POLL) ? WDC_DMA_POLL : 0;
@ -477,7 +433,7 @@ wdc_ata_bio_intr(chp, xfer, irq)
printf("%s:%d:%d: device timeout, c_bcount=%d, c_skip%d\n",
chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive,
xfer->c_bcount, xfer->c_skip);
#ifndef PMON
#if !defined(PMON)||defined(IDE_DMA)
/* if we were using DMA, turn off DMA channel */
if (xfer->c_flags & C_DMA) {
(*chp->wdc->dma_finish)(chp->wdc->dma_arg,
@ -492,7 +448,7 @@ wdc_ata_bio_intr(chp, xfer, irq)
drv_err = wdc_ata_err(drvp, ata_bio);
#ifndef PMON
#if !defined(PMON)||defined(IDE_DMA)
/* If we were using DMA, Turn off the DMA channel and check for error */
if (xfer->c_flags & C_DMA) {
if (ata_bio->flags & ATA_POLL) {
@ -549,9 +505,10 @@ wdc_ata_bio_intr(chp, xfer, irq)
wdc_ata_bio_done(chp, xfer);
return 1;
}
wdc_input_bytes(drvp, (char *)xfer->databuf + xfer->c_skip,ata_bio->nbytes);
wdc_input_bytes(drvp, (char *)xfer->databuf + xfer->c_skip,
ata_bio->nbytes);
}
#ifndef PMON
#if !defined(PMON)||defined(IDE_DMA)
end:
#endif
ata_bio->blkno += ata_bio->nblks;
@ -582,7 +539,7 @@ wdc_ata_bio_kill_xfer(chp, xfer)
{
struct ata_bio *ata_bio = xfer->cmd;
#ifndef PMON
#if !defined(PMON)||defined(IDE_DMA)
untimeout(wdctimeout, chp);
#endif
/* remove this command from xfer queue */
@ -611,7 +568,7 @@ wdc_ata_bio_done(chp, xfer)
(u_int)xfer->c_flags),
DEBUG_XFERS);
#ifndef PMON
#if !defined(PMON)||defined(IDE_DMA)
untimeout(wdctimeout, chp);
#endif
if (ata_bio->error == NOERROR)

180
sys/dev/ic/wdc.c

@ -96,7 +96,7 @@
#include "atapiscsi.h"
#endif
#define WDCDELAY 50 /* 50 microseconds */
#define WDCDELAY 100 /* 100 microseconds */
#define WDCNDELAY_RST (WDC_RESET_WAIT * 1000 / WDCDELAY)
#if 0
/* If you enable this, it will report any delays more than WDCDELAY * N long. */
@ -105,7 +105,7 @@
LIST_HEAD(xfer_free_list, wdc_xfer) xfer_free_list;
#ifndef PMON
#if !defined(PMON)||defined(IDE_DMA)
static void __wdcerror __P((struct channel_softc*, char *));
#endif
static int __wdcwait_reset __P((struct channel_softc *, int));
@ -125,21 +125,18 @@ void wdc_kill_pending __P((struct channel_softc *));
#define DEBUG_SDRIVE 0x40
#define DEBUG_DETACH 0x80
#define WDCDEBUG
#ifdef WDCDEBUG
int wdcdebug_mask = 0;
int wdc_nxfer = 0;
#define WDCDEBUG_PRINT(args, level) if (wdcdebug_mask & (level)) printf args
#else
#define WDCDEBUG_PRINT(args, level)
#define WDCDEBUG_PRINT(args, level)
#endif
int at_poll = AT_POLL;
u_int8_t wdc_default_read_reg __P((struct channel_softc *, enum wdc_regs));
void wdc_default_write_reg __P((struct channel_softc *, enum wdc_regs, u_int8_t));
void wdc_default_read_raw_multi_1 __P((struct channel_softc *,
void *, unsigned int));
void wdc_default_read_raw_multi_2 __P((struct channel_softc *,
void *, unsigned int));
void wdc_default_write_raw_multi_2 __P((struct channel_softc *,
@ -149,7 +146,6 @@ void wdc_default_read_raw_multi_4 __P((struct channel_softc *,
void wdc_default_write_raw_multi_4 __P((struct channel_softc *,
void *, unsigned int));
struct channel_softc_vtbl wdc_default_vtbl = {
wdc_default_read_reg,
wdc_default_write_reg,
@ -193,17 +189,14 @@ wdc_default_write_reg(chp, reg, val)
#endif
if (reg & _WDC_AUX)
{
bus_space_write_1(chp->ctl_iot, chp->ctl_ioh,
reg & _WDC_REGMASK, val);
// printf("haha, ctl_ioh=%x, reg=%d\n", chp->ctl_ioh, reg & _WDC_REGMASK);
}
else
bus_space_write_1(chp->cmd_iot, chp->cmd_ioh,
reg & _WDC_REGMASK, val);
}
static int mylbuf[2048/sizeof(int)];
void
wdc_default_read_raw_multi_2(chp, data, nbytes)
struct channel_softc *chp;
@ -220,19 +213,20 @@ wdc_default_read_raw_multi_2(chp, data, nbytes)
return;
}
if (!((unsigned int)data & 1))
bus_space_read_raw_multi_2(chp->cmd_iot, chp->cmd_ioh, 0,
data, nbytes);
else {
while (nbytes >0) {
int c = nbytes > 2048 ? 2048: nbytes;
bus_space_read_raw_multi_2(chp->cmd_iot, chp->cmd_ioh, 0,
mylbuf, c);
memcpy(data, mylbuf, c);
nbytes -= c;
data += c;
}
}
if((long)data&1)
{
unsigned int i;
u_int16_t data16;
for(i=0;i<nbytes;i+=2)
{
data16=bus_space_read_2(chp->cmd_iot, chp->cmd_ioh, 0);
memcpy((char *)data+i,&data16,2);
}
}
else
bus_space_read_raw_multi_2(chp->cmd_iot, chp->cmd_ioh, 0,
data, nbytes);
return;
}
@ -253,6 +247,18 @@ wdc_default_write_raw_multi_2(chp, data, nbytes)
return;
}
if((long)data&1)
{
unsigned int i;
u_int16_t data16;
for(i=0;i<nbytes;i+=2)
{
memcpy(&data16,(char *)data+i,4);
bus_space_write_2(chp->cmd_iot, chp->cmd_ioh, 0, data16);
}
}
else
bus_space_write_raw_multi_2(chp->cmd_iot, chp->cmd_ioh, 0,
data, nbytes);
return;
@ -274,6 +280,18 @@ wdc_default_write_raw_multi_4(chp, data, nbytes)
return;
}
if((long)data&3)
{
unsigned int i;
u_int32_t data32;
for(i=0;i<nbytes;i+=4)
{
memcpy(&data32,(char *)data+i,4);
bus_space_write_4(chp->cmd_iot, chp->cmd_ioh, 0, data32);
}
}
else
bus_space_write_raw_multi_4(chp->cmd_iot, chp->cmd_ioh, 0,
data, nbytes);
@ -297,18 +315,20 @@ wdc_default_read_raw_multi_4(chp, data, nbytes)
return;
}
if ((unsigned int)data & 3) {
while (nbytes > 0) {
int c = nbytes > 2048? 2048:nbytes;
bus_space_read_raw_multi_4(chp->cmd_iot, chp->cmd_ioh, 0,
mylbuf, c);
memcpy(data, mylbuf, c);
nbytes -= c;
data += c;
}
} else
bus_space_read_raw_multi_4(chp->cmd_iot, chp->cmd_ioh, 0,
data, nbytes);
if((long)data&3)
{
unsigned int i;
u_int32_t data32;
for(i=0;i<nbytes;i+=4)
{
data32=bus_space_read_4(chp->cmd_iot, chp->cmd_ioh, 0);
memcpy((char *)data+i,&data32,4);
}
}
else
bus_space_read_raw_multi_4(chp->cmd_iot, chp->cmd_ioh, 0,
data, nbytes);
return;
}
@ -388,25 +408,9 @@ wdc_select_drive(chp, drive, howlong)
* - test ATA/ATAPI signatures. If at last one drive found -> return.
* - try an ATA command on the master.
*/
/************************************************************************
Copyright (C)
File name: wdc.c
Author: *** Version: *** Date: ***
Description:
Others:
Function List:
Revision History:
--------------------------------------------------------------------------
Date Author Activity ID Activity Headline
2008-03-13 QianYuli PMON00000001 Add wdccommand_lba48() function to support LBA48
*************************************************************************/
int
wdcprobe(chp)
wdcprobe(chp) //yh
struct channel_softc *chp;
{
u_int8_t st0, st1, sc, sn, cl, ch;
@ -440,6 +444,9 @@ wdcprobe(chp)
return 0;
}
#ifndef WDC_NORESET
if(!getenv("wdcnoreset"))
{
/* assert SRST, wait for reset to complete */
CHP_WRITE_REG(chp, wdr_sdh, WDSD_IBM);
delay(10);
@ -455,6 +462,8 @@ wdcprobe(chp)
WDCDEBUG_PRINT(("%s:%d: after reset, ret_value=0x%d\n",
chp->wdc ? chp->wdc->sc_dev.dv_xname : "wdcprobe", chp->channel,
ret_value), DEBUG_PROBE);
}
#endif
/* if reset failed, there's nothing here */
if (ret_value == 0)
@ -470,7 +479,7 @@ wdcprobe(chp)
if ((ret_value & (0x01 << drive)) == 0)
continue;
CHP_WRITE_REG(chp, wdr_sdh, WDSD_IBM | (drive << 4));
delay(10);
delay(100);
/* Save registers contents */
sc = CHP_READ_REG(chp, wdr_seccnt);
sn = CHP_READ_REG(chp, wdr_sector);
@ -690,7 +699,7 @@ wdcattach(chp)
* led on)
*/
if ((chp->wdc->cap & WDC_CAPABILITY_NO_EXTRA_RESETS) == 0) {
//wdcreset(chp, VERBOSE);
wdcreset(chp, VERBOSE);
/*
* Read status registers to avoid spurious interrupts.
*/
@ -805,7 +814,7 @@ int
wdcintr(arg)
void *arg;
{
#ifndef PMON
#if !defined(PMON)||defined(IDE_DMA)
struct channel_softc *chp = arg;
struct wdc_xfer *xfer;
int ret;
@ -886,14 +895,12 @@ __wdcwait_reset(chp, drv_mask)
{
int timeout;
u_int8_t st0, st1;
int busy_count = 0;
/* Wait 50ms for drive firmware to settle */
delay(50000);
/* wait for BSY to deassert */
for (timeout = 0; timeout < 20 /*WDCNDELAY_RST/2*/;timeout++) {
delay(3000000);
for (timeout = 0; timeout < WDCNDELAY_RST;timeout++) {
CHP_WRITE_REG(chp, wdr_sdh, WDSD_IBM); /* master */
delay(10);
st0 = CHP_READ_REG(chp, wdr_status);
@ -901,7 +908,6 @@ __wdcwait_reset(chp, drv_mask)
delay(10);
st1 = CHP_READ_REG(chp, wdr_status);
printf("st0=%x,st1=%x\n", st0, st1);
if ((drv_mask & 0x01) == 0) {
/* no master */
if ((drv_mask & 0x02) != 0 && (st1 & WDCS_BSY) == 0) {
@ -918,14 +924,7 @@ __wdcwait_reset(chp, drv_mask)
/* Wait for both master and slave to be ready */
if ((st0 & WDCS_BSY) == 0 && (st1 & WDCS_BSY) == 0) {
goto end;
} else
busy_count++;
/* FIXME For CS5536 ide, the busy bit cannot be cleared*/
if((st0 & WDCS_DWF) && (st1 & WDCS_DWF)) {
if (busy_count > 3)
goto end;
}
}
delay(WDCDELAY);
}
@ -967,6 +966,9 @@ wdcwait(chp, mask, bits, timeout)
timeout = timeout * 1000 / WDCDELAY; /* delay uses microseconds */
for (;;) {
#ifdef DEVBD2F_FIREWALL
delay(10); //atp8620 can not read too fast.
#endif
#ifdef TEST_ALTSTS
chp->ch_status = status = CHP_READ_REG(chp, wdr_altsts);
#else
@ -982,17 +984,16 @@ wdcwait(chp, mask, bits, timeout)
CHP_READ_REG(chp, wdr_status);
#endif
}
if ((status & WDCS_BSY) == 0 && (status & mask) == bits) {
if ((status & WDCS_BSY) == 0 && (status & mask) == bits)
break;
}
if (++time > timeout) {
if (++time > timeout) {
WDCDEBUG_PRINT(("wdcwait: timeout, status %x "
"error %x\n", status,
CHP_READ_REG(chp, wdr_error)),
DEBUG_STATUSX | DEBUG_STATUS);
return -1;
}
delay(WDCDELAY/10);
delay(WDCDELAY);
}
#ifdef TEST_ALTSTS
/* Acknowledge any pending interrupts */
@ -1024,7 +1025,7 @@ wdcwait(chp, mask, bits, timeout)
return 0;
}
#ifndef PMON
#if !defined(PMON)||defined(IDE_DMA)
void
wdctimeout(arg)
void *arg;
@ -1310,7 +1311,7 @@ wdc_print_caps(drvp)
} else
printf("16-bit");
printf(", PIO mode %d/%d", drvp->PIO_cap, drvp->PIO_mode);
printf(", PIO mode %d", drvp->PIO_cap);
if (drvp->drive_flags & DRIVE_DMA) {
printf(", DMA mode %d", drvp->DMA_cap);
@ -1331,7 +1332,7 @@ int
wdc_downgrade_mode(drvp)
struct ata_drive_datas *drvp;
{
#ifndef PMON
#if !defined(PMON)||defined(IDE_DMA)
struct channel_softc *chp = drvp->chnl_softc;
struct wdc_softc *wdc = chp->wdc;
int cf_flags = drvp->cf_flags;
@ -1450,6 +1451,8 @@ wdc_exec_command(drvp, wdc_c)
return ret;
}
void
__wdccommand_start(chp, xfer)
struct channel_softc *chp;
@ -1485,7 +1488,7 @@ __wdccommand_start(chp, xfer)
}
} else
DELAY(10);
wdccommand(chp, drive, wdc_c->r_command, wdc_c->r_cyl, wdc_c->r_head,
wdc_c->r_sector, wdc_c->r_count, wdc_c->r_precomp);
#ifndef PMON
@ -1595,6 +1598,7 @@ wdccommand(chp, drive, command, cylin, head, sector, count, precomp)
"sector=%d count=%d precomp=%d\n", chp->wdc->sc_dev.dv_xname,
chp->channel, drive, command, cylin, head, sector, count, precomp),
DEBUG_FUNCS);
/* Select drive, head, and addressing mode. */
CHP_WRITE_REG(chp, wdr_sdh, WDSD_IBM | (drive << 4) | head);
@ -1606,33 +1610,11 @@ wdccommand(chp, drive, command, cylin, head, sector, count, precomp)
CHP_WRITE_REG(chp, wdr_seccnt, count);
/* Send command. */
CHP_WRITE_REG(chp, wdr_command, command);
return;
}
//03-12
void
wdccommand_lba48( struct channel_softc *chp, u_int8_t drive, u_int8_t command, u_int32_t lba,u_int8_t head,u_int8_t count,u_int8_t precomp)
{
/* Select drive, head, and addressing mode. */
CHP_WRITE_REG(chp, wdr_sdh, (drive << 4) | WDSD_LBA);
/* Load parameters for LBA48 read_sector_ext command */
CHP_WRITE_REG(chp, wdr_seccnt, 0);//Sector count register first time
CHP_WRITE_REG(chp, wdr_seccnt, count);//Sector count register second time
CHP_WRITE_REG(chp, wdr_sector, (lba >> 24) & 0xff);//LBA Low register first time
CHP_WRITE_REG(chp, wdr_sector, lba & 0xff);//LBA Low register second time
CHP_WRITE_REG(chp, wdr_cyl_lo, 0);//LBA Mid register first time
CHP_WRITE_REG(chp, wdr_cyl_lo, (lba >> 8) & 0xff);//LBA Mid register second time
CHP_WRITE_REG(chp, wdr_cyl_hi, 0);//LBA Hight register first time
CHP_WRITE_REG(chp, wdr_cyl_hi, (lba >> 16) & 0xff);//LBA Hight register second time
/* Send command. */
CHP_WRITE_REG(chp, wdr_command, command);
return;
}
/*
* Simplified version of wdccommand(). Unbusy/ready/drq must be
* tested by the caller.
@ -1756,7 +1738,7 @@ wdc_kill_pending(chp)
}
}
#ifndef PMON
#if !defined(PMON)||defined(IDE_DMA)
static void
__wdcerror(chp, msg)
struct channel_softc *chp;

8
sys/dev/ic/wdcreg.h

@ -83,11 +83,6 @@
#define WDCC_READ 0x20 /* disk read code */
#define WDCC_WRITE 0x30 /* disk write code */
//03-12
#define WDCC_READ_SECTORS_EXT 0x24 /*disk read ext code(for LBA48)*/
#define WDCC_WRITE_SECTORS_EXT 0x34 /*disk write ext code(for LBA48)*/
#define WDCC__LONG 0x02 /* modifier -- access ecc bytes */
#define WDCC__NORETRY 0x01 /* modifier -- no retrys */
@ -98,9 +93,6 @@
#define WDCC_READMULTI 0xc4 /* read multiple */
#define WDCC_WRITEMULTI 0xc5 /* write multiple */
#define WDCC_SETMULTI 0xc6 /* set multiple mode */
//03-12
#define WDCC_READMULTI_EXT 0x29 /* read multiple ext (for LBA48)*/
#define WDCC_WRITEMULTI_EXT 0x39/* write multiple ext (for LBA48)*/
#define WDCC_READDMA 0xc8 /* read with DMA */
#define WDCC_WRITEDMA 0xca /* write with DMA */

13
sys/dev/ic/wdcvar.h

@ -36,8 +36,6 @@
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#ifndef WDCVAR_H
#define WDCVAR_H
#define WAITTIME (10 * hz) /* time to wait for a completion */
/* this is a lot for hard drives, but not for cdroms */
@ -250,9 +248,6 @@ void wdcbit_bucket __P((struct channel_softc *, int));
void wdccommand __P((struct channel_softc *, u_int8_t, u_int8_t, u_int16_t,
u_int8_t, u_int8_t, u_int8_t, u_int8_t));
//03-12
void wdccommand_lba48 __P( (struct channel_softc *, u_int8_t, u_int8_t, u_int32_t,u_int8_t, u_int8_t, u_int8_t));
void wdccommandshort __P((struct channel_softc *, int, int));
void wdctimeout __P((void *arg));
@ -268,11 +263,7 @@ void wdc_delref __P((struct channel_softc *));
#define wait_for_ready(chp, timeout) wdcwait((chp), WDCS_DRDY, \
WDCS_DRDY, (timeout))
/* ATA/ATAPI specs says a device can take 31s to reset */
//#define WDC_RESET_WAIT 31000
#define WDC_RESET_WAIT 2000
/*max sector counts of LBA28*/
#define LBA28_MAX_SECTORS 268435456
#define WDC_RESET_WAIT 31000
void wdc_atapibus_attach __P((struct channel_softc *));
int atapi_print __P((void *, const char *));
@ -284,5 +275,3 @@ int wdc_select_drive __P((struct channel_softc *, int, int));
void wdc_output_bytes __P((struct ata_drive_datas *drvp, void *, unsigned int));
void wdc_input_bytes __P((struct ata_drive_datas *drvp, void *, unsigned int));
#endif

211
sys/dev/pci/pciide.c

@ -76,36 +76,11 @@
*
*/
#define DEBUG_DMA 0x01
#define DEBUG_XFERS 0x02
#define DEBUG_FUNCS 0x08
#define DEBUG_PROBE 0x10
#define PCI_PRODUCT_AMD_SB710_IDE 0x439c
#define PCI_PRODUCT_AMD_SB710_SATA 0x4390
#if 1
struct pio_timing {
int command; /*command width*/
int recovery; /*recovery width*/
int ct; /*bus-cycle timing*/
};
#endif
static struct pio_timing amdsb710_pio_set[5] = {
{9, 9, 600}, /* PIO 0 */
{4, 7, 390}, /* PIO 1 */
{3, 4, 270}, /* PIO 2 */
{2, 2, 180}, /* PIO 3 */
{2, 0, 120}, /* PIO 4 */
};
/* Channel enable */
//#define amdsb710_CHANSTATUS_EN 0x4C
#define AMDSB710_PIO_TIMING 0x40
#define WDCDEBUG
#ifdef WDCDEBUG
int wdcdebug_pciide_mask = DEBUG_DMA|DEBUG_XFERS|DEBUG_FUNCS|DEBUG_PROBE;
#define WDCDEBUG_PRINT(args, level) \
@ -129,8 +104,8 @@ int wdcdebug_pciide_mask = DEBUG_DMA|DEBUG_XFERS|DEBUG_FUNCS|DEBUG_PROBE;
#include <dev/pci/pciidevar.h>
#include <dev/pci/pciide_piix_reg.h>
#include <dev/pci/pciide_amd_reg.h>
#ifndef PMON
#include <dev/pci/pciide_apollo_reg.h>
#ifndef PMON
#endif
#include <dev/pci/pciide_cmd_reg.h>
#ifndef PMON
@ -226,16 +201,10 @@ static u_int32_t piix_setup_idetim_drvs __P((struct ata_drive_datas*));
static u_int32_t piix_setup_sidetim_timings __P((u_int8_t, u_int8_t, u_int8_t));
void amd756_chip_map __P((struct pciide_softc*, struct pci_attach_args*));
void amd756_setup_channel __P((struct channel_softc*));
void amdcs5536_chip_map __P((struct pciide_softc*, struct pci_attach_args*));
void amdcs5536_setup_channel __P((struct channel_softc*));
void amdsb710_chip_map __P((struct pciide_softc*, struct pci_attach_args*));
void amdsb710_setup_channel __P((struct channel_softc*));
#ifndef PMON
void apollo_chip_map __P((struct pciide_softc*, struct pci_attach_args*));
void apollo_setup_channel __P((struct channel_softc*));
@ -266,7 +235,7 @@ void pdc20268_setup_channel __P((struct channel_softc*));
int pdc202xx_pci_intr __P((void *));
int pdc20265_pci_intr __P((void *));
#ifndef PMON
#if !defined(PMON)||defined(IDE_DMA)
void pciide_channel_dma_setup __P((struct pciide_channel *));
int pciide_dma_table_setup __P((struct pciide_softc*, int, int));
int pciide_dma_init __P((void*, int, int, void *, size_t, int));
@ -333,22 +302,6 @@ const struct pciide_product_desc pciide_amd_products[] = {
},
};
const struct pciide_product_desc pciide_ati_products[] = {
{
PCI_PRODUCT_AMD_SB710_IDE, /* AMD SB710 IDE*/
0,
amdsb710_chip_map
//default_chip_map
},
{
PCI_PRODUCT_AMD_SB710_SATA, /* AMD SB710 SATA*/
0,
default_chip_map
},
};
const struct pciide_product_desc pciide_cmd_products[] = {
{ PCI_PRODUCT_CMDTECH_640, /* CMD Technology PCI0640 */
0,
@ -444,8 +397,6 @@ const struct pciide_vendor_desc pciide_vendors[] = {
sizeof(pciide_intel_products)/sizeof(pciide_intel_products[0]) },
{ PCI_VENDOR_AMD, pciide_amd_products,
sizeof(pciide_amd_products)/sizeof(pciide_amd_products[0]) },
{ 0x1002, pciide_ati_products,
sizeof(pciide_ati_products)/sizeof(pciide_ati_products[0]) },
{ PCI_VENDOR_CMDTECH, pciide_cmd_products,
sizeof(pciide_cmd_products)/sizeof(pciide_cmd_products[0]) },
#ifndef PMON
@ -459,7 +410,7 @@ const struct pciide_vendor_desc pciide_vendors[] = {
{ PCI_VENDOR_ALI, pciide_acer_products,
sizeof(pciide_acer_products)/sizeof(pciide_acer_products[0]) },
{ PCI_VENDOR_PROMISE, pciide_promise_products,
sizeof(pciide_promise_products)/sizeof(pciide_promise_products[0]) },
sizeof(pciide_promise_products)/sizeof(pciide_promise_products[0]) }
};
#define PCIIDE_CHANNEL_NAME(chan) ((chan) == 0 ? "ch 0" : "ch 1")
@ -541,23 +492,7 @@ pciide_match(parent, match, aux)
{
struct pci_attach_args *pa = aux;
const struct pciide_product_desc *pp;
int bus, device, function;
_pci_break_tag(pa->pa_tag, &bus, &device, &function);
/* liujl for test.... */
{
int vid, did;
vid = _pci_conf_read(pa->pa_tag, 0);
did = (vid & 0xffff0000) >> 16;
vid = vid & 0x0000ffff;
if( (vid == 0x1002) && (did == 0x4380) ){
printf("sorry, reserved SATA to QYL.\n");
return 0;
}
}
/*
* Check the ID register to see that it's a PCI IDE controller.
* If it is, we assume that we can deal with it; it _should_
@ -580,7 +515,6 @@ pciide_match(parent, match, aux)
return (0);
}
#include <sys/dev/pci/pcireg.h>
void
pciide_attach(parent, self, aux)
struct device *parent, *self;
@ -593,6 +527,7 @@ pciide_attach(parent, self, aux)
pcitag_t tag = pa->pa_tag;
struct pciide_softc *sc = (struct pciide_softc *)self;
pcireg_t csr;
pcireg_t tmpreg;
char devinfo[256];
sc->sc_pp = pciide_lookup_product(pa->pa_id);
@ -610,6 +545,14 @@ pciide_attach(parent, self, aux)
printf("sc_pc %x, sc_tag %x\n", sc->sc_pc, sc->sc_tag);
#endif
#ifdef MCP68_IDE
/* Enable IDE controller of MCP68 */
tmpreg = pci_conf_read(pc, tag, 0x50);
pci_conf_write(pc, tag, 0x50, tmpreg | 0x02);
tmpreg = pci_conf_read(pc, tag, 0x50);
printf("\nMCP68 IDE enable : 0x50 : %8x\n",tmpreg);
#endif
sc->sc_pp->chip_map(sc, pa);
if (sc->sc_dma_ok) {
@ -619,7 +562,7 @@ pciide_attach(parent, self, aux)
}
WDCDEBUG_PRINT(("pciide: command/status register=%x\n",
pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG)), DEBUG_PROBE);
pci_conf_read(pc, tag, PCI_COMMAND_STATUS_REG)), DEBUG_PROBE);
}
/* tell wether the chip is enabled or not */
@ -746,7 +689,7 @@ pciide_mapreg_dma(sc, pa)
struct pciide_softc *sc;
struct pci_attach_args *pa;
{
#ifndef PMON
#if !defined(PMON)||defined(IDE_DMA)
/*
* Map DMA registers
*
@ -767,7 +710,7 @@ pciide_mapreg_dma(sc, pa)
sc->sc_dma_ok = (pci_mapreg_map(pa,
PCIIDE_REG_BUS_MASTER_DMA, PCI_MAPREG_TYPE_IO, 0,
&sc->sc_dma_iot, &sc->sc_dma_ioh, NULL, NULL) == 0);
&sc->sc_dma_iot, &sc->sc_dma_ioh, NULL, NULL,0) == 0);
sc->sc_dmat = pa->pa_dmat;
if (sc->sc_dma_ok == 0) {
printf(", (unuseable)"); /* couldn't map registers */
@ -828,7 +771,7 @@ pciide_pci_intr(arg)
return (rv);
}
#ifndef PMON
#if !defined(PMON)||defined(IDE_DMA)
void
pciide_channel_dma_setup(cp)
struct pciide_channel *cp;
@ -953,8 +896,7 @@ pciide_dma_init(v, channel, drive, databuf, datalen, flags)
channel, drive, error);
return error;
}
#ifndef __OpenBSD__
#if !defined(__OpenBSD__)||defined(IDE_DMA)
bus_dmamap_sync(sc->sc_dmat, dma_maps->dmamap_xfer,
0,
dma_maps->dmamap_xfer->dm_mapsize,
@ -965,7 +907,6 @@ pciide_dma_init(v, channel, drive, databuf, datalen, flags)
(flags & WDC_DMA_READ) ?
BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
#endif
for (seg = 0; seg < dma_maps->dmamap_xfer->dm_nsegs; seg++) {
#ifdef DIAGNOSTIC
/* A segment must not cross a 64k boundary */
@ -994,7 +935,7 @@ pciide_dma_init(v, channel, drive, databuf, datalen, flags)
dma_maps->dma_table[dma_maps->dmamap_xfer->dm_nsegs -1].byte_count |=
htopci(IDEDMA_BYTE_COUNT_EOT);
#ifndef __OpenBSD__
#if !defined(__OpenBSD__) || defined(IDE_DMA)
bus_dmamap_sync(sc->sc_dmat, dma_maps->dmamap_table,
0,
dma_maps->dmamap_table->dm_mapsize,
@ -1024,10 +965,10 @@ pciide_dma_init(v, channel, drive, databuf, datalen, flags)
bus_space_read_1(sc->sc_dma_iot, sc->sc_dma_ioh,
(IDEDMA_CTL-1) + IDEDMA_SCH_OFFSET * channel));
/* Write table addr */
printf("dma table start at 0x%08x\n", dma_maps->dmamap_table->dm_segs[0].ds_addr);
//printf("dma table start at 0x%08x\n", dma_maps->dmamap_table->dm_segs[0].ds_addr);
bus_space_write_4(sc->sc_dma_iot, sc->sc_dma_ioh,
IDEDMA_TBL + IDEDMA_SCH_OFFSET * channel,
dma_maps->dmamap_table->dm_segs[0].ds_addr | 0x80000000); /* XXX */
dma_maps->dmamap_table->dm_segs[0].ds_addr/* | 0x80000000*/); /* XXX */
/* set read/write */
bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,
IDEDMA_CMD + IDEDMA_SCH_OFFSET * channel,
@ -1061,7 +1002,7 @@ pciide_dma_finish(v, channel, drive, flags)
&sc->pciide_channels[channel].dma_maps[drive];
/* Unload the map of the data buffer */
#ifndef __OpenBSD__
#if !defined(__OpenBSD__)||defined(IDE_DMA)
bus_dmamap_sync(sc->sc_dmat, dma_maps->dmamap_xfer,
0,
dma_maps->dmamap_xfer->dm_mapsize,
@ -1188,13 +1129,14 @@ pciiide_chan_candisable(cp)
* generic code to map the compat intr if hw_ok=1 and it is a compat channel.
* Set hw_ok=0 on failure
*/
#define pciide_machdep_compat_intr_establish(a, b, c, d, e) tgt_poll_register((c), (d), (e))
void
pciide_map_compat_intr(pa, cp, compatchan, interface)
struct pci_attach_args *pa;
struct pciide_channel *cp;
int compatchan, interface;
{
#ifndef PMON
#if !defined(PMON)||defined(IDE_DMA)
struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc;
struct channel_softc *wdc_cp = &cp->wdc_channel;
@ -1265,14 +1207,11 @@ default_chip_map(sc, pa)
struct pci_attach_args *pa;
{
struct pciide_channel *cp;
/* setting the virtual class interface */
pcireg_t interface = PCI_INTERFACE(pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_CLASS_REG));
//pcireg_t interface = 0x00;
pcireg_t interface = PCI_INTERFACE(pci_conf_read(sc->sc_pc,
sc->sc_tag, PCI_CLASS_REG));
pcireg_t csr;
int channel;
#ifndef PMON
#if !defined(PMON)||defined(IDE_DMA)
int drive;
struct ata_drive_datas *drvp;
u_int8_t idedma_ctl;
@ -1285,12 +1224,15 @@ default_chip_map(sc, pa)
if (interface & PCIIDE_INTERFACE_BUS_MASTER_DMA) {
printf(": DMA");
#ifndef IDE_DMA
if (sc->sc_pp == &default_product_desc &&
(sc->sc_wdcdev.sc_dev.dv_cfdata->cf_flags &
PCIIDE_OPTIONS_DMA) == 0) {
printf(" (unsupported)");
sc->sc_dma_ok = 0;
} else {
} else
#endif
{
pciide_mapreg_dma(sc, pa);
if (sc->sc_dma_ok != 0)
printf(", (partial support)");
@ -1326,12 +1268,9 @@ default_chip_map(sc, pa)
* Check to see if something appears to be there.
*/
failreason = NULL;
printf("wdc : entering probe.\n");
if (!wdcprobe(&cp->wdc_channel)) {
failreason = "not responding; disabled or no drives?";
goto next;
}else{
printf("%s:%s wdcprobeok\n",sc->sc_wdcdev.sc_dev.dv_xname,cp->name);
}
/*
* Now, make sure it's actually attributable to this PCI IDE
@ -1344,13 +1283,13 @@ default_chip_map(sc, pa)
PCI_COMMAND_STATUS_REG);
pci_conf_write(sc->sc_pc, sc->sc_tag, PCI_COMMAND_STATUS_REG,
csr & ~PCI_COMMAND_IO_ENABLE);
#if 0 /* shoud be fixed in gxemul */
if (wdcprobe(&cp->wdc_channel))
failreason = "other hardware responding at addresses";
#ifdef FOR_GXEMUL
failreason=0;
#endif
pci_conf_write(sc->sc_pc, sc->sc_tag,
PCI_COMMAND_STATUS_REG, csr);
next:
if (failreason) {
printf("%s: %s ignored (%s)\n",
@ -1371,7 +1310,7 @@ next:
}
}
#ifndef PMON
#if !defined(PMON)||defined(IDE_DMA)
if (sc->sc_dma_ok == 0)
return;
@ -2057,88 +1996,6 @@ pio: /* setup PIO mode */
pci_conf_write(sc->sc_pc, sc->sc_tag, AMD756_UDMA, udmatim_reg);
}
void
amdsb710_chip_map (sc, pa)
struct pciide_softc *sc;
struct pci_attach_args *pa;
{
struct pciide_channel *cp;
pcireg_t interface = 0x00;
int channel;
pcireg_t chanenable0;
pcireg_t chanenable1;
bus_size_t cmdsize, ctlsize;
printf("enter amdsb710_chip_map\n");
if (pciide_chipen(sc, pa) == 0)
{
printf("pciide chip unenable\n");
return;
}
printf(": DMA");
pciide_mapreg_dma(sc, pa);
if (sc->sc_dma_ok)
sc->sc_wdcdev.cap |= WDC_CAPABILITY_DMA | WDC_CAPABILITY_UDMA;
sc->sc_wdcdev.cap |= WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32 | WDC_CAPABILITY_MODE;
sc->sc_wdcdev.PIO_cap = 4;
sc->sc_wdcdev.DMA_cap = 0;//2; /*FIXME yinnn */
sc->sc_wdcdev.UDMA_cap = 0;//6;
sc->sc_wdcdev.set_modes = amdsb710_setup_channel;
sc->sc_wdcdev.channels = sc->wdc_chanarray;
sc->sc_wdcdev.nchannels = PCIIDE_NUM_CHANNELS;
//sc->sc_wdcdev.nchannels = 1;
sc->sc_wdcdev.cap |= WDC_CAPABILITY_DATA16;
pciide_print_channels(sc->sc_wdcdev.nchannels, interface);
for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++)
{
cp = &sc->pciide_channels[channel];
if (pciide_chansetup(sc, channel, interface) == 0)
continue;
printf("current channel=%d,max channels=%d\n",channel,sc->sc_wdcdev.nchannels);
/* Really initialization work begin here */
pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize,
pciide_pci_intr);
pciide_map_compat_intr(pa, cp, channel, interface);
if (cp->hw_ok == 0)
continue;
amdsb710_setup_channel(&cp->wdc_channel);
}
printf("exit amdsb710_chip_map\n");
return;
}
void amdsb710_setup_channel(chp)
struct channel_softc* chp;
{
u_int32_t recovery_reg, command_reg;
int mode, drive;
struct ata_drive_datas *drvp;
struct pciide_channel *cp = (struct pciide_channel*)chp;
struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc;
printf("enter amdsb710_setup_channel\n");
for (drive = 0; drive < 1; drive++) {
printf("drive%d:\n",drive);
drvp = &chp->ch_drive[drive];
drvp->PIO_mode &= 0x7;
if(drvp->PIO_mode >4)
drvp->PIO_mode = 4;
mode = drvp->PIO_mode;
printf("PIO_mode=%d\n",mode);
}
pciide_print_modes(cp);
printf("exit amdsb710_setup_channel\n");
}
#ifndef PMON
void
apollo_chip_map(sc, pa)

Loading…
Cancel
Save