From owner-freebsd-hackers Mon Dec 4 00:09:26 1995 Return-Path: owner-hackers Received: (from root@localhost) by freefall.freebsd.org (8.6.12/8.6.6) id AAA06883 for hackers-outgoing; Mon, 4 Dec 1995 00:09:26 -0800 Received: from ref.tfs.com (ref.tfs.com [140.145.254.251]) by freefall.freebsd.org (8.6.12/8.6.6) with ESMTP id AAA06876 for ; Mon, 4 Dec 1995 00:09:23 -0800 Received: (from julian@localhost) by ref.tfs.com (8.6.12/8.6.9) id AAA04418; Mon, 4 Dec 1995 00:07:42 -0800 From: Julian Elischer Message-Id: <199512040807.AAA04418@ref.tfs.com> Subject: Re: Proper way to determine non-blocking status... To: witr@rwwa.com (Robert Withrow) Date: Mon, 4 Dec 1995 00:07:41 -0800 (PST) Cc: bde@zeta.org.au, freebsd-hackers@freebsd.org, witr@rwwa.com In-Reply-To: <199512031615.LAA13131@spooky.rwwa.com> from "Robert Withrow" at Dec 3, 95 11:15:31 am X-Mailer: ELM [version 2.4 PL24] Content-Type: text Content-Length: 4444 Sender: owner-hackers@freebsd.org Precedence: bulk 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 > >