Commit Graph

216 Commits

Author SHA1 Message Date
bouyer c31b572a47 Allow polled commands to be queued, if ata_exec_xfer() is called in thread
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.
2004-10-30 23:10:37 +00:00
bouyer 235e7412c1 Revert 1.215, with a comment explaining why we can't use interrupts here. 2004-10-30 17:17:21 +00:00
bouyer 01d27a59a7 wdc_drvprobe(): don't poll for the IDENTIFY, use interrupts. There's no
reasons to not use interrupts here, and polling cause problems when there is
a shared queue between 2 channels.
Fix kern/27421 by Martin Husemann.
2004-10-26 21:21:59 +00:00
enami 63a896d5a8 Fill some entry in fake wdc_ata_bustype since those are called even
if no wd(4) device is configured in a kernel.
2004-10-25 22:42:09 +00:00
thorpej 218dbb60a6 Make some functions referenced only in wdc.c private to that file. 2004-08-21 01:51:46 +00:00
thorpej 335b799580 atastart() (called only at splbio(), and from interrupts) can change
drive_flags, to make sure all drive_flags manipulations are done at
splbio().
2004-08-21 00:28:34 +00:00
thorpej e975b9caee - Add an (*ata_reset_channel)() member to ata_bustype.
- 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!
2004-08-20 23:26:53 +00:00
thorpej 56e2a255b5 Move common parts of attaching an ata_channel to a new ata_channel_attach()
function.
2004-08-20 22:17:06 +00:00
thorpej 3234a02f48 Move atabusconfig() to ata.c. 2004-08-20 22:02:40 +00:00
thorpej 2606542c7b - Add an atac_bustype_ata member to atac_softc to hold a pointer to
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.
2004-08-20 20:52:31 +00:00
thorpej 9cc521a148 Move most of wdc_softc into a new atac_softc structure that contains
info common to all types of ATA controllers.
2004-08-20 06:39:37 +00:00
thorpej 1600c8b8cd - Add and use a CHAN_TO_WDC() macro to get the wdc_softc from an
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.)
2004-08-19 23:25:35 +00:00
thorpej 4b51cecfc2 - Split the register handles out of struct wdc_channel into a separate
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.
2004-08-14 15:08:04 +00:00
thorpej 46f4277564 WDCDEBUG -> ATADEBUG. 2004-08-13 04:10:49 +00:00
thorpej ab20886f7b Don't bother with bits that tell of the presence of optional callbacks;
just check the function pointers for NULL.
2004-08-13 03:12:59 +00:00
thorpej 577bf67014 Move wdcstart() to ata.c and rename it to atastart(). 2004-08-13 02:16:40 +00:00
thorpej 996c3ca90e Move wdc_exec_xfer() to ata.c and rename it ata_exec_xfer(). 2004-08-13 02:10:43 +00:00
thorpej e6d61c5bc9 Move wdc_addref() and wdc_delref() to ata.c and rename them to
ata_*.
2004-08-12 22:39:40 +00:00
thorpej 2eaa5c6142 Move wdc_kill_pending() to ata.c and rename it ata_kill_pending(). 2004-08-12 22:33:45 +00:00
thorpej 2600c55e01 - Move wdc_xfer_pool, wdc_get_xfer(), wdc_free_xfer() to ata.c, and rename
to ata_*.
- Use a static initializer for the ata_xfer_pool.
2004-08-12 21:34:52 +00:00
thorpej 52ed169a28 Move wdc_probe_caps() to ata.c and rename it ata_probe_caps(). 2004-08-12 21:10:18 +00:00
thorpej ac7276784a Move wdc_downgrade_mode() to ata.c and rename it to ata_downgrade_mode(). 2004-08-12 21:05:09 +00:00
thorpej 9939d3c63d Move wdc_print_modes() into ata.c and rename it ata_print_modes(). 2004-08-12 20:59:27 +00:00
mycroft 849d423c4e Whoops. Swap the order of the delref() and the config_pending_decr(). 2004-08-12 14:36:46 +00:00
thorpej 9167731c79 Rename some constants:
WDC_COMPLETE -> ATACMD_COMPLETE
WDC_QUEUED -> ATACMD_QUEUED
WDC_TRY_AGAIN -> ATACMD_TRY_AGAIN
2004-08-12 05:02:50 +00:00
thorpej 3ddac9b2da Rename "struct wdc_command" to "struct ata_command". 2004-08-12 04:57:19 +00:00
mycroft 6741190fbc Make datain_pio and dataout_pio function pointers in wdc_softc, which can
be overridden by the backend if desired.  Add experimental code to wdc_pcmcia
to use this in memory-mapped mode, disabled by default.
2004-08-11 18:41:46 +00:00
mycroft 04a46876e5 Add two helper functions -- wdc_datain_pio() and wdc_dataout_pio() -- which
encapsulate the logic for the various methods of transferring data.  Use these
throughout.
2004-08-11 17:49:27 +00:00
mycroft 32dee96c25 Hold a reference between atabus_attach() and atabusconfig() to avoid an extra
enable/disable cycle.  Now my CF card attaches a bit faster.

