Date: Mon, 4 Dec 1995 00:07:41 -0800 (PST) From: Julian Elischer <julian@ref.tfs.com> To: witr@rwwa.com (Robert Withrow) Cc: bde@zeta.org.au, freebsd-hackers@freebsd.org, witr@rwwa.com Subject: Re: Proper way to determine non-blocking status... Message-ID: <199512040807.AAA04418@ref.tfs.com> In-Reply-To: <199512031615.LAA13131@spooky.rwwa.com> from "Robert Withrow" at Dec 3, 95 11:15:31 am
next in thread | previous in thread | raw e-mail | index | archive | help
I'm going to let bruce answer most of these, but am going to note which
ones are going to change when I get that far..
>
> Do you mind if I pepper you with some more questions?
>
> 4) I'm porting a streams driver to FreeBSD. It isn't
> a network style device, so I need to use the character
> dev model. The backend (and parts of the frontend)
> construct and enqueue messages to pass to the user
> when he eventually does a read. I need to alloc
> memory for each of these messages (which have random
> sizes, from dozens of bytes up to 1024 bytes). I'm curently
> using malloc(size,M_DEVBUF,waitflag). Is there better
> way to do this?
Note that in -current, the cdevsw entries are IN THE DRIVER
and not in conf.c (well they are in both places until
about Wednesday after which #define JREMOD will become the default..
Check any device that has cdevsw entries and check out the JREMOD sections
(though the conditional JREMOD will be gone soon)
>
> 6) Where does device ipl come from? I don't see it in the
> config file? How do I know what ipl my device interrupts
> at?
it's in the config file entry for each device..
dev net tty are the three known values I believe.
this is getting a bullet in the head in a coupel of weeks when
my present changes get that far. It will change but I'm not quite sure
how yet (other than the implientation will be very different)
>
> 7) xxintr(int unit). Which unit? How computed? I'm used
> to xxintr(int vec).
unit, as in if you are disk 2 you get 0x02
it's static at the moment and comes from the config stuff..
another bullet job I'm afraid.. (it'll happen at the same
time as the ipl change)
>
> 8) I see that people often avoid having xxread/xxwrite routines
> for this situation. I did the opposite: I have xxread/xxwrite
> routines and require the stuff sent to be protocol packets.
> Is there any major drawback to this besides the possiblity
> of having some butthead do ``cat /etc/passwd /dev/mcc''?
there are no draw-backs to using read/write..
the alternative (ioctl) would actually
be slower as it is a bit more complicated..
(it does a copyin() of your args first for you, etc..)
>
> Also:
>
> > The ugl^H^H^Hrightly formatted way is:
>
> Actual routine is:
>
> int mccread(dev_t dev, struct uio *uio, int ioflag)
> {
> mcc_t *mcc = MCC_DEV(dev); /* Private data for this channel */
Is the private data for the channel dynamically allocated?
> mcc_mblk_t *mp;
> int oldspl;
>
> /* Send first accumulated message, or wait if possible */
> again:
> oldspl = SPLINT(); /* Lock */
> mp = l_remove_head(&mcc->mcc_done); /* Get anything there */
> if (mp) { /* Return it */
> mc_primitives_union_t *mcp = MCC_MBLK_DATA(mp);
> if (mcp->header.mc_length > uio->uio_resid) {
> /*
> We refuse to copy less than a complete message,
> so we requeue this one!
> */
> l_add_head(&mcc->mcc_done,mp); /* Return it to head of list */
> splx(oldspl); /* Unlock */
> return EINVAL;
hmm is this the best message? This shouldn't happen too often..
a message to the console might speed up debugging of the app.
(at least 1 in 100 times) (if (n%100 == 1) printf("Idiot.. try getting the
whole packet\n");
> } else {
> splx(oldspl); /* Unlock */
> uiomove(mcp, mcp->header.mc_length, uio);
> free(mp,M_DEVBUF);
looks fine though I need to see if the user's target address has been checked..
somewhere it is checked for existance...
is it in uiomove?
(can't remember..) can uiomove fail?
> return 0;
> }
> } else if (ioflag & IO_NDELAY) { /* Can't block, sorry */
> splx(oldspl); /* Unlock */
> return EWOULDBLOCK;
> } else { /* Otherwise try again */
> int error;
> mcc->mcc_blocked = 1; /* Mark ourselves blocked */
> error = tsleep(&mcc->mcc_done, PZERO | PCATCH, "mccin", 0);
> mcc->mcc_blocked = 0; /* Mark ourselves unblocked */
> splx(oldspl); /* Unlock */
> if (error && (error != ERESTART)) return error;
> goto again;
> }
> }
>
looks pretty correct to me..
(though I would follow the 'read' thread through to see where the
check for write permissiosn on ram occurs)
julian
> -----------------------------------------------------------------------------
> Robert Withrow, Tel: +1 617 598 4480, Fax: +1 617 598 4430 Net: witr@rwwa.COM
> R.W. Withrow Associates, 319 Lynnway Suite 201, Lynn MA 01901 USA
>
>
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199512040807.AAA04418>
