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(); cs5536_init();
#endif #endif
printf("rs780_early_setup\n"); printf("rs780_early_setup\n");
rs780_early_setup(); rs780_early_setup();
@ -838,7 +837,7 @@ tgt_devinit()
#endif #endif
#if 0 #ifndef ENABLE_SATA
//SBD_DISPLAY("disable data",0); //SBD_DISPLAY("disable data",0);
//disable sata //disable sata
printf("disable sata\n"); 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 MCP68_IDE # Enable the MCP68 IDE 0 channel
option USE_LPC_UART option USE_LPC_UART
option MULTI_CHIP option MULTI_CHIP
option ENABLE_SATA #Enable SATA ,when enable IDE can also use, when commended only IDE can use
select amd_780e 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"); printk_info("IO Address Enable\n");
/*pci_write_config8(dev, 0x79, 0x4F); */ /*pci_write_config8(dev, 0x79, 0x4F); */
pci_write_config8(dev, 0x78, 0xFF); 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.*/ /* 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"); printk_info("set ide as primary\n");
byte = pci_read_config8(dev, 0xAD); 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. */ /* Enable PCIB_DUAL_EN_UP will fix potential problem with PCI cards. */
printk_info("enable pcib_dual_en_up\n"); printk_info("enable pcib_dual_en_up\n");
pci_write_config8(dev, 0x50, 0x01); pci_write_config8(dev, 0x50, 0x01);
#ifdef ENABLE_SATA
/* SATA Device, BDF:0-17-0, Non-Raid-5 SATA controller */ /* SATA Device, BDF:0-17-0, Non-Raid-5 SATA controller */
printk_info("sb700_devices_por_init(): SATA Device, BDF:0-17-0\n"); printk_info("sb700_devices_por_init(): SATA Device, BDF:0-17-0\n");
//dev = pci_locate_device(PCI_ID(0x1002, 0x4380), 0); //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.*/ * 0x2c00 for ASIC revision A13 and above.*/
printk_info("PHY Global Control\n"); printk_info("PHY Global Control\n");
pci_write_config16(dev, 0x86, 0x2C00); pci_write_config16(dev, 0x86, 0x2C00);
#endif
} }
static void pmio_write(u8 reg, u8 value) static void pmio_write(u8 reg, u8 value)
{ {
@ -598,7 +599,7 @@ static void sb700_pci_cfg()
byte = pci_read_config8(dev, 0x78); byte = pci_read_config8(dev, 0x78);
byte &= 0xfd; byte &= 0xfd;
pci_write_config8(dev, 0x78, byte); pci_write_config8(dev, 0x78, byte);
#ifdef ENABLE_SATA
/* SATA Device, BDF:0-18-0, Non-Raid-5 SATA controller */ /* SATA Device, BDF:0-18-0, Non-Raid-5 SATA controller */
//dev = pci_locate_device(PCI_ID(0x1002, 0x4380), 0); //dev = pci_locate_device(PCI_ID(0x1002, 0x4380), 0);
dev = _pci_make_tag(0, 17, 0); dev = _pci_make_tag(0, 17, 0);
@ -613,7 +614,7 @@ static void sb700_pci_cfg()
pci_write_config8(dev, 0x34, 0x50); pci_write_config8(dev, 0x34, 0x50);
byte &= ~(1 << 0); byte &= ~(1 << 0);
pci_write_config8(dev, 0x40, byte); pci_write_config8(dev, 0x40, byte);
#endif
/* TODO: There are several pairs of USB devices. /* TODO: There are several pairs of USB devices.
* Two 4396s, two 4397s, two 4398s. * Two 4396s, two 4397s, two 4398s.
* The code below only set one of each two. The other * The code below only set one of each two. The other
@ -999,7 +1000,7 @@ void sb700_after_pci_fixup(void){
//sb700_enable(); //sb700_enable();
//internal_gfx_pci_dev_init(); //internal_gfx_pci_dev_init();
//vga_bios_init(); //vga_bios_init();
#if 1 #ifdef ENABLE_SATA
printk_info("sata init\n"); printk_info("sata init\n");
sata_init(_pci_make_tag(0, 0x11, 0)); sata_init(_pci_make_tag(0, 0x11, 0));
#endif #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.3 LPC bit 20 of sm_dev 0x64 : 0 - disable, default + 32 * 1
* 0:14.4 PCI 4 * 0:14.4 PCI 4
*/ */
#if 1 #ifdef ENABLE_SATA
printk_info("enable_sata\n"); printk_info("enable_sata\n");
sb700_sata(1); sb700_sata(1);
#endif #endif
printk_info("enable usb0\n"); printk_info("enable usb0\n");
sb700_usb(_pci_make_tag(0, 0x12, 0), 1, 0); 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; extern struct southbridge_ati_sb700_config conf_info;
#if 1 #ifndef 1
static sata_drive_detect(int portnum, u32 iobar) static sata_drive_detect(int portnum, u32 iobar)
{ {
u8 byte, byte2; u8 byte, byte2;
@ -200,11 +200,11 @@ static void sata_init(device_t dev)
/* Use BAR5+0x1A8,BAR0 for Primary Slave */ /* Use BAR5+0x1A8,BAR0 for Primary Slave */
/* Use BAR5+0x228,BAR2 for Secondary Master */ /* Use BAR5+0x228,BAR2 for Secondary Master */
/* Use BAR5+0x2A8,BAR2 for Secondary Slave */ /* Use BAR5+0x2A8,BAR2 for Secondary Slave */
#ifdef EANBLE_SATA
sata_bar5 = sata_bar5 | 0xa0000000; sata_bar5 = sata_bar5 | 0xa0000000;
sata_bar0 = sata_bar0 | 0xb8000000; sata_bar0 = sata_bar0 | 0xb8000000;
sata_bar2 = sata_bar2 | 0xb8000000; sata_bar2 = sata_bar2 | 0xb8000000;
#if 1
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
byte = READB(sata_bar5 + 0x128 + 0x80 * i); byte = READB(sata_bar5 + 0x128 + 0x80 * i);
printk_spew("SATA port %d status = %x\n", i, byte); printk_spew("SATA port %d status = %x\n", i, byte);
@ -256,7 +256,7 @@ static void sata_init(device_t dev)
} }
#endif #endif
#if 1 #ifdef 1
/* Below is CIM InitSataLateFar */ /* Below is CIM InitSataLateFar */
/* Enable interrupts from the HBA */ /* Enable interrupts from the HBA */
printk_info("Enable interrupts from the HBA\n"); 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/atareg.h>
#include <dev/ata/atavar.h> #include <dev/ata/atavar.h>
#include <machine/bus.h>
#include <dev/ic/wdcvar.h>
#define DEBUG_FUNCS 0x08 #define DEBUG_FUNCS 0x08
#define DEBUG_PROBE 0x10 #define DEBUG_PROBE 0x10
#ifdef WDCDEBUG #ifdef WDCDEBUG
@ -81,8 +78,7 @@ ata_get_params(drvp, flags, prms)
wdc_c.r_command = WDCC_IDENTIFY; wdc_c.r_command = WDCC_IDENTIFY;
wdc_c.r_st_bmask = WDCS_DRDY; wdc_c.r_st_bmask = WDCS_DRDY;
wdc_c.r_st_pmask = WDCS_DRQ; wdc_c.r_st_pmask = WDCS_DRQ;
// wdc_c.timeout = 1000; /* 1s */ wdc_c.timeout = 1000; /* 1s */
wdc_c.timeout = 10000; /* 10s */
} else if (drvp->drive_flags & DRIVE_ATAPI) { } else if (drvp->drive_flags & DRIVE_ATAPI) {
wdc_c.r_command = ATAPI_IDENTIFY_DEVICE; wdc_c.r_command = ATAPI_IDENTIFY_DEVICE;
wdc_c.r_st_bmask = 0; wdc_c.r_st_bmask = 0;
@ -159,10 +155,6 @@ ata_set_mode(drvp, mode, flags)
u_int8_t flags; u_int8_t flags;
{ {
struct wdc_command wdc_c; 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); WDCDEBUG_PRINT(("ata_set_mode=0x%x\n", mode), DEBUG_FUNCS);
bzero(&wdc_c, sizeof(struct wdc_command)); 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)) { if (wdc_c.flags & (AT_ERROR | AT_TIMEOU | AT_DF)) {
return CMD_ERR; return CMD_ERR;
} }
#if 1
printf("begin set mode\n");
if(wdc->set_modes)
wdc->set_modes(chp);
#endif
return CMD_OK; 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 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE. * 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/param.h>
#include <sys/systm.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_RECOV 0x01 /* There was a recovered error */
#define WDC_ATA_ERR 0x02 /* Drive reports an 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 * Handle block I/O operation. Return WDC_COMPLETE, WDC_QUEUED, or
* WDC_TRY_AGAIN. Must be called at splio(). * WDC_TRY_AGAIN. Must be called at splio().
@ -165,9 +141,9 @@ wdc_ata_bio(drvp, ata_bio)
return WDC_TRY_AGAIN; return WDC_TRY_AGAIN;
if (ata_bio->flags & ATA_POLL) if (ata_bio->flags & ATA_POLL)
xfer->c_flags |= C_POLL; xfer->c_flags |= C_POLL;
#ifndef PMON #if !defined(PMON)||defined(IDE_DMA)
if ((drvp->drive_flags & (DRIVE_DMA | DRIVE_UDMA)) && /* if ((drvp->drive_flags & (DRIVE_DMA | DRIVE_UDMA)) &&
(ata_bio->flags & ATA_SINGLE) == 0) (ata_bio->flags & ATA_SINGLE) == 0)*/
xfer->c_flags |= C_DMA; xfer->c_flags |= C_DMA;
#endif #endif
xfer->drive = drvp->drive; xfer->drive = drvp->drive;
@ -186,7 +162,7 @@ wdc_ata_bio_start(chp, xfer)
struct channel_softc *chp; struct channel_softc *chp;
struct wdc_xfer *xfer; struct wdc_xfer *xfer;
{ {
#ifndef PMON #if !defined(PMON)||defined(IDE_DMA)
struct ata_bio *ata_bio = xfer->cmd; struct ata_bio *ata_bio = xfer->cmd;
WDCDEBUG_PRINT(("wdc_ata_bio_start %s:%d:%d\n", WDCDEBUG_PRINT(("wdc_ata_bio_start %s:%d:%d\n",
chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive), 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; u_int8_t head, sect, cmd = 0;
int nblks; int nblks;
int ata_delay; int ata_delay;
#ifndef PMON #if !defined(PMON) || defined(IDE_DMA)
int dma_flags = 0; int dma_flags = 0;
#endif #endif
WDCDEBUG_PRINT(("_wdc_ata_bio_start %s:%d:%d\n", WDCDEBUG_PRINT(("_wdc_ata_bio_start %s:%d:%d\n",
chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive), chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive),
DEBUG_INTR | DEBUG_XFERS); DEBUG_INTR | DEBUG_XFERS);
@ -247,7 +223,7 @@ _wdc_ata_bio_start(chp, xfer)
return; return;
} }
#ifndef PMON #if !defined(PMON) || defined(IDE_DMA)
if (xfer->c_flags & C_DMA) { if (xfer->c_flags & C_DMA) {
dma_flags = (ata_bio->flags & ATA_READ) ? WDC_DMA_READ : 0; dma_flags = (ata_bio->flags & ATA_READ) ? WDC_DMA_READ : 0;
dma_flags |= (ata_bio->flags & ATA_POLL) ? WDC_DMA_POLL : 0; dma_flags |= (ata_bio->flags & ATA_POLL) ? WDC_DMA_POLL : 0;
@ -307,7 +283,7 @@ _wdc_ata_bio_start(chp, xfer)
cyl = blkno; cyl = blkno;
head |= WDSD_CHS; head |= WDSD_CHS;
} }
#ifndef PMON #if !defined(PMON) || defined(IDE_DMA)
if (xfer->c_flags & C_DMA) { if (xfer->c_flags & C_DMA) {
ata_bio->nblks = nblks; ata_bio->nblks = nblks;
ata_bio->nbytes = xfer->c_bcount; ata_bio->nbytes = xfer->c_bcount;
@ -340,41 +316,21 @@ _wdc_ata_bio_start(chp, xfer)
#endif #endif
ata_bio->nblks = min(nblks, ata_bio->multi); ata_bio->nblks = min(nblks, ata_bio->multi);
ata_bio->nbytes = ata_bio->nblks * ata_bio->lp->d_secsize; ata_bio->nbytes = ata_bio->nblks * ata_bio->lp->d_secsize;
if (ata_bio->nblks > 1 && (ata_bio->flags & ATA_SINGLE) == 0) {
//03-12 cmd = (ata_bio->flags & ATA_READ) ?
if (LBA28_MAX_SECTORS > ata_bio->blkno) { WDCC_READMULTI : WDCC_WRITEMULTI;
if (ata_bio->nblks > 1 && (ata_bio->flags & ATA_SINGLE) == 0) { } else {
cmd = (ata_bio->flags & ATA_READ) ? cmd = (ata_bio->flags & ATA_READ) ?
WDCC_READMULTI : WDCC_WRITEMULTI; WDCC_READ : WDCC_WRITE;
} 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;
}
}
/* Initiate command! */ /* Initiate command! */
CHP_WRITE_REG(chp, wdr_sdh, WDSD_IBM | (xfer->drive << 4)); CHP_WRITE_REG(chp, wdr_sdh, WDSD_IBM | (xfer->drive << 4));
if (wait_for_ready(chp, ata_delay) < 0) if (wait_for_ready(chp, ata_delay) < 0)
goto timeout; goto timeout;
//03-12 wdccommand(chp, xfer->drive, cmd, cyl,
if (LBA28_MAX_SECTORS > ata_bio->blkno) {
wdccommand(chp, xfer->drive, cmd, cyl,
head, sect, nblks, head, sect, nblks,
(ata_bio->lp->d_type == DTYPE_ST506) ? (ata_bio->lp->d_type == DTYPE_ST506) ?
ata_bio->lp->d_precompcyl / 4 : 0); 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) { } else if (ata_bio->nblks > 1) {
/* The number of blocks in the last stretch may be smaller. */ /* The number of blocks in the last stretch may be smaller. */
nblks = xfer->c_bcount / ata_bio->lp->d_secsize; nblks = xfer->c_bcount / ata_bio->lp->d_secsize;
@ -403,7 +359,7 @@ _wdc_ata_bio_start(chp, xfer)
ata_bio->nbytes); ata_bio->nbytes);
} }
#ifndef PMON #if !defined(PMON) || defined(IDE_DMA)
intr: /* Wait for IRQ (either real or polled) */ intr: /* Wait for IRQ (either real or polled) */
#endif #endif
if ((ata_bio->flags & ATA_POLL) == 0) { 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_bio *ata_bio = xfer->cmd;
struct ata_drive_datas *drvp = &chp->ch_drive[xfer->drive]; struct ata_drive_datas *drvp = &chp->ch_drive[xfer->drive];
int drv_err; int drv_err;
#ifndef PMON #if !defined(PMON) || defined(IDE_DMA)
int dma_flags = 0; int dma_flags = 0;
#endif #endif
@ -452,7 +408,7 @@ wdc_ata_bio_intr(chp, xfer, irq)
panic("wdc_ata_bio_intr: bad state\n"); panic("wdc_ata_bio_intr: bad state\n");
} }
#ifndef PMON #if !defined(PMON)||defined(IDE_DMA)
if (xfer->c_flags & C_DMA) { if (xfer->c_flags & C_DMA) {
dma_flags = (ata_bio->flags & ATA_READ) ? WDC_DMA_READ : 0; dma_flags = (ata_bio->flags & ATA_READ) ? WDC_DMA_READ : 0;
dma_flags |= (ata_bio->flags & ATA_POLL) ? WDC_DMA_POLL : 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", printf("%s:%d:%d: device timeout, c_bcount=%d, c_skip%d\n",
chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive, chp->wdc->sc_dev.dv_xname, chp->channel, xfer->drive,
xfer->c_bcount, xfer->c_skip); xfer->c_bcount, xfer->c_skip);
#ifndef PMON #if !defined(PMON)||defined(IDE_DMA)
/* if we were using DMA, turn off DMA channel */ /* if we were using DMA, turn off DMA channel */
if (xfer->c_flags & C_DMA) { if (xfer->c_flags & C_DMA) {
(*chp->wdc->dma_finish)(chp->wdc->dma_arg, (*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); 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 we were using DMA, Turn off the DMA channel and check for error */
if (xfer->c_flags & C_DMA) { if (xfer->c_flags & C_DMA) {
if (ata_bio->flags & ATA_POLL) { if (ata_bio->flags & ATA_POLL) {
@ -549,9 +505,10 @@ wdc_ata_bio_intr(chp, xfer, irq)
wdc_ata_bio_done(chp, xfer); wdc_ata_bio_done(chp, xfer);
return 1; 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: end:
#endif #endif
ata_bio->blkno += ata_bio->nblks; ata_bio->blkno += ata_bio->nblks;
@ -582,7 +539,7 @@ wdc_ata_bio_kill_xfer(chp, xfer)
{ {
struct ata_bio *ata_bio = xfer->cmd; struct ata_bio *ata_bio = xfer->cmd;
#ifndef PMON #if !defined(PMON)||defined(IDE_DMA)
untimeout(wdctimeout, chp); untimeout(wdctimeout, chp);
#endif #endif
/* remove this command from xfer queue */ /* remove this command from xfer queue */
@ -611,7 +568,7 @@ wdc_ata_bio_done(chp, xfer)
(u_int)xfer->c_flags), (u_int)xfer->c_flags),
DEBUG_XFERS); DEBUG_XFERS);
#ifndef PMON #if !defined(PMON)||defined(IDE_DMA)
untimeout(wdctimeout, chp); untimeout(wdctimeout, chp);
#endif #endif
if (ata_bio->error == NOERROR) if (ata_bio->error == NOERROR)

180
sys/dev/ic/wdc.c

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

8
sys/dev/ic/wdcreg.h

@ -83,11 +83,6 @@
#define WDCC_READ 0x20 /* disk read code */ #define WDCC_READ 0x20 /* disk read code */
#define WDCC_WRITE 0x30 /* disk write 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__LONG 0x02 /* modifier -- access ecc bytes */
#define WDCC__NORETRY 0x01 /* modifier -- no retrys */ #define WDCC__NORETRY 0x01 /* modifier -- no retrys */
@ -98,9 +93,6 @@
#define WDCC_READMULTI 0xc4 /* read multiple */ #define WDCC_READMULTI 0xc4 /* read multiple */
#define WDCC_WRITEMULTI 0xc5 /* write multiple */ #define WDCC_WRITEMULTI 0xc5 /* write multiple */
#define WDCC_SETMULTI 0xc6 /* set multiple mode */ #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_READDMA 0xc8 /* read with DMA */
#define WDCC_WRITEDMA 0xca /* write 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 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE. * POSSIBILITY OF SUCH DAMAGE.
*/ */
#ifndef WDCVAR_H
#define WDCVAR_H
#define WAITTIME (10 * hz) /* time to wait for a completion */ #define WAITTIME (10 * hz) /* time to wait for a completion */
/* this is a lot for hard drives, but not for cdroms */ /* 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, 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)); 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 wdccommandshort __P((struct channel_softc *, int, int));
void wdctimeout __P((void *arg)); 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, \ #define wait_for_ready(chp, timeout) wdcwait((chp), WDCS_DRDY, \
WDCS_DRDY, (timeout)) WDCS_DRDY, (timeout))
/* ATA/ATAPI specs says a device can take 31s to reset */ /* ATA/ATAPI specs says a device can take 31s to reset */
//#define WDC_RESET_WAIT 31000 #define WDC_RESET_WAIT 31000
#define WDC_RESET_WAIT 2000
/*max sector counts of LBA28*/
#define LBA28_MAX_SECTORS 268435456
void wdc_atapibus_attach __P((struct channel_softc *)); void wdc_atapibus_attach __P((struct channel_softc *));
int atapi_print __P((void *, const char *)); 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_output_bytes __P((struct ata_drive_datas *drvp, void *, unsigned int));
void wdc_input_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_DMA 0x01
#define DEBUG_XFERS 0x02 #define DEBUG_XFERS 0x02
#define DEBUG_FUNCS 0x08 #define DEBUG_FUNCS 0x08
#define DEBUG_PROBE 0x10 #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 #ifdef WDCDEBUG
int wdcdebug_pciide_mask = DEBUG_DMA|DEBUG_XFERS|DEBUG_FUNCS|DEBUG_PROBE; int wdcdebug_pciide_mask = DEBUG_DMA|DEBUG_XFERS|DEBUG_FUNCS|DEBUG_PROBE;
#define WDCDEBUG_PRINT(args, level) \ #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/pciidevar.h>
#include <dev/pci/pciide_piix_reg.h> #include <dev/pci/pciide_piix_reg.h>
#include <dev/pci/pciide_amd_reg.h> #include <dev/pci/pciide_amd_reg.h>
#ifndef PMON
#include <dev/pci/pciide_apollo_reg.h> #include <dev/pci/pciide_apollo_reg.h>
#ifndef PMON
#endif #endif
#include <dev/pci/pciide_cmd_reg.h> #include <dev/pci/pciide_cmd_reg.h>
#ifndef PMON #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)); 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_chip_map __P((struct pciide_softc*, struct pci_attach_args*));
void amd756_setup_channel __P((struct channel_softc*)); void amd756_setup_channel __P((struct channel_softc*));
void amdcs5536_chip_map __P((struct pciide_softc*, struct pci_attach_args*)); void amdcs5536_chip_map __P((struct pciide_softc*, struct pci_attach_args*));
void amdcs5536_setup_channel __P((struct channel_softc*)); 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 #ifndef PMON
void apollo_chip_map __P((struct pciide_softc*, struct pci_attach_args*)); void apollo_chip_map __P((struct pciide_softc*, struct pci_attach_args*));
void apollo_setup_channel __P((struct channel_softc*)); 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 pdc202xx_pci_intr __P((void *));
int pdc20265_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 *)); void pciide_channel_dma_setup __P((struct pciide_channel *));
int pciide_dma_table_setup __P((struct pciide_softc*, int, int)); int pciide_dma_table_setup __P((struct pciide_softc*, int, int));
int pciide_dma_init __P((void*, int, int, void *, size_t, 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[] = { const struct pciide_product_desc pciide_cmd_products[] = {
{ PCI_PRODUCT_CMDTECH_640, /* CMD Technology PCI0640 */ { PCI_PRODUCT_CMDTECH_640, /* CMD Technology PCI0640 */
0, 0,
@ -444,8 +397,6 @@ const struct pciide_vendor_desc pciide_vendors[] = {
sizeof(pciide_intel_products)/sizeof(pciide_intel_products[0]) }, sizeof(pciide_intel_products)/sizeof(pciide_intel_products[0]) },
{ PCI_VENDOR_AMD, pciide_amd_products, { PCI_VENDOR_AMD, pciide_amd_products,
sizeof(pciide_amd_products)/sizeof(pciide_amd_products[0]) }, 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, { PCI_VENDOR_CMDTECH, pciide_cmd_products,
sizeof(pciide_cmd_products)/sizeof(pciide_cmd_products[0]) }, sizeof(pciide_cmd_products)/sizeof(pciide_cmd_products[0]) },
#ifndef PMON #ifndef PMON
@ -459,7 +410,7 @@ const struct pciide_vendor_desc pciide_vendors[] = {
{ PCI_VENDOR_ALI, pciide_acer_products, { PCI_VENDOR_ALI, pciide_acer_products,
sizeof(pciide_acer_products)/sizeof(pciide_acer_products[0]) }, sizeof(pciide_acer_products)/sizeof(pciide_acer_products[0]) },
{ PCI_VENDOR_PROMISE, pciide_promise_products, { 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") #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; struct pci_attach_args *pa = aux;
const struct pciide_product_desc *pp; 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. * 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_ * If it is, we assume that we can deal with it; it _should_
@ -580,7 +515,6 @@ pciide_match(parent, match, aux)
return (0); return (0);
} }
#include <sys/dev/pci/pcireg.h>
void void
pciide_attach(parent, self, aux) pciide_attach(parent, self, aux)
struct device *parent, *self; struct device *parent, *self;
@ -593,6 +527,7 @@ pciide_attach(parent, self, aux)
pcitag_t tag = pa->pa_tag; pcitag_t tag = pa->pa_tag;
struct pciide_softc *sc = (struct pciide_softc *)self; struct pciide_softc *sc = (struct pciide_softc *)self;
pcireg_t csr; pcireg_t csr;
pcireg_t tmpreg;
char devinfo[256]; char devinfo[256];
sc->sc_pp = pciide_lookup_product(pa->pa_id); 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); printf("sc_pc %x, sc_tag %x\n", sc->sc_pc, sc->sc_tag);
#endif #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); sc->sc_pp->chip_map(sc, pa);
if (sc->sc_dma_ok) { if (sc->sc_dma_ok) {
@ -619,7 +562,7 @@ pciide_attach(parent, self, aux)
} }
WDCDEBUG_PRINT(("pciide: command/status register=%x\n", 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 */ /* tell wether the chip is enabled or not */
@ -746,7 +689,7 @@ pciide_mapreg_dma(sc, pa)
struct pciide_softc *sc; struct pciide_softc *sc;
struct pci_attach_args *pa; struct pci_attach_args *pa;
{ {
#ifndef PMON #if !defined(PMON)||defined(IDE_DMA)
/* /*
* Map DMA registers * Map DMA registers
* *
@ -767,7 +710,7 @@ pciide_mapreg_dma(sc, pa)
sc->sc_dma_ok = (pci_mapreg_map(pa, sc->sc_dma_ok = (pci_mapreg_map(pa,
PCIIDE_REG_BUS_MASTER_DMA, PCI_MAPREG_TYPE_IO, 0, 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; sc->sc_dmat = pa->pa_dmat;
if (sc->sc_dma_ok == 0) { if (sc->sc_dma_ok == 0) {
printf(", (unuseable)"); /* couldn't map registers */ printf(", (unuseable)"); /* couldn't map registers */
@ -828,7 +771,7 @@ pciide_pci_intr(arg)
return (rv); return (rv);
} }
#ifndef PMON #if !defined(PMON)||defined(IDE_DMA)
void void
pciide_channel_dma_setup(cp) pciide_channel_dma_setup(cp)
struct pciide_channel *cp; struct pciide_channel *cp;
@ -953,8 +896,7 @@ pciide_dma_init(v, channel, drive, databuf, datalen, flags)
channel, drive, error); channel, drive, error);
return error; return error;
} }
#if !defined(__OpenBSD__)||defined(IDE_DMA)
#ifndef __OpenBSD__
bus_dmamap_sync(sc->sc_dmat, dma_maps->dmamap_xfer, bus_dmamap_sync(sc->sc_dmat, dma_maps->dmamap_xfer,
0, 0,
dma_maps->dmamap_xfer->dm_mapsize, dma_maps->dmamap_xfer->dm_mapsize,
@ -965,7 +907,6 @@ pciide_dma_init(v, channel, drive, databuf, datalen, flags)
(flags & WDC_DMA_READ) ? (flags & WDC_DMA_READ) ?
BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE); BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
#endif #endif
for (seg = 0; seg < dma_maps->dmamap_xfer->dm_nsegs; seg++) { for (seg = 0; seg < dma_maps->dmamap_xfer->dm_nsegs; seg++) {
#ifdef DIAGNOSTIC #ifdef DIAGNOSTIC
/* A segment must not cross a 64k boundary */ /* 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 |= dma_maps->dma_table[dma_maps->dmamap_xfer->dm_nsegs -1].byte_count |=
htopci(IDEDMA_BYTE_COUNT_EOT); htopci(IDEDMA_BYTE_COUNT_EOT);
#ifndef __OpenBSD__ #if !defined(__OpenBSD__) || defined(IDE_DMA)
bus_dmamap_sync(sc->sc_dmat, dma_maps->dmamap_table, bus_dmamap_sync(sc->sc_dmat, dma_maps->dmamap_table,
0, 0,
dma_maps->dmamap_table->dm_mapsize, 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, bus_space_read_1(sc->sc_dma_iot, sc->sc_dma_ioh,
(IDEDMA_CTL-1) + IDEDMA_SCH_OFFSET * channel)); (IDEDMA_CTL-1) + IDEDMA_SCH_OFFSET * channel));
/* Write table addr */ /* 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, bus_space_write_4(sc->sc_dma_iot, sc->sc_dma_ioh,
IDEDMA_TBL + IDEDMA_SCH_OFFSET * channel, 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 */ /* set read/write */
bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh, bus_space_write_1(sc->sc_dma_iot, sc->sc_dma_ioh,
IDEDMA_CMD + IDEDMA_SCH_OFFSET * channel, IDEDMA_CMD + IDEDMA_SCH_OFFSET * channel,
@ -1061,7 +1002,7 @@ pciide_dma_finish(v, channel, drive, flags)
&sc->pciide_channels[channel].dma_maps[drive]; &sc->pciide_channels[channel].dma_maps[drive];
/* Unload the map of the data buffer */ /* 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, bus_dmamap_sync(sc->sc_dmat, dma_maps->dmamap_xfer,
0, 0,
dma_maps->dmamap_xfer->dm_mapsize, 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. * generic code to map the compat intr if hw_ok=1 and it is a compat channel.
* Set hw_ok=0 on failure * Set hw_ok=0 on failure
*/ */
#define pciide_machdep_compat_intr_establish(a, b, c, d, e) tgt_poll_register((c), (d), (e))
void void
pciide_map_compat_intr(pa, cp, compatchan, interface) pciide_map_compat_intr(pa, cp, compatchan, interface)
struct pci_attach_args *pa; struct pci_attach_args *pa;
struct pciide_channel *cp; struct pciide_channel *cp;
int compatchan, interface; int compatchan, interface;
{ {
#ifndef PMON #if !defined(PMON)||defined(IDE_DMA)
struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc; struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc;
struct channel_softc *wdc_cp = &cp->wdc_channel; struct channel_softc *wdc_cp = &cp->wdc_channel;
@ -1265,14 +1207,11 @@ default_chip_map(sc, pa)
struct pci_attach_args *pa; struct pci_attach_args *pa;
{ {
struct pciide_channel *cp; struct pciide_channel *cp;
pcireg_t interface = PCI_INTERFACE(pci_conf_read(sc->sc_pc,
/* setting the virtual class interface */ sc->sc_tag, PCI_CLASS_REG));
pcireg_t interface = PCI_INTERFACE(pci_conf_read(sc->sc_pc, sc->sc_tag, PCI_CLASS_REG));
//pcireg_t interface = 0x00;
pcireg_t csr; pcireg_t csr;
int channel; int channel;
#ifndef PMON #if !defined(PMON)||defined(IDE_DMA)
int drive; int drive;
struct ata_drive_datas *drvp; struct ata_drive_datas *drvp;
u_int8_t idedma_ctl; u_int8_t idedma_ctl;
@ -1285,12 +1224,15 @@ default_chip_map(sc, pa)
if (interface & PCIIDE_INTERFACE_BUS_MASTER_DMA) { if (interface & PCIIDE_INTERFACE_BUS_MASTER_DMA) {
printf(": DMA"); printf(": DMA");
#ifndef IDE_DMA
if (sc->sc_pp == &default_product_desc && if (sc->sc_pp == &default_product_desc &&
(sc->sc_wdcdev.sc_dev.dv_cfdata->cf_flags & (sc->sc_wdcdev.sc_dev.dv_cfdata->cf_flags &
PCIIDE_OPTIONS_DMA) == 0) { PCIIDE_OPTIONS_DMA) == 0) {
printf(" (unsupported)"); printf(" (unsupported)");
sc->sc_dma_ok = 0; sc->sc_dma_ok = 0;
} else { } else
#endif
{
pciide_mapreg_dma(sc, pa); pciide_mapreg_dma(sc, pa);
if (sc->sc_dma_ok != 0) if (sc->sc_dma_ok != 0)
printf(", (partial support)"); printf(", (partial support)");
@ -1326,12 +1268,9 @@ default_chip_map(sc, pa)
* Check to see if something appears to be there. * Check to see if something appears to be there.
*/ */
failreason = NULL; failreason = NULL;
printf("wdc : entering probe.\n");
if (!wdcprobe(&cp->wdc_channel)) { if (!wdcprobe(&cp->wdc_channel)) {
failreason = "not responding; disabled or no drives?"; failreason = "not responding; disabled or no drives?";
goto next; 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 * 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_COMMAND_STATUS_REG);
pci_conf_write(sc->sc_pc, sc->sc_tag, PCI_COMMAND_STATUS_REG, pci_conf_write(sc->sc_pc, sc->sc_tag, PCI_COMMAND_STATUS_REG,
csr & ~PCI_COMMAND_IO_ENABLE); csr & ~PCI_COMMAND_IO_ENABLE);
#if 0 /* shoud be fixed in gxemul */
if (wdcprobe(&cp->wdc_channel)) if (wdcprobe(&cp->wdc_channel))
failreason = "other hardware responding at addresses"; failreason = "other hardware responding at addresses";
#ifdef FOR_GXEMUL
failreason=0;
#endif #endif
pci_conf_write(sc->sc_pc, sc->sc_tag, pci_conf_write(sc->sc_pc, sc->sc_tag,
PCI_COMMAND_STATUS_REG, csr); PCI_COMMAND_STATUS_REG, csr);
next: next:
if (failreason) { if (failreason) {
printf("%s: %s ignored (%s)\n", 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) if (sc->sc_dma_ok == 0)
return; return;
@ -2057,88 +1996,6 @@ pio: /* setup PIO mode */
pci_conf_write(sc->sc_pc, sc->sc_tag, AMD756_UDMA, udmatim_reg); 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 #ifndef PMON
void void
apollo_chip_map(sc, pa) apollo_chip_map(sc, pa)

Loading…
Cancel
Save