[comp.sys.mac.programmer] Whaddya do in ioCompletion routine?

rmitchel@bbn.com (Rob Mitchell) (03/01/91)

	So, I'm writing all this AppleTalk Preferred Interface call,
	post a few GetRequest asynchronously, and wait.

	Well, when the ioCompletion routine is called by Device Mgr.,
	what do I do?  I know I have to SetupA5() and RestoreA5() and
	call some a self-created function in the middle, but what does
	that buy me?  Which Parameter Block is being returned by the
	Device Mgr. and how can I access it with "moving memory?"

	Thanks fer yer support.


Rob Mitchell                            Advanced Simulation Division
Unix & Macintosh Engineer               BBN Systems & Technologies
Internet: rmitchel@vax.bbn.com          33 Moulton Street   MS: 8/C
Primary Dwelling:   617-873-4041        Cambridge, MA  02138
Secondary Dwelling: 617-873-4071
FAX:                617-873-4315

These opinions are mine and mine only.  They do not represent BBNs' opinions.

stevec@Apple.COM (Steve Christensen) (03/02/91)

In article <63044@bbn.BBN.COM> rmitchel@bbn.com (Rob Mitchell) writes:
>
>	So, I'm writing all this AppleTalk Preferred Interface call,
>	post a few GetRequest asynchronously, and wait.
>
>	Well, when the ioCompletion routine is called by Device Mgr.,
>	what do I do?  I know I have to SetupA5() and RestoreA5() and
>	call some a self-created function in the middle, but what does
>	that buy me?  Which Parameter Block is being returned by the
>	Device Mgr. and how can I access it with "moving memory?"

Completion routines are called when an asynchronous driver request completes
(hence the name).  The completion routine is passed a pointer to the parameter
block from the completing request.  The completion routine is most likely
being called at an interrupt level, so all the rules about not moving memory
apply (i.e., don't call any Toolbox, Quickdraw, etc., routines).

So what does it buy you?  Well, you can modify program variables if you want,
or daisy-chain another request based on whether or not the current request
completed successfully, or...

steve

-- 
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  Steve Christensen			Never hit a man with glasses.
  stevec@apple.com			Hit him with a baseball bat.

dundas@granite.jpl.nasa.gov (John Dundas) (03/08/91)

Read Inside Macintosh II, pp. 181-183 carefully.  To quote:  "When your
completion routine is called, register A0 points to the parameter block
of the asynchronous call and register D0 contains the result code."

John Dundas

tim@hoptoad.uucp (Tim Maroney) (03/09/91)

In article <63044@bbn.BBN.COM> rmitchel@bbn.com (Rob Mitchell) writes:
>	So, I'm writing all this AppleTalk Preferred Interface call,
>	post a few GetRequest asynchronously, and wait.
>
>	Well, when the ioCompletion routine is called by Device Mgr.,
>	what do I do?  I know I have to SetupA5() and RestoreA5() and
>	call some a self-created function in the middle, but what does
>	that buy me?  Which Parameter Block is being returned by the
>	Device Mgr. and how can I access it with "moving memory?"

It's best not to use A5 if you can help it.  I prefer to stuff an
unused field of the parameter block with a pointer to some data area
which may be used by the request.  The Mac queue data structures work
well for this, since Enqueue and Dequeue are interrupt-friendly.  To
get at the parameter block, look at register A0 on entry to your
completion routine.

If you must use A5, note that you can't rely on CurrentA5 at the
interrupt level.  You will have to stuff your A5 in the parameter
block, in an unused field.
-- 
Tim Maroney, Mac Software Consultant, sun!hoptoad!tim, tim@toad.com

"Something was badly amiss with the spiritual life of the planet, thought
 Gibreel Farishta.  Too many demons inside people claiming to believe in
 God." -- Salman Rushdie, THE SATANIC VERSES

urlichs@smurf.sub.org (Matthias Urlichs) (03/10/91)

In comp.sys.mac.programmer, article <15951@hoptoad.uucp>,
  tim@hoptoad.UUCP (Tim Maroney) writes:
< 
< It's best not to use A5 if you can help it.  I prefer to stuff an
< unused field of the parameter block with a pointer to some data area
< which may be used by the request. [...]
To be safe, don't rely on any fields being unused (sometimes the ROM does
some really weird things with your parameter blocks) but instead declare a
structure like this:

struct myPB {
     HParamBlockRec PB; // or whatever
     struct myGlobals *Globals; // anything
};

This method also comes in handy when you have to do some pseudo-multitasking.
For instance, in my SingleShare server there are three pointers to globals in
SingleShare's moral equivalent of this structure; one to global state, one
for user-related state and one for the state of the current command.
You can also have more than one parameter block in there, but in that case
you'll have to do some pointer arithmetic. (Beware -- said arithmetic may
conceivably trash the A0 pointer you want to get, so better use a temporary
variable.)

-- 
Matthias Urlichs -- urlichs@smurf.sub.org -- urlichs@smurf.ira.uka.de     /(o\
Humboldtstrasse 7 - 7500 Karlsruhe 1 - FRG -- +49-721-621127(0700-2330)   \o)/

zben@ni.umd.edu (Ben Cranston) (03/11/91)

Anybody seen the behaviour with ASynch _Read calls:  whatever is in D0 when
the IO completion routine returns gets returned to the mainline in D0 rather
than the IO result for the operation itself?  I tend to code a check in the
mainline:

        LEA  IOPB,A0
        _Read  ASync
        BEq.S  around
        <ERROR DETECTED HERE>
around  ;

and in the completion routine

Compl	;
    Tst.W  D0
    BEq.S  around
    <ERROR DETECTED HERE>
around  ;

and I find I have to be very careful to clear D0 at the exit of the
completion routine or else the value will pop up as an error in the
mainline.

Also, anybody ever seen an asynch _Open and/or _Read return to the
mainline with D0 = 1 and ioResult(A0) = 2????  I've only seen this when
AppleShare Server was running in foreground...

urlichs@smurf.sub.org (Matthias Urlichs) (03/12/91)

In comp.sys.mac.programmer, article <1991Mar10.231236.21526@ni.umd.edu>,
  zben@ni.umd.edu (Ben Cranston) writes:
< Anybody seen the behaviour with ASynch _Read calls:  whatever is in D0 when
< the IO completion routine returns gets returned to the mainline in D0 rather
< than the IO result for the operation itself?  I tend to code a check in the
< mainline:
< 
<         LEA  IOPB,A0
<         _Read  ASync
<         BEq.S  around
<         <ERROR DETECTED HERE>
< around  ;
< 
Ignore the "error" returned from the _Read call. The D0 there might contain
literally anything.

The only reliable place where you get the error reported correctly is in the
completion routine.
< 
< Also, anybody ever seen an asynch _Open and/or _Read return to the
< mainline with D0 = 1 and ioResult(A0) = 2????  I've only seen this when
< AppleShare Server was running in foreground...

It's _asynchronous_. You don't have any guarantee that it returns in the next
five minutes, much less immediately. This only holds for SCSI, and only right
now because Apple seems to be still working on a reasonably intelligent SCSI
Manager.

The async call is completed iff the ioResult field is <= 0. Don't touch the
parameter block before that time.

-- 
Matthias Urlichs -- urlichs@smurf.sub.org -- urlichs@smurf.ira.uka.de     /(o\
Humboldtstrasse 7 - 7500 Karlsruhe 1 - FRG -- +49-721-621127(0700-2330)   \o)/