pcmcia devices, the drive may still be doing its power-on reset.
XXX From the specs the delay could be up to 31s here, but we don't want to
wait for 31s if we have a channel with no drives and pull-up resitors on
the bus.
Based on patch submitted in kern/25659 by Steven M. Bellovin, part of fix for
kern/25659.
context. For this introduce 3 new xfer tags:
- C_WAIT, equivalent of AT_WAIT
- C_WAITACT, when there is a thread waiting on this xfer to become the active
one (that is, to be at the head of the queue)
- C_FREE, set by ata_free_xfer() when it can't free the xfer because it's
still in use. The holder should then free the xfer ASAP.
If ata_exec_xfer() is called with (C_POLL | C_WAIT), and there is already
xfers to be processed, assert C_WAITACT and sleep.
atastart() checks for C_WAITACT, and wakeup the thread waiting for this xfer
to become active if set. atastart() won't process this xfer, it's the
responsability of the thread waked up to handle it.
Fix (the right way) kern/27421 by Martin Husemann.
- Add an ata_reset_channel() function that performs the common parts
of resetting an ATA channel, which uses the (*ata_reset_channel)()
callback to do the heavy lifting. Adjust callers to use ata_reset_channel()
instead of wdc_reset_channel().
This removes the last wdc-specific code from ata.c!
the ata_bustype for the controller. Fill it in and use it instead
of referencing wdc_ata_bustype directly.
- Add an atac_atapibus_attach member to atac_softc to hold a pointer
to the function that attaches the ATAPI bus for the controller. Fill
it in and use it instead of referencing wdc_atapibus_attach directly.
ata_channel.
- Add and use a CHAN_TO_WDC_REGS() macro to get the wdc_regs from an
ata_channel.
- Add and use a CHAN_TO_PCIIDE() macro to get the pciide_softc from an
ata_channel.
- Add and use a CHAN_TO_PCHAN() macro to get the pciide_channel from an
ata_channel. (This one just hides a cast, and is really just for
consistency with the others.)
wdc_regs structure, and array of which (indexed per channel) is pointed
to by struct wdc_softc.
- Move the resulting wdc_channel structure to atavar.h and rename it to
ata_channel. Rename the corresponding flags.
- Add a "ch_ndrive" member to struct ata_channel, which indicates the
maximum number of drives that can be present on the channel. For now,
this is always 2. Add an ATA_MAXDRIVES constant that places an upper
limit on this value, also currently 2.
and kill only pending requests for this drive.
Implement a DRIVE_WAITDRAIN flag, which will cause the active command to
be killed once complete.
Other minor fixes.
Now it's possible to detach a ATA or ATAPI device from ioctl even when
a dd on the raw char partition is running.
struct ata_xfer *active_xfer
to ata_queue. Now the active xfer isn't the head of the queue any more,
this makes a few things easier (this will also help for tagged queuing
support).
Remove the WDCF_ACTIVE flag, test active_xfer != NULL instead.
clean up wdc_free_xfer() and kill_xfer().
Clean up wdc_reset_channel(), and make it issue a ATAPI_SOFT_RESET if the
active command is ATAPI.
In wdc_atapi_get_params(), use AT_WAIT | AT_POLL for ATAPI_SOFT_RESET,
so that we'll use tsleep() instead of delay().
In wdc_atapi_start(), call wdc_dmawait() at the right place.
Use this to reset the channel before doing a dump, instead of the hack in
wdc_exec_xfer() based on C_POLL. This hack was causing problems on
controllers with a shared queue, because we now can have C_POLL set during
concurent channels probes (problem found and analysed on sparc64 by
Martin Husemann).
This should even make core dumps marginally more reliable on ATA drives.
is anti-social -- especially given that there's no way to upgrade again short
of rebooting.
Also, downgrade UDMA modes more slowly. It's entirely possible that they're
using an 80-wire cable, but it's just too long for the higher modes, or there
is minor crosstalk.
registers are registers that overlap with others on many controllers, but
which may actually be distinct on some controllers. Right now, the two
shadows are:
- wd_status (usually overlaps wd_command)
- wd_features (usually overlaps wd_error)
Add a new helper function, wdc_init_shadow_regs(), used to initialize
the shadow register handles on controllers where they do actually overlap.
Partially from Jordan Rhody @ Wasabi Systems, Inc.
Some ATAPI device never get out of busy if touched too fast after a reset.
Delay value from atapi_wdc.c; fix problem reported by Nicolas Joly on
current-users.