Browse Source

Merge files from Lemote and Dawning to make SATA and IDE work

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

2
Targets/Bonito3adawning/Bonito/tgt_machdep.c

@ -838,7 +838,7 @@ tgt_devinit()
#endif
#if 1
#if 0
//SBD_DISPLAY("disable data",0);
//disable sata
printf("disable sata\n");

15
Targets/Bonito3adawning/pci/amd_780e.c

@ -312,15 +312,16 @@ 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
/* 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);
byte |= 1 << 4;
pci_write_config8(dev, 0xAD, byte);
/* This register is not used on sb700. It came from older chipset. */
/*pci_write_config8(dev, 0x95, 0xFF); */
#endif
/* Set smbus iospace enable, I don't know why write 0x04 into reg5 that is reserved */
printk_info("Set smbus iospace enable\n");
@ -419,10 +420,10 @@ void sb700_devices_por_init(void)
printk_info("enable pcib_dual_en_up\n");
pci_write_config8(dev, 0x50, 0x01);
/* SATA Device, BDF:0-18-0, Non-Raid-5 SATA controller */
printk_info("sb700_devices_por_init(): SATA Device, BDF:0-18-0\n");
/* 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);
dev = _pci_make_tag(0, 18, 0);
dev = _pci_make_tag(0, 17, 0);
/*PHY Global Control, we are using A14.
* default: 0x2c40 for ASIC revision A12 and below
* 0x2c00 for ASIC revision A13 and above.*/
@ -600,7 +601,7 @@ static void sb700_pci_cfg()
/* 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, 18, 0);
dev = _pci_make_tag(0, 17, 0);
/* rpr7.12 SATA MSI and D3 Power State Capability.
* TODO: We assume S1 is supported. What if it isn't support? */
byte = pci_read_config8(dev, 0x40);
@ -998,7 +999,7 @@ void sb700_after_pci_fixup(void){
//sb700_enable();
//internal_gfx_pci_dev_init();
//vga_bios_init();
#if 0
#if 1
printk_info("sata init\n");
sata_init(_pci_make_tag(0, 0x11, 0));
#endif

2
Targets/Bonito3adawning/pci/sb700.c

@ -148,7 +148,7 @@ void sb700_enable()
* 0:14.3 LPC bit 20 of sm_dev 0x64 : 0 - disable, default + 32 * 1
* 0:14.4 PCI 4
*/
#if 0
#if 1
printk_info("enable_sata\n");
sb700_sata(1);
#endif

94
Targets/Bonito3adawning/pci/sb700_sata.c

@ -1,15 +1,54 @@
#include "sb700.h"
#include "rs780_cmn.h"
#if 0
#define writeb(val, addr) (*(volatile u8*)(addr) = (val))
#define writew(val, addr) (*(volatile u16*)(addr) = (val))
#define writel(val, addr) (*(volatile u32*)(addr) = (val))
#define readb(addr) (*(volatile u8*)(addr))
#define readw(addr) (*(volatile u16*)(addr))
#define readl(addr) (*(volatile u32*)(addr))
#endif
extern struct southbridge_ati_sb700_config conf_info;
#if 1
static sata_drive_detect(int portnum, u32 iobar)
{
u8 byte, byte2;
int i = 0;
OUTB(0xA0 + 0x10 * (portnum % 2), iobar + 0x6);
while (byte = INB(iobar + 0x6), byte2 = INB(iobar + 0x7),
(byte != (0xA0 + 0x10 * (portnum % 2))) ||
((byte2 & 0x88) != 0)) {
printk_spew("0x6=%x, 0x7=%x\n", byte, byte2);
if (byte != (0xA0 + 0x10 * (portnum % 2))) {
/* This will happen at the first iteration of this loop
* if the first SATA port is unpopulated and the
* second SATA port is poulated.
*/
printk_debug("drive no longer selected after %d ms, "
"retrying init\n", i * 10);
return 1;
} else
printk_spew("drive detection not yet completed, "
"waiting...\n");
udelay(10000);
i++;
}
printk_spew("drive detection done after %d ms\n", i * 10);
return 0;
}
#endif
static void sata_init(device_t dev)
{
u8 byte;
u16 word;
u32 dword;
u8 *sata_bar5;
u16 sata_bar0, sata_bar1, sata_bar2, sata_bar3, sata_bar4;
u32 sata_bar5;
u32 sata_bar0, sata_bar1, sata_bar2, sata_bar3, sata_bar4;
int i, j;
u8 rev_id;
@ -25,7 +64,7 @@ static void sata_init(device_t dev)
printk_info("Disable SATA SMBUS\n");
byte = pci_read_config8(sm_dev, 0xad);
byte |= (1 << 1);
pci_write_config8(sm_dev, 0xad, byte);
//pci_write_config8(sm_dev, 0xad, byte); //coreboot didn't do write action
/* Enable SATA and power saving */
printk_info("Enable SATA and power saving\n");
@ -45,7 +84,7 @@ static void sata_init(device_t dev)
/* get base addresss */
printk_info("get base address\n");
sata_bar5 = (u8 *) (pci_read_config32(dev, 0x24) & ~0x3FF);
sata_bar5 = (pci_read_config32(dev, 0x24) & ~0x3FF);
sata_bar0 = pci_read_config16(dev, 0x10) & ~0x7;
sata_bar1 = pci_read_config16(dev, 0x14) & ~0x7;
sata_bar2 = pci_read_config16(dev, 0x18) & ~0x7;
@ -57,7 +96,7 @@ static void sata_init(device_t dev)
printk_spew("sata_bar2=%x\n", sata_bar2); /* 3040 */
printk_spew("sata_bar3=%x\n", sata_bar3); /* 3080 */
printk_spew("sata_bar4=%x\n", sata_bar4); /* 3000 */
printk_spew("sata_bar5=%p\n", sata_bar5); /* e0309000 */
printk_spew("sata_bar5=%x\n", sata_bar5); /* e0309000 */
//add for sb700
/* disable combined mode to */
@ -90,7 +129,8 @@ static void sata_init(device_t dev)
byte |= (1 << 4);
pci_write_config8(dev, 0x40, byte);
dword = 0x01018f00;
dword = 0x01018f00; //bit[8]:1, Native PCI-mode, 0, Compability mode; bit[10]:1, Native PCI-mode, 0, Compability mode
//dword = 0x01018a00;
pci_write_config32(dev, 0x8, dword);
byte = pci_read_config8(dev, 0x40);
@ -160,10 +200,14 @@ 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 */
#if 0
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 %i status = %x\n", i, byte);
byte = READB(sata_bar5 + 0x128 + 0x80 * i);
printk_spew("SATA port %d status = %x\n", i, byte);
byte &= 0xF;
if( byte == 0x1 ) {
@ -172,25 +216,25 @@ static void sata_init(device_t dev)
printk_spew("SATA device detected but not talking. Trying lower speed.\n");
/* Read in Port-N Serial ATA Control Register */
byte = readb(sata_bar5 + 0x12C + 0x80 * i);
byte = READB(sata_bar5 + 0x12C + 0x80 * i);
/* Set Reset Bit and 1.5g bit */
byte |= 0x11;
writeb(byte, (sata_bar5 + 0x12C + 0x80 * i));
WRITEB(byte, (sata_bar5 + 0x12C + 0x80 * i));
/* Wait 1ms */
delay(1 * 1000);
/* Clear Reset Bit */
byte &= ~0x01;
writeb(byte, (sata_bar5 + 0x12C + 0x80 * i));
WRITEB(byte, (sata_bar5 + 0x12C + 0x80 * i));
/* Wait 1ms */
delay(1 * 1000);
/* Reread status */
byte = readb(sata_bar5 + 0x128 + 0x80 * i);
printk_spew("SATA port %i status = %x\n", i, byte);
byte = READB(sata_bar5 + 0x128 + 0x80 * i);
printk_spew("SATA port %d status = %x\n", i, byte);
byte &= 0xF;
}
@ -199,34 +243,34 @@ static void sata_init(device_t dev)
if (!sata_drive_detect(i, ((i / 2) == 0) ? sata_bar0 : sata_bar2))
break;
}
printk_debug("%s %s device is %sready after %i tries\n",
printk_debug("%s %s device is %sready after %d tries\n",
(i / 2) ? "Secondary" : "Primary",
(i % 2 ) ? "Slave" : "Master",
(j == 10) ? "not " : "",
(j == 10) ? j : j + 1);
} else {
printk_debug("No %s %s SATA drive on Slot%i\n",
printk_debug("No %s %s SATA drive on Slot%d\n",
(i / 2) ? "Secondary" : "Primary",
(i % 2 ) ? "Slave" : "Master", i);
}
}
#endif
#if 0
#if 1
/* Below is CIM InitSataLateFar */
/* Enable interrupts from the HBA */
printk_info("Enable interrupts from the HBA\n");
byte = readb(sata_bar5 + 0x4);
byte = READB(sata_bar5 + 0x4);
byte |= 1 << 1;
writeb(byte, (sata_bar5 + 0x4));
WRITEB(byte, (sata_bar5 + 0x4));
/* Clear error status */
printk_info("Clear error status\n");
writel(0xFFFFFFFF, (sata_bar5 + 0x130));
writel(0xFFFFFFFF, (sata_bar5 + 0x1b0));
writel(0xFFFFFFFF, (sata_bar5 + 0x230));
writel(0xFFFFFFFF, (sata_bar5 + 0x2b0));
writel(0xFFFFFFFF, (sata_bar5 + 0x330));
writel(0xFFFFFFFF, (sata_bar5 + 0x3b0));
WRITEL(0xFFFFFFFF, (sata_bar5 + 0x130));
WRITEL(0xFFFFFFFF, (sata_bar5 + 0x1b0));
WRITEL(0xFFFFFFFF, (sata_bar5 + 0x230));
WRITEL(0xFFFFFFFF, (sata_bar5 + 0x2b0));
WRITEL(0xFFFFFFFF, (sata_bar5 + 0x330));
WRITEL(0xFFFFFFFF, (sata_bar5 + 0x3b0));
#endif
/* Clear SATA status,Firstly we get the AcpiGpe0BlkAddr */

16
sys/dev/ata/ata.c

@ -42,6 +42,9 @@
#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
@ -78,7 +81,8 @@ 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 = 1000; /* 1s */
wdc_c.timeout = 10000; /* 10s */
} else if (drvp->drive_flags & DRIVE_ATAPI) {
wdc_c.r_command = ATAPI_IDENTIFY_DEVICE;
wdc_c.r_st_bmask = 0;
@ -155,6 +159,10 @@ 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));
@ -171,6 +179,12 @@ 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,6 +68,27 @@
* 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>
@ -124,6 +145,9 @@ 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().
@ -141,9 +165,9 @@ wdc_ata_bio(drvp, ata_bio)
return WDC_TRY_AGAIN;
if (ata_bio->flags & ATA_POLL)
xfer->c_flags |= C_POLL;
#if !defined(PMON)||defined(IDE_DMA)
/* if ((drvp->drive_flags & (DRIVE_DMA | DRIVE_UDMA)) &&
(ata_bio->flags & ATA_SINGLE) == 0)*/
#ifndef PMON
if ((drvp->drive_flags & (DRIVE_DMA | DRIVE_UDMA)) &&
(ata_bio->flags & ATA_SINGLE) == 0)
xfer->c_flags |= C_DMA;
#endif
xfer->drive = drvp->drive;
@ -162,7 +186,7 @@ wdc_ata_bio_start(chp, xfer)
struct channel_softc *chp;
struct wdc_xfer *xfer;
{
#if !defined(PMON)||defined(IDE_DMA)
#ifndef PMON
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),
@ -186,10 +210,10 @@ _wdc_ata_bio_start(chp, xfer)
u_int8_t head, sect, cmd = 0;
int nblks;
int ata_delay;
#if !defined(PMON) || defined(IDE_DMA)
#ifndef PMON
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);
@ -223,7 +247,7 @@ _wdc_ata_bio_start(chp, xfer)
return;
}
#if !defined(PMON) || defined(IDE_DMA)
#ifndef PMON
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;
@ -283,7 +307,7 @@ _wdc_ata_bio_start(chp, xfer)
cyl = blkno;
head |= WDSD_CHS;
}
#if !defined(PMON) || defined(IDE_DMA)
#ifndef PMON
if (xfer->c_flags & C_DMA) {
ata_bio->nblks = nblks;
ata_bio->nbytes = xfer->c_bcount;
@ -316,21 +340,41 @@ _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;
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;
}
//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;
}
}
/* Initiate command! */
CHP_WRITE_REG(chp, wdr_sdh, WDSD_IBM | (xfer->drive << 4));
if (wait_for_ready(chp, ata_delay) < 0)
goto timeout;
wdccommand(chp, xfer->drive, cmd, cyl,
//03-12
if (LBA28_MAX_SECTORS > ata_bio->blkno) {
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;
@ -359,7 +403,7 @@ _wdc_ata_bio_start(chp, xfer)
ata_bio->nbytes);
}
#if !defined(PMON) || defined(IDE_DMA)
#ifndef PMON
intr: /* Wait for IRQ (either real or polled) */
#endif
if ((ata_bio->flags & ATA_POLL) == 0) {
@ -391,7 +435,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;
#if !defined(PMON) || defined(IDE_DMA)
#ifndef PMON
int dma_flags = 0;
#endif
@ -408,7 +452,7 @@ wdc_ata_bio_intr(chp, xfer, irq)
panic("wdc_ata_bio_intr: bad state\n");
}
#if !defined(PMON)||defined(IDE_DMA)
#ifndef PMON
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;
@ -433,7 +477,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);
#if !defined(PMON)||defined(IDE_DMA)
#ifndef PMON
/* if we were using DMA, turn off DMA channel */
if (xfer->c_flags & C_DMA) {
(*chp->wdc->dma_finish)(chp->wdc->dma_arg,
@ -448,7 +492,7 @@ wdc_ata_bio_intr(chp, xfer, irq)
drv_err = wdc_ata_err(drvp, ata_bio);
#if !defined(PMON)||defined(IDE_DMA)
#ifndef PMON
/* 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) {
@ -505,10 +549,9 @@ 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);
}
#if !defined(PMON)||defined(IDE_DMA)
#ifndef PMON
end:
#endif
ata_bio->blkno += ata_bio->nblks;
@ -539,7 +582,7 @@ wdc_ata_bio_kill_xfer(chp, xfer)
{
struct ata_bio *ata_bio = xfer->cmd;
#if !defined(PMON)||defined(IDE_DMA)
#ifndef PMON
untimeout(wdctimeout, chp);
#endif
/* remove this command from xfer queue */
@ -568,7 +611,7 @@ wdc_ata_bio_done(chp, xfer)
(u_int)xfer->c_flags),
DEBUG_XFERS);
#if !defined(PMON)||defined(IDE_DMA)
#ifndef PMON
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 100 /* 100 microseconds */
#define WDCDELAY 50 /* 50 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;
#if !defined(PMON)||defined(IDE_DMA)
#ifndef PMON
static void __wdcerror __P((struct channel_softc*, char *));
#endif
static int __wdcwait_reset __P((struct channel_softc *, int));
@ -125,18 +125,21 @@ 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 *,
@ -146,6 +149,7 @@ 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,
@ -189,14 +193,17 @@ 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;
@ -213,20 +220,19 @@ wdc_default_read_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)
{
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);
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;
}
}
return;
}
@ -247,18 +253,6 @@ 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;
@ -280,18 +274,6 @@ 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);
@ -315,20 +297,18 @@ wdc_default_read_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)
{
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);
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);
return;
}
@ -408,9 +388,25 @@ 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) //yh
wdcprobe(chp)
struct channel_softc *chp;
{
u_int8_t st0, st1, sc, sn, cl, ch;
@ -444,9 +440,6 @@ wdcprobe(chp) //yh
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);
@ -462,8 +455,6 @@ if(!getenv("wdcnoreset"))
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)
@ -479,7 +470,7 @@ if(!getenv("wdcnoreset"))
if ((ret_value & (0x01 << drive)) == 0)
continue;
CHP_WRITE_REG(chp, wdr_sdh, WDSD_IBM | (drive << 4));
delay(100);
delay(10);
/* Save registers contents */
sc = CHP_READ_REG(chp, wdr_seccnt);
sn = CHP_READ_REG(chp, wdr_sector);
@ -699,7 +690,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.
*/
@ -814,7 +805,7 @@ int
wdcintr(arg)
void *arg;
{
#if !defined(PMON)||defined(IDE_DMA)
#ifndef PMON
struct channel_softc *chp = arg;
struct wdc_xfer *xfer;
int ret;
@ -895,12 +886,14 @@ __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 < WDCNDELAY_RST;timeout++) {
for (timeout = 0; timeout < 20 /*WDCNDELAY_RST/2*/;timeout++) {
delay(3000000);
CHP_WRITE_REG(chp, wdr_sdh, WDSD_IBM); /* master */
delay(10);
st0 = CHP_READ_REG(chp, wdr_status);
@ -908,6 +901,7 @@ __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) {
@ -924,7 +918,14 @@ __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);
}
@ -966,9 +967,6 @@ 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
@ -984,16 +982,17 @@ 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);
delay(WDCDELAY/10);
}
#ifdef TEST_ALTSTS
/* Acknowledge any pending interrupts */
@ -1025,7 +1024,7 @@ wdcwait(chp, mask, bits, timeout)
return 0;
}
#if !defined(PMON)||defined(IDE_DMA)
#ifndef PMON
void
wdctimeout(arg)
void *arg;
@ -1311,7 +1310,7 @@ wdc_print_caps(drvp)
} else
printf("16-bit");
printf(", PIO mode %d", drvp->PIO_cap);
printf(", PIO mode %d/%d", drvp->PIO_cap, drvp->PIO_mode);
if (drvp->drive_flags & DRIVE_DMA) {
printf(", DMA mode %d", drvp->DMA_cap);
@ -1332,7 +1331,7 @@ int
wdc_downgrade_mode(drvp)
struct ata_drive_datas *drvp;
{
#if !defined(PMON)||defined(IDE_DMA)
#ifndef PMON
struct channel_softc *chp = drvp->chnl_softc;
struct wdc_softc *wdc = chp->wdc;
int cf_flags = drvp->cf_flags;
@ -1451,8 +1450,6 @@ wdc_exec_command(drvp, wdc_c)
return ret;
}
void
__wdccommand_start(chp, xfer)
struct channel_softc *chp;
@ -1488,7 +1485,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
@ -1598,7 +1595,6 @@ 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);
@ -1610,11 +1606,33 @@ 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.
@ -1738,7 +1756,7 @@ wdc_kill_pending(chp)
}
}
#if !defined(PMON)||defined(IDE_DMA)
#ifndef PMON
static void
__wdcerror(chp, msg)
struct channel_softc *chp;

