Return to BSD News archive
Newsgroups: comp.os.386bsd.development Path: sserve!newshost.anu.edu.au!munnari.oz.au!constellation!osuunx.ucc.okstate.edu!moe.ksu.ksu.edu!vixen.cso.uiuc.edu!howland.reston.ans.net!europa.eng.gtefsd.com!uunet!world!hd From: hd@world.std.com (HD Associates) Subject: Re: part 1 of 4 scsi system Message-ID: <CCqDEK.FLF@world.std.com> Organization: The World Public Access UNIX, Brookline, MA References: <264ert$kp@belfast.dcd.wa.gov.au> Date: Thu, 2 Sep 1993 14:25:31 GMT Lines: 248 In article <264ert$kp@belfast.dcd.wa.gov.au>, Julian Elischer <juliane@belfast.dcd.wa.gov.au> wrote: >here are the latest copies of the scsi sources in my tree. >they fix several problems, particularly in tape controllers, >however they probably break some devices I can no-longer test.. >(e.g. no-one has tested the audio in cd.c for a long time) ... >There is MOST of a generic scsi driver included, but the port is not >complete, because there are some kernel patches needed as well. >I may post them separatly, at which time it should be a working driver. Peter? That must be my que. The generic SCSI driver is a subset of the SGI "ds" (/dev/scsi) driver. I've used it to successfully port some software between the SGI and 386bsd. I also have a subset of the SGI libds.a library that I'll put together and post. This suits my needs, however, as I've kicked around with Julian, I'm not sure it is any better than publishing an interace that matches his data structures (the advantage of familiarity both in and out of the kernel) or by basing something on the SCSI CAM proposal (the advantage of a proposed standard). This has the advantage of some prior art. These kernel patches permit outside access to physio, via a rawio function. The smart solution is to publish physio and have it work the way it is documented in the daemon book. Chris (cgd) has done this on netbsd. netbsd users should find it easy to modify the driver to use physio directly, or to add a rawio function that behaves the way the one I stuck in 386bsd works. I think access to physio is the right solution. As I'm moving to netbsd 0.9 (hope to go get my tape today) I'll probably be doing this soon. These are the patches I have. *** kern_subr.c.orig Fri Apr 30 09:53:52 1993 --- kern_subr.c Fri Apr 30 10:08:49 1993 *************** *** 100,108 **** return (error); } ! uioapply(func, arg1, arg2, uio) ! int (*func)() ; ! register struct uio *uio; { register struct iovec *iov; u_int cnt, cnt1; --- 100,109 ---- return (error); } ! int uioapply( ! int (*func)() , ! int arg1, int arg2, int arg3 , ! struct uio *uio) { register struct iovec *iov; u_int cnt, cnt1; *************** *** 124,130 **** continue; } cnt1 = cnt; ! error = (*func)(arg1, arg2, uio->uio_offset, uio->uio_rw, iov->iov_base, &cnt1, uio->uio_procp); cnt -= cnt1; iov->iov_base += cnt; --- 125,131 ---- continue; } cnt1 = cnt; ! error = (*func)(arg1, arg2, arg3, uio->uio_offset, uio->uio_rw, iov->iov_base, &cnt1, uio->uio_procp); cnt -= cnt1; iov->iov_base += cnt; *** kern__physio.c.orig Fri Apr 30 09:42:58 1993 --- kern__physio.c Fri Apr 30 13:17:16 1993 *************** *** 53,58 **** --- 53,62 ---- * 09 Sep 92 Paul Kranenburg Fixed read from /dev/drum * 28 Nov 92 Mark Tinguely Fixed small leak in physio() */ + + /* 28 Apr 93 Peter Dufault Added passed in bp + */ + static char rcsid[] = "$Header: /usr/bill/working/sys/kern/RCS/kern__physio.c,v 1.3 92/01/21 21:29:06 william Exp $"; #include "param.h" *************** *** 65,108 **** #include "vm/vm.h" #include "specdev.h" ! static physio(int (*)(), int, int, int, caddr_t, int *, struct proc *); ! ! /* ! * Driver interface to do "raw" I/O in the address space of a ! * user process directly for read and write operations.. ! */ ! ! rawread(dev, uio) ! dev_t dev; struct uio *uio; ! { ! return (uioapply(physio, cdevsw[major(dev)].d_strategy, dev, uio)); ! } ! ! rawwrite(dev, uio) ! dev_t dev; struct uio *uio; ! { ! return (uioapply(physio, cdevsw[major(dev)].d_strategy, dev, uio)); ! } ! ! static physio(strat, dev, off, rw, base, len, p) int (*strat)(); dev_t dev; int rw, off; caddr_t base; int *len; struct proc *p; { - register struct buf *bp; int amttodo = *len, error, amtdone; vm_prot_t ftype; static zero; caddr_t adr; rw = rw == UIO_READ ? B_READ : 0; /* create and build a buffer header for a transfer */ ! bp = (struct buf *)malloc(sizeof(*bp), M_TEMP, M_NOWAIT); ! bzero((char *)bp, sizeof(*bp)); /* 09 Sep 92*/ bp->b_flags = B_BUSY | B_PHYS | rw; bp->b_proc = p; bp->b_dev = dev; --- 69,97 ---- #include "vm/vm.h" #include "specdev.h" ! static physio(strat, dev, bp, off, rw, base, len, p) int (*strat)(); dev_t dev; + struct buf *bp; int rw, off; caddr_t base; int *len; struct proc *p; { int amttodo = *len, error, amtdone; vm_prot_t ftype; static zero; caddr_t adr; + int bp_alloc = (bp == 0); rw = rw == UIO_READ ? B_READ : 0; /* create and build a buffer header for a transfer */ ! ! if (bp_alloc) { ! bp = (struct buf *)malloc(sizeof(*bp), M_TEMP, M_NOWAIT); ! bzero((char *)bp, sizeof(*bp)); /* 09 Sep 92*/ ! } bp->b_flags = B_BUSY | B_PHYS | rw; bp->b_proc = p; bp->b_dev = dev; *************** *** 119,129 **** /* first, check if accessible */ if (rw == B_READ && !useracc(base, bp->b_bcount, B_WRITE)) { ! free(bp, M_TEMP); return (EFAULT); } if (rw == B_WRITE && !useracc(base, bp->b_bcount, B_READ)) { ! free(bp, M_TEMP); return (EFAULT); } --- 108,120 ---- /* first, check if accessible */ if (rw == B_READ && !useracc(base, bp->b_bcount, B_WRITE)) { ! if (bp_alloc) ! free(bp, M_TEMP); return (EFAULT); } if (rw == B_WRITE && !useracc(base, bp->b_bcount, B_READ)) { ! if (bp_alloc) ! free(bp, M_TEMP); return (EFAULT); } *************** *** 154,160 **** } while (amttodo && (bp->b_flags & B_ERROR) == 0 && amtdone > 0); error = bp->b_error; ! free(bp, M_TEMP); *len = amttodo; return (error); } --- 145,178 ---- } while (amttodo && (bp->b_flags & B_ERROR) == 0 && amtdone > 0); error = bp->b_error; ! if (bp_alloc) ! free(bp, M_TEMP); *len = amttodo; return (error); } + + /* + * Driver interface to do "raw" I/O in the address space of a + * user process directly for read and write operations.. + */ + + /* bp can be NULL and one will be allocated and freed. + */ + int rawio(dev_t dev, struct uio *uio, struct buf *bp) + { + return uioapply(physio, + (int)(cdevsw[major(dev)].d_strategy), (int)dev, (int)bp, uio); + } + + rawread(dev, uio) + dev_t dev; struct uio *uio; + { + return rawio(dev, uio, 0); + } + + rawwrite(dev, uio) + dev_t dev; struct uio *uio; + { + rawio(dev, uio, 0); + } + Peter -- Peter Dufault Real Time Machine Control and Simulation HD Associates Voice: 508 433 6936 hd@world.std.com Fax: 508 433 5267 Looking for: Orangey-brown front leather seats or NOS covers for '73 BMW 3.0cs