[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: (wdc_obio.c) ata-4 improves 40% in transfer
- Subject: Re: (wdc_obio.c) ata-4 improves 40% in transfer
- From: Tsubai Masanari <tsubai@iri.co.jp>
- To: port-powerpc-ja@jp.netbsd.org
- Date: Sun, 01 Jul 2001 20:58:06 +0900
- Message-Id: <E15Gfra-0003Lw-00@ruri.iri.co.jp>
- In-Reply-To: <200106290108.GMT@onsemi.ki.nu>
- Delivered-To: mailing list port-powerpc-ja@jp.netbsd.org
- Mailing-List: contact port-powerpc-ja-help@jp.netbsd.org; run by ezmlm-idx
>○ ところで wd1 として MDMA が付いている時に、つまり次のような時に、
...
>○ 次のように止ってしまいます。
wdc を Ultra のタイミングにしちゃうので当然なんですが、もちろん
それでいいわけないのでこれ↓で遅いほうに合わせます。
この場合、たぶん dd で計る速度は以前よりかなり遅くなります。普通の
MDMA 並に、ってことですけど。
# 書きかけなので再配付には注意してください。以前の ADB のパッチみたい
# に連絡なしに commit しちゃうこまったちゃんがいますので。
*** wdc_obio.c~ Sat Jun 16 02:02:41 2001
--- wdc_obio.c Sun Jul 1 20:47:48 2001
***************
*** 81,86 ****
--- 81,87 ----
void wdc_obio_dma_start __P((void *, int, int));
int wdc_obio_dma_finish __P((void *, int, int, int));
static void adjust_timing __P((struct channel_softc *));
+ static void adjust_timing_ata4 __P((struct channel_softc *));
struct cfattach wdc_obio_ca = {
sizeof(struct wdc_obio_softc), wdc_obio_probe, wdc_obio_attach,
***************
*** 187,192 ****
--- 188,203 ----
sc->sc_wdcdev.dma_start = wdc_obio_dma_start;
sc->sc_wdcdev.dma_finish = wdc_obio_dma_finish;
sc->sc_wdcdev.set_modes = adjust_timing;
+
+ if (strcmp(ca->ca_name, "ata-4") == 0) {
+ sc->sc_wdcdev.cap |= WDC_CAPABILITY_UDMA;
+ sc->sc_wdcdev.UDMA_cap = 4;
+ sc->sc_wdcdev.set_modes = adjust_timing_ata4;
+ #if 1
+ printf("%s: ata-4\n", self->dv_xname);
+ #endif
+ }
+
chp->channel = 0;
chp->wdc = &sc->sc_wdcdev;
chp->ch_queue = malloc(sizeof(struct channel_queue),
***************
*** 212,221 ****
wdcattach(chp);
! /* modify DMA access timings */
! if (use_dma)
! adjust_timing(chp);
!
}
/* Multiword DMA transfer timings */
--- 223,230 ----
wdcattach(chp);
! /* Modify access timings. */
! sc->sc_wdcdev.set_modes(chp);
}
/* Multiword DMA transfer timings */
***************
*** 236,242 ****
{ 120, 70 }, /* Mode 2 */
};
! #define TIME_TO_TICK(time) howmany((time), 30)
#define CONFIG_REG (0x200 >> 4) /* IDE access timing register */
--- 245,252 ----
{ 120, 70 }, /* Mode 2 */
};
! #define TIME_TO_TICK(time) howmany(time, 30)
! #define TIME_TO_TICK_ATA4(time) howmany((time) * 2, 15)
#define CONFIG_REG (0x200 >> 4) /* IDE access timing register */
***************
*** 295,300 ****
--- 305,395 ----
conf |=
(half_tick << 21) | (inact_tick << 16) | (act_tick << 11);
}
+ bus_space_write_4(chp->cmd_iot, chp->cmd_ioh, CONFIG_REG, conf);
+ #if 0
+ printf("conf = 0x%x, cyc = %d (%d ns), act = %d (%d ns), inact = %d\n",
+ conf, cycle_tick, min_cycle, act_tick, min_active, inact_tick);
+ #endif
+ wdc_print_modes(chp);
+ }
+
+ void
+ adjust_timing_ata4(chp)
+ struct channel_softc *chp;
+ {
+ struct ata_drive_datas *drvp;
+ u_int conf;
+ int drive;
+ int piomode = -1, dmamode = -1, udmamode = -1;
+ int min_cycle, min_active;
+ int cycle_tick, act_tick, inact_tick;
+
+ for (drive = 0; drive < 2; drive++) {
+ drvp = &chp->ch_drive[drive];
+ if ((drvp->drive_flags & DRIVE) == 0)
+ continue;
+ if (piomode == -1 || piomode > drvp->PIO_mode)
+ piomode = drvp->PIO_mode;
+ if (drvp->drive_flags & DRIVE_DMA) {
+ if (dmamode == -1 || dmamode > drvp->DMA_mode)
+ dmamode = drvp->DMA_mode;
+ }
+ if (drvp->drive_flags & DRIVE_UDMA) {
+ if (udmamode == -1 || udmamode > drvp->DMA_mode)
+ udmamode = drvp->UDMA_mode;
+ } else
+ udmamode = -2;
+ }
+ for (drive = 0; drive < 2; drive++) {
+ drvp = &chp->ch_drive[drive];
+ if (drvp->drive_flags & DRIVE) {
+ drvp->PIO_mode = piomode;
+ if (drvp->drive_flags & DRIVE_DMA)
+ drvp->DMA_mode = dmamode;
+ if (drvp->drive_flags & DRIVE_UDMA) {
+ if (udmamode < 0)
+ drvp->drive_flags &= ~DRIVE_UDMA;
+ else
+ drvp->UDMA_mode = udmamode;
+ }
+ }
+ }
+ min_cycle = pio_timing[piomode].cycle;
+ min_active = pio_timing[piomode].active;
+
+ cycle_tick = TIME_TO_TICK_ATA4(min_cycle);
+ act_tick = TIME_TO_TICK_ATA4(min_active);
+ inact_tick = cycle_tick - act_tick;
+
+ /* conf &= ~0x3ff; 5-5 */
+ conf = (inact_tick << 5) | act_tick;
+
+ if (dmamode >= 0) {
+ /* there are active DMA mode */
+
+ min_cycle = dma_timing[dmamode].cycle;
+ min_active = dma_timing[dmamode].active;
+
+ cycle_tick = TIME_TO_TICK_ATA4(min_cycle);
+ act_tick = TIME_TO_TICK_ATA4(min_active);
+ inact_tick = cycle_tick - act_tick;
+
+ /* XXX */
+ inact_tick = min(inact_tick, 31);
+
+ /* conf &= ~0x001ffc00; 1-5-5? */
+ conf |= inact_tick << 15 | act_tick << 10;
+ }
+
+ if (udmamode >= 0) {
+ /* XXX really? */
+ act_tick = 0;
+ cycle_tick = 0;
+
+ /* conf &= ~0x1ff00000; 4-4-1 */
+ conf |= act_tick << 25 | cycle_tick << 21 | 1 << 20;
+ }
+
bus_space_write_4(chp->cmd_iot, chp->cmd_ioh, CONFIG_REG, conf);
#if 0
printf("conf = 0x%x, cyc = %d (%d ns), act = %d (%d ns), inact = %d\n",