8
sys/dev/ic/wdcreg.h

@ -83,6 +83,11 @@
#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 */
@ -93,6 +98,9 @@
#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,6 +36,8 @@
* 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 */
@ -248,6 +250,9 @@ 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));
@ -263,7 +268,11 @@ 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 31000
#define WDC_RESET_WAIT 2000
/*max sector counts of LBA28*/
#define LBA28_MAX_SECTORS 268435456
void wdc_atapibus_attach __P((struct channel_softc *));
int atapi_print __P((void *, const char *));
@ -275,3 +284,5 @@ 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,11 +76,36 @@
*
*/
#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) \
@ -104,8 +129,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>
#include <dev/pci/pciide_apollo_reg.h>
#ifndef PMON
#include <dev/pci/pciide_apollo_reg.h>
#endif
#include <dev/pci/pciide_cmd_reg.h>
#ifndef PMON
@ -201,10 +226,16 @@ 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*));
@ -235,7 +266,7 @@ void pdc20268_setup_channel __P((struct channel_softc*));
int pdc202xx_pci_intr __P((void *));
int pdc20265_pci_intr __P((void *));
#if !defined(PMON)||defined(IDE_DMA)
#ifndef PMON
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));
@ -302,6 +333,22 @@ 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,
@ -397,6 +444,8 @@ 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
@ -410,7 +459,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")
@ -492,7 +541,23 @@ 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_
@ -515,6 +580,7 @@ pciide_match(parent, match, aux)
return (0);
}
#include <sys/dev/pci/pcireg.h>
void
pciide_attach(parent, self, aux)
struct device *parent, *self;
@ -527,7 +593,6 @@ 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);
@ -545,14 +610,6 @@ 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) {
@ -562,7 +619,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 */
@ -689,7 +746,7 @@ pciide_mapreg_dma(sc, pa)
struct pciide_softc *sc;
struct pci_attach_args *pa;
{
#if !defined(PMON)||defined(IDE_DMA)
#ifndef PMON
/*
* Map DMA registers
*
@ -710,7 +767,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) == 0);
&sc->sc_dma_iot, &sc->sc_dma_ioh, NULL, NULL) == 0);
sc->sc_dmat = pa->pa_dmat;
if (sc->sc_dma_ok == 0) {
printf(", (unuseable)"); /* couldn't map registers */
@ -771,7 +828,7 @@ pciide_pci_intr(arg)
return (rv);
}
#if !defined(PMON)||defined(IDE_DMA)
#ifndef PMON
void
pciide_channel_dma_setup(cp)
struct pciide_channel *cp;
@ -896,7 +953,8 @@ pciide_dma_init(v, channel, drive, databuf, datalen, flags)
channel, drive, error);
return error;
}
#if !defined(__OpenBSD__)||defined(IDE_DMA)
#ifndef __OpenBSD__
bus_dmamap_sync(sc->sc_dmat, dma_maps->dmamap_xfer,
0,
dma_maps->dmamap_xfer->dm_mapsize,
@ -907,6 +965,7 @@ 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 */
@ -935,7 +994,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);
#if !defined(__OpenBSD__) || defined(IDE_DMA)
#ifndef __OpenBSD__
bus_dmamap_sync(sc->sc_dmat, dma_maps->dmamap_table,
0,
dma_maps->dmamap_table->dm_mapsize,
@ -965,10 +1024,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,
@ -1002,7 +1061,7 @@ pciide_dma_finish(v, channel, drive, flags)
&sc->pciide_channels[channel].dma_maps[drive];
/* Unload the map of the data buffer */
#if !defined(__OpenBSD__)||defined(IDE_DMA)
#ifndef __OpenBSD__
bus_dmamap_sync(sc->sc_dmat, dma_maps->dmamap_xfer,
0,
dma_maps->dmamap_xfer->dm_mapsize,
@ -1129,14 +1188,13 @@ 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;
{
#if !defined(PMON)||defined(IDE_DMA)
#ifndef PMON
struct pciide_softc *sc = (struct pciide_softc *)cp->wdc_channel.wdc;
struct channel_softc *wdc_cp = &cp->wdc_channel;
@ -1207,11 +1265,14 @@ default_chip_map(sc, pa)
struct pci_attach_args *pa;
{
struct pciide_channel *cp;
pcireg_t interface = PCI_INTERFACE(pci_conf_read(sc->sc_pc,
sc->sc_tag, PCI_CLASS_REG));
/* 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 csr;
int channel;
#if !defined(PMON)||defined(IDE_DMA)
#ifndef PMON
int drive;
struct ata_drive_datas *drvp;
u_int8_t idedma_ctl;
@ -1224,15 +1285,12 @@ 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
#endif
{
} else {
pciide_mapreg_dma(sc, pa);
if (sc->sc_dma_ok != 0)
printf(", (partial support)");
@ -1268,9 +1326,12 @@ 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
@ -1283,13 +1344,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",
@ -1310,7 +1371,7 @@ next:
}
}
#if !defined(PMON)||defined(IDE_DMA)
#ifndef PMON
if (sc->sc_dma_ok == 0)
return;
@ -1996,6 +2057,88 @@ 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