[unix-pc.general] HELP with *BLOCK* device driver

michael@stb.uucp (Michael Gersten) (02/05/90)

HELP! I'm getting bind errors with this.

Repeat-by:
masterupd -a block open close strategy release nfs
cc -c nfs.c
lddrv -av nfs

lddrv complains: BIND error: Invalid parameter.

Note that if I say it is a char driver, with read instead of strategy,
it works fine. Can block device drivers be loaded at all?

(this is an attempt to write a driver whose data is supplied by another
user program; in this case getting data from another machine by serial
port).
	
/* block device driver. */
#define NUMDEV 8	/* Number of remote files */
/* Here's how it works. read/write (character device) is the user
mode relay code. strategy is the block code. We get the address,
length, and pass it to whoever is waiting on the read channel.

Specifically: Relayer does a read (char dev). We send him a READ
(long) start address (long) length (long)
Or a WRITE (long) start address (long) length (long) data

	This is the driver code. */

#define DEBUG

#include <sys/param.h>
#include <sys/buf.h>
#include <sys/iobuf.h>
#include <sys/dir.h>
#include <sys/conf.h>
#include <sys/user.h>
#include <errno.h>

extern struct user u;

struct iobuf nfstab[NUMDEV];	/* Start of request queue */
int ControlOpen = 0;
struct buf *CurrentBuf = NULL;

struct io {
	long devicenum;
	long readflag;
	long startblock;
	long length;
	char data[4];
};

/* An idea for the future: one raw control channel per real disk? Nahw, then
we can't do real raw i/o to the drives */

nfsopen (dev, flag, id)
/* id = 0 for char, 1 for block */
/* dev = 0 for control channel, other for real channel */
{
eprintf ("Open: dev=%d, flag=%d, id=%d\n", dev, flag, id);
	if (dev == 0 && id == 0 && ControlOpen == 0)	/* raw control */
		ControlOpen = 1;
	else if (dev == 0 || id == 0)	/* raw real or block control */
		u.u_error = ENXIO;
}

nfsclose (dev, flag)
{
eprintf ("Close: dev=%d, flag=%d\n", dev, flag);
	if (dev == 0)
		ControlOpen = 0;
}

nfsstrategy(bp)
struct buf *bp;
{
	int x;
#ifdef DEBUG
eprintf ("Strategy: Incoming data:\n");
eprintf ("for dev=%d\n", bp->b_dev);
eprintf ("count cyl sec trk\n");
eprintf ("  %d  %d   %d  %d\n", bp->x.count, bp->x.cyl, bp->x.sec, bp->x.trk);
eprintf ("blkno bcount paddr\n");
eprintf ("%5d %5d %x", bp->b_blkno, bp->b_bcount, paddr(bp));
#endif
	iodone (bp);
	return;
	/*NOTREACHED*/
	/* NOTREACHED */
	bp->x.cyl = 0;
	/** No disksort() routine???
	x = spl6();
	disksort (&nfstab[bp->b_dev], bp);
	splx (x);
	*/
	wakeup (&nfstab[bp->b_dev]); /* Wakeup someone waiting for a command */
}

nfsrelease()
{};

nfsread()
{}
;
-- 
		Michael
denwa!stb!michael anes.ucla.edu!stb!michael 
"The 80's: Ten years that came in a row."

lenny@icus.islp.ny.us (Lenny Tropiano) (02/06/90)

In article <1990Feb5.074541.26335@stb.uucp> michael@stb.uucp (Michael Gersten) 
writes:
|>
|>HELP! I'm getting bind errors with this.
|>
|>Repeat-by:
|>masterupd -a block open close strategy release nfs
|>cc -c nfs.c
|>lddrv -av nfs
|>
|>lddrv complains: BIND error: Invalid parameter.
|>
|>Note that if I say it is a char driver, with read instead of strategy,
|>it works fine. Can block device drivers be loaded at all?
|>
[...]
Ahh, I remember this well! :-)  For some reason or another, a entry point
in the device driver called "drvprint()" is required. 
drv is the driver name (ie. nfs) and the masterupd line being:

# masterupd -a block open close strategy release print nfs

The print-entry-point isn't discussed, at least to my recollection, in
the "Writing a Device Driver Guide" so I don't even know what it does,
and why it _might_ be called.

There are other entry points that are "available" in masterupd(1M) according
to a string dump:

ioctl write read close open init print strategy release info lopen lclose 
lread lwrite lioctl linput loutput lmdmint char block required
supp nocnt once

Some of course are familar, and some are not...

-Lenny
-- 
| Lenny Tropiano            ICUS Software Systems      lenny@icus.islp.ny.us |
| {ames,pacbell,decuac,hombre,sbcs,attctc}!icus!lenny     attmail!icus!lenny |
+------- ICUS Software Systems -- PO Box 1;  Islip Terrace, NY  11752 -------+

jcm@mtune.ATT.COM (John McMillan) (02/06/90)

In article <1990Feb5.074541.26335@stb.uucp> michael@stb.uucp (Michael Gersten) writes:
>
>HELP! I'm getting bind errors with this.
>
>Repeat-by:
>masterupd -a block open close strategy release nfs
>cc -c nfs.c
>lddrv -av nfs
>
>lddrv complains: BIND error: Invalid parameter.

	I don't find that error in the sources.  Are you running 3.51 ?

>Note that if I say it is a char driver, with read instead of strategy,
>it works fine. Can block device drivers be loaded at all?

	I've never dealt with a BLOCK driver that lacked an
	underlying CHAR driver.  This presumption may be
	built into the code.  You can always FAKE the CHAR
	entries -- aborting an OPEN.

>(this is an attempt to write a driver whose data is supplied by another
>user program; in this case getting data from another machine by serial
>port).
:
	I didn't see -- in a 15 second intense scrutiny ;-) --
	WHY you were writing a BLOCK driver rather than a CHAR
	driver....  Nor shall I worry about it.

john mcmillan -- att!mtune!jcm -- muttering for SELF, not them

jcm@mtune.ATT.COM (John McMillan) (02/07/90)

In article <1087@icus.islp.ny.us> lenny@icus.islp.ny.us (Lenny Tropiano) writes:
:
>Ahh, I remember this well! :-)  For some reason or another, a entry point
>in the device driver called "drvprint()" is required. 
>drv is the driver name (ie. nfs) and the masterupd line being:
>
># masterupd -a block open close strategy release print nfs
>
>The print-entry-point isn't discussed, at least to my recollection, in
>the "Writing a Device Driver Guide" so I don't even know what it does,
>and why it _might_ be called.
:
	1) It is ridiculous that an unsupplied PRINT param is not
		converted to a null procedure call.  Not my code.
		"They" were probably rushed -- EVERYONE was rushed.

	2) 'prdev()' is used to print FS errors: eg.,
			prdev("Bad free count", dev);
		'prdev(str,dev)' calls
			(*bdevsw[bmajor(dev)].d_print)(minor(dev), str);
		This permits logging or other activities particular
		to that device.

	3) All -- the ONLY 8-) -- built-in BLOCK drivers ignore the
		feature by using 'nulldev' as the value for the procedure.

jcm -- muttering for self, not them