XXX This code is split strangely between files.
2004-08-10 23:09:38 +00:00
mycroft dc594b03f9 Be robust against the case of the child devices failing to decrement the
refcnt.
2004-08-10 02:40:51 +00:00
bouyer 1f5d4dd9dd Change wdc_kill_pending() to take a struct ata_drive_datas * as argument,
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.
2004-08-04 22:44:04 +00:00
bouyer 9b0cc941a3 Add
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.
2004-08-04 18:24:10 +00:00
bouyer 73203a8277 Make it possible for (*dma_finish)() to abort quietly a DMA op. Use this
in wdc_reset_channel().
2004-08-02 22:20:54 +00:00
bouyer 495631e4d6 Clean up interraction between wdc_reset_channel and the kernel thread.
Move kill_xfer() after the reset, and stop the DMA engine if needed
(this will unload the DMA maps).
2004-08-02 22:02:35 +00:00
bouyer 011181ac3e Implement an atabus control device, and define some ATA bus control
IOCTLS. Implement ATABUSIORESET, which will reset the given ATA bus.
2004-08-01 21:40:41 +00:00
bouyer 7ffa35d1a2 Implement asynchronous channel reset.
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.
2004-07-31 21:26:42 +00:00
bouyer 5a33ee9f49 For now, remove the ATAPI_SOFT_RESET done at attach time. I added this to get a
IBM pcmcia external cdrom drive working, but it cause troubles for others
IDE/ATAPI devices. Need to find another way to get this IBM drive to probe.
2004-06-23 21:10:52 +00:00
mycroft a4135d1d48 Only downgrade modes due to an actual CRC error. Downgrading on other errors
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.
2004-06-01 19:32:30 +00:00
mycroft 0a5a28eeae Write the registers in the proscribed order -- sector,cyllo,cylhi (LSB first
for LBA).  This make no difference with real devices, but the funky IDE
analyzer can't search properly if the order is wrong.
2004-05-27 16:47:35 +00:00
thorpej aeb454bce4 Clean-up of use of "precomp". It is used as "features" everywhere, so
rename the fields in wdc_command as appropriate.
2004-05-27 02:23:12 +00:00
thorpej 46986953d0 In wdcccommand(), load wd_features, not wd_precomp, with the features
provided by callers.

From Jordan Rhody @ Wasabi.
2004-05-27 02:09:26 +00:00
thorpej 2ecdd552dc Add the notion of "shadow registers" to the wdc driver. These shadow
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.
2004-05-25 20:42:40 +00:00
bouyer 5c594e4cc4 Add a delay(5000) between the ATAPI_SOFT_RESET and the channel reset.
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.
2004-05-24 20:45:30 +00:00
bouyer bf4920bc20 In wdcprobe1(), protect the register writability test with splbio().
What we do here seems to trigger interrupts on some pcmcia adapters, which
cause the kernel to hang.
Add some WDCDEBUG_PRINT((), DEBUG_PROBE).
Avoid touching registers of nonexistent drives, once we know which drive is
or is not here.

This makes the "IBM PCMCIA Portable CD-ROM Drive" (external CD drive with
PCMCIA adapter) work.
2004-05-15 17:15:09 +00:00
bouyer 879d21cebe Add a delay(10) after re-enabling interrupts in the control register.
Some controllers/drives (e.g. SataLink 3114 with WD Raptor) require
it. Should fix kern/23808 by Chris Gilbert, patch suplied by Chris Gilbert
on tech-kern, extended to all places enabling interrupts by me.
2004-05-08 15:03:32 +00:00
bouyer 27e1cb0c55 Deassert RST before re-enabling interrupts. Some drives (or controller)
require it.
From Michael van Elst in kern/24904.
2004-03-25 19:45:09 +00:00
thorpej cb9ba8776e Add a comment about some code that should be cleaned up. 2004-01-07 22:03:56 +00:00
thorpej 197f2f50da More structure member namespace cleanup: thread -> ch_thread 2004-01-03 23:59:58 +00:00
thorpej a963286f8d More wdc_channel structure member namespace cleanup:
- channel -> ch_channel
- wdc -> ch_wdc
2004-01-03 22:56:52 +00:00
thorpej 5bd80d8373 Rename "struct channel_softc" to "struct wdc_channel". 2004-01-03 01:50:52 +00:00