From owner-freebsd-hackers Mon Nov 9 12:34:58 1998 Return-Path: Received: (from majordom@localhost) by hub.freebsd.org (8.8.8/8.8.8) id MAA18176 for freebsd-hackers-outgoing; Mon, 9 Nov 1998 12:34:58 -0800 (PST) (envelope-from owner-freebsd-hackers@FreeBSD.ORG) Received: from dingo.cdrom.com (dingo.cdrom.com [204.216.28.145]) by hub.freebsd.org (8.8.8/8.8.8) with ESMTP id MAA18171 for ; Mon, 9 Nov 1998 12:34:55 -0800 (PST) (envelope-from mike@dingo.cdrom.com) Received: from dingo.cdrom.com (localhost.cdrom.com [127.0.0.1]) by dingo.cdrom.com (8.9.1/8.8.8) with ESMTP id MAA00693; Mon, 9 Nov 1998 12:33:57 -0800 (PST) (envelope-from mike@dingo.cdrom.com) Message-Id: <199811092033.MAA00693@dingo.cdrom.com> X-Mailer: exmh version 2.0.2 2/24/98 To: lcremean@tidalwave.net cc: hackers@FreeBSD.ORG Subject: Re: Encryption coprocessor, part 2. In-reply-to: Your message of "Mon, 09 Nov 1998 15:14:23 EST." <19981109151423.A2157@tidalwave.net> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Date: Mon, 09 Nov 1998 12:33:57 -0800 From: Mike Smith Sender: owner-freebsd-hackers@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.ORG > All right, I've figured out what I want to do with the packets (though a > zero-copy implementation would be faster, I doubt it's easy to do here). I'm > going to set up a list of buffers in memory, then feed their address to the > chip as needed...(actually, it'll be four rings, since there are 4 DMA > channels). What I need to know now is what the best way would be to get the > user buffers into the kernel (I'm assuming we'd be trying to send pointers > to all four at once, then copying). Er, this is really list management 101. For each buffer set you have: - a free list, populated at startup - a work queue - a done queue It sounds from your previous messages as though the control buffers are actually associated with the data buffers, so you might want to unify them. In the write routine, assuming that you mandate atomic writes of single packets, you do something like this: if (uio->uio_resid != WRITE_SIZE) return(ENOSPC); bufp = getbuf_free(); if ((error = uiomove(bufp->data, WRITE_SIZE, uio)) != 0) { putbuf_free(bufp); return(error); } putbuf_work(bufp); foointr(); the interurpt handler should do something like: if (interrupt_reason & WORK_DONE) { bufp = sc->busybuf; putbuf_done(bufp); } if (device_status & CHANNEL_FREE) { bufp = getbuf_work(); if (bufp != NULL) { sc->busybuf = bufp; stuff_buffer_into_device(); } } and the read routine should look like this: if (uio->uio_resid != READ_SIZE) return(ENOSPC); bufp = getbuf_done(); if ((error = uiomove(bufp->data, READ_SIZE, uio)) != 0) { putbuf_done(bufp); /* XXX push onto head of list */ return(error); } putbuf_free(bufp); Then you just need to arrange for the getbuf_done and getbuf_free functions to sleep if there's no buffer on the head of the queue. -- \\ Sometimes you're ahead, \\ Mike Smith \\ sometimes you're behind. \\ mike@smith.net.au \\ The race is long, and in the \\ msmith@freebsd.org \\ end it's only with yourself. \\ msmith@cdrom.com To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message