diff options
| author | scottr <scottr@NetBSD.org> | 1998-09-14 05:49:21 +0000 |
|---|---|---|
| committer | scottr <scottr@NetBSD.org> | 1998-09-14 05:49:21 +0000 |
| commit | f2c6836685448c109d5ba89ed0b91ff2abb9d42d (patch) | |
| tree | a1e58b4bcfad6dc0b091b86e9c06b826212e0204 /sys/dev | |
| parent | 10640f1bfc8ece38df616617d549f9000b759c9e (diff) | |
Fix a problem uncovered when we started to use the pool allocator to manage
scsipi_xfer structures.
When scsipi_execute_xs() calls the driver's scsi_cmd function, it assumes
that it can still dereference a pointer to the scsipi_xfer struct. Since
scsipi_done() has already been called, which in turn has called
scsipi_free_xs(), the struct has already been returned the structure to
the pool! In other words, xs->flags has been compromised, but we are still
testing it.
These changes resolve the problem by doing the following:
- In scsipi_execute_xs(), if the hardware driver's scsi_cmd function
returns SUCCESSFULLY_QUEUED, set a new flag (SCSI_ASYNCREQ) in xs->flags.
Since the request will be handled asynchronously, we will need the
scsipi_xfer struct to be freed in scsipi_done().
If the hardware driver's scsi_cmd function returns COMPLETE, we now
simply return any actual errors, or 0 if none occurred. (Previously,
we may have returned EJUSTRETURN, of which the sole effect was to
avoid freeing the scsipi_xfer struct in our caller.)
- In scsipi_done(), only free the scsipi_xfer struct for async requests.
The contents of the struct will otherwise remain valid until the
function that initiated the transfer frees it.
With this change, responsibility for freeing the struct now lies in two
places, depending on the type of the request:
- For synchronous requests, the routine calling scsipi_execute_xs()
must clean up.
- For asynchronous requests, scsipi_done() cleans up (as it always has).
[Note: this change also corrects a problem with sddump(): scsipi_done()
was attempting to return a static scsipi_xfer struct to the pool! Since
dumps are performed synchronously, we now handle this correctly.]
This solution was provided by Jason Thorpe, after I got him to look at
some related (but insufficient) attempts of my own.
Diffstat (limited to 'sys/dev')
| -rw-r--r-- | sys/dev/scsipi/scsipiconf.h | 4 |
1 files changed, 3 insertions, 1 deletions
diff --git a/sys/dev/scsipi/scsipiconf.h b/sys/dev/scsipi/scsipiconf.h index 09efeff1709..4fd844c9df7 100644 --- a/sys/dev/scsipi/scsipiconf.h +++ b/sys/dev/scsipi/scsipiconf.h @@ -1,4 +1,4 @@ -/* $NetBSD: scsipiconf.h,v 1.14 1998/09/08 07:32:42 mjacob Exp $ */ +/* $NetBSD: scsipiconf.h,v 1.15 1998/09/14 05:49:21 scottr Exp $ */ /*- * Copyright (c) 1998 The NetBSD Foundation, Inc. @@ -288,6 +288,8 @@ struct scsipi_xfer { #define SCSI_TARGET 0x2000 /* This defines a TARGET mode op. */ #define SCSI_ESCAPE 0x4000 /* Escape operation */ #define SCSI_URGENT 0x8000 /* Urgent operation (e.g., HTAG) */ + /* 0x00ff0000 reserved for ATAPI. */ +#define SCSI_ASYNCREQ 0x01000000 /* request completes asynchronously */ /* * Error values an adapter driver may return |
