Re: Universal Driver Interface spec available

Alan Cox (alan@lxorguk.ukuu.org.uk)
Thu, 2 Sep 1999 19:43:18 +0100 (BST)


> I've been on the UDI tech mailing list for quite a while, yet haven't seen
> any postings from you with suggestions on how to improve performance. I
> haven't gone through the public comments, perhaps you put them there?

No. I read the 0.9 spec. I thought "oh dear". I read the 1.0 spec and thought
"oh well"

> waiting, they exit and allow the region locking mechanism within UDI handle
> when to call back.
> The drivers in UDI do not do mutexs. If anything, it should make things
> perform better on a real time system than they used to.

I can see that isa win for RtLinux

> > a portable way,
> > nor the memory allocator, nor the layering stuff.
>
> Does it need to? Why can't the OS do this, just tell the driver where to put
> the data?

Linux doesnt permit memory allocation in a block I/O handler. Linux
supports blocking memory allocations all sorts of places which UDI can't
express.

> > for Linux Magazine on 2.0->2.2 conversions - you can grab them from
> > O'Reilly's web site or buy the magazine 8)
>
> Got it and read it before I started. It fails to mention that PCI access was
> redone.

Read it again. It tells you that the old PCI methods still work.

> So what other surprises am I going to hit as I try to implement my Linux
> driver? I've already had to reference the kernel source a couple of times
> just to figure out the return types of a few functions.

The kernel source is the reference.

> The other thing you could do is point me to a well done loadable module
> character driver. Preferably one done for PCI that does bus mastering and
> uses MODULE_PARM() to allow some customization.

drivers/char/synclink.c is the only character driver making major use of
PCI bus mastering in simple ways (the video capture stuff tends to write
scripts for video engines so its less than intuitive). The network
drivers are a much easier read for that. Basically its

buf=kmalloc(size, GFP_KERNEL);
if(buf==NULL)
sulk();

phys_addr = virt_to_bus(buf);

write_buffer_out();

mb(); /* stop the compiler from any sneaky saves in registers */

poke_hardware(phys_addr);

Then whenever you are told the buffer is done continue with it.

The only horrible case to watch is terminating a live DMA. PCI does write
posting so doing

writel(STOP_DMA, card->control);
kfree(buf);

is fatal every so often, as the write will be posted, the buffer freed,
reallocated and trashed before the DMA is posted. Instead use

writel(STOP_DMA, card->control);
readl(card->anythingboring);
kfree(buf);

Alan

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@vger.rutgers.edu
Please read the FAQ at http://www.tux.org/lkml/