Benjamin Herrenschmidt wrote: ;; >- out_le32(&md->control, (RUN|PAUSE|FLUSH|WAKE) << 16); /* stop dma */ ;; ;; What about waiting for the DBDMA channel to actually stop ? ;; You should spin loop until the channel is actually stopped here. ;; ;; Note also that due to PCI write posting, doing an out_xxx, followed by a ;; udelay, may not work properly. You should do the out_xx, then a dummy ;; in_xxx from the same PCI bus to fush write buffers, then the udelay.
After applying the patch from velco, my mesh_init looks like this: static void mesh_init(struct mesh_state *ms) { volatile struct mesh_regs *mr = ms->mesh; volatile struct dbdma_regs *md = ms->dma; udelay(100); out_8(&mr->exception, 0xff); /* clear all exception bits */ out_8(&mr->error, 0xff); /* clear all error bits */ out_8(&mr->sequence, SEQ_RESETMESH); /* flush write buffers.. How? in_8(&mr->sequence); ?? */ udelay(10); out_8(&mr->interrupt, 0xff); /* clear all interrupt bits */ out_8(&mr->intr_mask, INT_ERROR | INT_EXCEPTION | INT_CMDDONE); out_8(&mr->source_id, ms->host->this_id); out_8(&mr->sel_timeout, 25); /* 250ms */ out_8(&mr->sync_params, ASYNC_PARAMS); /* asynchronous initially */ /* stop dma */ out_le32(&md->control, (RUN|PAUSE|FLUSH|WAKE) << 16); } Since I have little idea what it is doing, I don't think I am capable of incorporatng your suggestions into it... Could you just tell me if the above code is dangerous to use (it could trash my HD etc)? regards, abe