Path: utzoo!attcan!utgpu!jarvis.csri.toronto.edu!rutgers!apple!bionet!ames!uhccux!munnari.oz.au!olympic!enno From: enno@olympic.oz (Enno Davids) Newsgroups: comp.sys.amiga.tech Subject: Re: help with disk/tape device driver(s) (quite long) Summary: More details on the problem. Keywords: device drivers, message ports, tasks Message-ID: <1048@olympic.oz> Date: 13 Jul 89 05:17:52 GMT References: <1006@olympic.oz> <5107@tekigm2.MEN.TEK.COM> Organization: Olympic Amusements, Melbourne, Australia. Lines: 137 In article <5107@tekigm2.MEN.TEK.COM>, phils@tekigm2.MEN.TEK.COM (Philip E Staub) writes: > In article <1006@olympic.oz> enno@olympic.oz (Enno Davids) writes: > [questions about device drivers] > > G'day Enno: > > Our machine apparently doesn't know how to get to oz, and I > don't know the correct routing to do it manually, hence this posting. > > This is a brief description of a hard disk device driver which I wrote (and > am continuing to tinker with). I'm sure it isn't quite the same sort of thing > that you're working with, but maybe the structure of the driver will give you > some ideas. > > [more good driver related stuff] > > Well, I hope this information is of some use to you. If there is anything > further you'd like to know about my driver, let me know. > > Regards, > Phil > -- G'Day Phil, Thanks for the (only!) reply. As you noted I am not doing exactly what you outlined, although I was in the past. To explain in more detail I have tried some disgusting ASCII pseudo-diagrams to help out. The problem I have is a fairly simple one. I have a SCSI adapter card and a hard disk driver that uses it. Nothing special here. This driver, much like the one you describe, and CBM documents in the RKM's, has a number of interface routines that various client tasks (most often filesystem tasks of course) use to interact with the driver. The driver either executes the appropriate code directly (e.g. open/close/beginIO to/with unit), or if the bus/unit is in use, may choose to queue the request for later completion by a task that has (as in your driver) been started for the unit. +--------+ | Client | DoIO/SendIO | task 1 | -------\ +--------+ \ \----> +------------------+ +---------+ | Driver interface | | | +--------+ /----> | routines 3 | --------------> | Common | | Client | / +------------------+ | SCSI | | task 2 | -------/ | |interface| +--------+ DoIO/SendIO | Queued I/O requests | code | v | | +--------------------+ | 5 | | Unit queue service | | | | task started by | ------------> | | | driver 4 | | | +--------------------+ +---------+ This is as I said much like the driver you described. The important point to note in this is which task is doing the work. For I/O requests that are immediately executed the 'current task' or context is that of the client task which originated the request. For queued I/O the context is that of the unit task that acts on the clients behalf sometime later. A final point of note is that non 'quick' I/O requests are replyed back to the calling client as recorded in the client's original I/O request (which was passed to the unit task whole) by whatever executes them (that is from box 3 or 4 as appropriate). Now I complicate the matter by acquiring a SCSI tape drive and adding it to the system. To simplify the software I want to keep the tape and disk driver code separate. To do this I must provide some alternate way for the tape driver code to access the SCSI bus independantly of the disk driver. The simplest way to do this is to provide a separate task which opens a public message port with a pre-defined name ('scsi_server' in this case) and accepts messages containing SCSI commands and data. The server puts these onto the bus and returns the SCSI completion status to the device driver. To visualise this pretend that I have added another task (6) to the diagram above, (off the right end of your terminal) which the common SCSI interface code (5) now interacts with (i.e. instead of driving the SCSI bus the interface code now sends a message to the server code which drives the bus for it.) The difficulty now arises when we consider contexts that the device driver code runs in. Specifically, the driver at some point must allocate a private reply port so that it can wait there for the returning message from the SCSI server task. Unfortunately the reply port has in it, a pointer to the task which sent it(!) and a signal mask used to wake the task (if the port is set as PA_SIGNAL). Unfortunately, these fields are set at the time the reply port is created, and can thus be quite wrong. The ideal situation is to have one private reply port per client task that opens the device driver, plus one for each each unit task that is started. Unfortunately, there is no easy way for the device driver to track which of several clients may currently be using it. Other solutions are to fudge the reply port creation so that it always asks for the same signal (if it is available) hence making all clients of the device driver use this signal and using FindTask(0) to fill in the task pointer immediately prior to sending the message to the scsi_server port. A final solution is to create the reply port at each instance of sending a message to the SCSI server and deleting it when the server completes processing. Each of these last two solutions has been implemented and works quite acceptably. I am however left with the nagging feeling that, 'there must be a better way' that I have missed. Hence my question to the net. The question is really quite generic in that what I am asking is how to allow a device driver to communicate with another task using message ports. Finally, I should note that the driver you described won't exhibit the problems I describe provided that the reply port is created by the unit task (as you appear to be automatically queuing all requests that will cause a real I/O to occur) although you will need to be careful in the unit close code to have the port removed. Other questions I originally asked were about what I could and couldn't do in the device driver. I believe for instance that it is not kosher to use dos.library either directly or otherwise. Is this correct? Interestingly the V1.1 RKM's example device driver shows the Init code using dos.library to CreateProc the unit task. Is dos OK here (e.g. to loadseg the scsi_server if it's port cannot be found and start it up). Could I make the scsi_server a device itself and OpenDevice it (with a possible load from disk, etc). I note that the 1.3 RKM example no longer uses dos but Exec to AddTask in do the same thing. Lastly, where is there any further information about the contents of the 1.3 include files scsidisk.h and hardblocks.h. (That is over and above the files themselves). Is this in the 1.3 Libraries & Devices RKM (not in Oz yet). Anyone from CBM care to comment about any of this? Enno. Just for the record, for those who want to try mail, the trick is to get to uunet and then to munnari. From there olympic.oz is one step (effectively). If you want to post a news reply stay in c.s.a.tech as we don't currently receive c.s.a in this country. Good Luck.