command (unlock for sd and cd) if no other partitions are open, return
EBUSY otherwise. DIOCEJECT will have the old semantic if its argument is not
0. The old ioctl has been renamed to ODIOCEJECT for binary compatibility.
in the drive. restrict "opening of empty drive" to character devices only
(reading a block device returns a short read instead of ENODEV, which can lead
to confusion).
pending_xfers queue.
- When freeing a scsipi_xfer, remove it from the device's pending_xfers
queue. If the queue is empty, and SDEV_WAITDRAIN is set, wakeup
those waiting for the queue to drain.
- Implement scsipi_wait_drain(), which waits for a device's pending_xfers
queue to drain.
"device_q" TAILQ entries. The former is for use by the adapter driver,
as it sees fit. The latter is for the scsipi middle layer to track
pending xfers per device.
- Add a pending_xfers queue to scsipi_link, to track pending xfers per
device.
- Grow scsipi_link's flags to int, and add SDEV_WAITDRAIN, to indicate that
we're waiting for the pending_xfers queue to empty.
FC loops). Change the semantics of scsi_probedev so that it returns 1 if
you should continue probing at this target, else 0 for not.
Replace the blanket use of '7' with the use of the new sc_maxlun property
that is now gathered from HBAs. Allocate scsipi_link arrays based upon this.
Fix a really nasty and silly bug that has been there for a while where the
number of first level scsipi_link structures was one less than it needed
to be.
an array of fixed-sized channel_softc elements. This way IDE controllers
which more than 1 channel (pciide) can extend the channel data easily
for private needs.
To avoid the double dereference at runtime, change the argument of
wdcstart() to the channel data pointer instead of the array index.
Return XS_SENSE when the full sense info has been retrieved, or
XS_SHORTSENSE if only the sense key was available (from the error register)
Make atapi_interpret_sense() deal with this, and call scsipi_interpret_sense()
for XS_SENSE. (XXX sd_interpret_sense() and the ioctl code needs to be made
aware of XS_SHORTSENSE too ! sense hanlding for these is now less broken for
devices that support 'REQUEST SENSE')
All the ATAPI devices I have access to seems to honnor the SENSE_REQUEST
command, but I suspect some ATAPI devices will not (althouh it's mandatory).
The code should be able to deal with this, but is untested ...
scsi_base.c to scsipi_base.c. Rename the functions from scsi_verbose.c
too, and rename the file itself. Cleaup includes too (scsi_*.h should not
be #included in scsipi_*.h files, which are supposed to be
common to atapi and scsi).
in the printing of DMA mode (piix3/4 only)
others: set the debug_mask to 0, so that debug messages are turned off by
default but can be easily turned on.
Reset drive_flags to 0 for unconfigured devices, so that they are ignored
later. For configured devices, reset state to 0 after probe/attach.
Our other constants also use "ATALK".
Added many new ETHERTYPE constants to sys/net/ethertypes.h, including the
ones from libpcap and tcpdump "ethertype.h" files.
Implement ioctl pass-through to the host bus adapter, allowing both
SCBUS* ioctls handled at that level and host adapter-specific ioctls
to be implemented. Implement SCBUSIORESET as a pass-through.
Inspired by PR #6090, from Matt Jacob.
struct scsipi_adapter; they were not used.
Add a scsipi_ioctl entry point to struct scsipi_adapter. This will be
used to issue ioctl commands to the host adapters.
Inspired by PR #6090, from Matt Jacob.
in scsipi_done() if the transfer is asynchronous. This reduces the size
of the critical section in scsipi_execute_xs() somewhat (in fact,
back to its original size).
(probably due to an interrupt) between the time it is scheduled and the
time we get around to setting the SCSI_ASYNCREQ flag, we can lose the xs.
Fix this by checking to see if the transfer has already completed after
the scsi_cmd function returns SUCCESSFULLY_QUEUED, and just return to the
caller if so.
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.
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 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 lower-level driver's scsi_cmd function
returns SUCCESSFULLY_QUEUED and SCSI_NOSLEEP is set in xs->flags, set a
new flag (SCSI_ASYNCREQ). This indicates that scsipi_done() should free
the scsipi_xfer struct.
If the lower-level driver's scsi_cmd function returns SUCCESSFULLY_QUEUED
but SCSI_NOSLEEP is not set, we wait (via tsleep()) for the request to
complete, then fall through to the COMPLETE case.
If the lower-level 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. No code seems
to depend on this behavior, however.)
- 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.