1) because the CS5536 is not associated with a x86 CPU, interrupts are not
ack'ed as it expects so interrupts cannot configured as edge-triggered
(as is expected for a PCIIDE in compat mode)
2) the PATA->SATA bridge ignores the WDC_IDS (interrupt disable bit) so
the PATA IRQ line gets asserted when resetting or running some polled
commands. It also wrongly asserts IRQ when the (nonexistent) slave
device is selected
2) wouldn't be an issue with edge-triggered interrupt because we would
get a spurious interrupt and continue operation, a new interrupt only shows
up when the PATA IRQ line goes low and high again. But because of 1),
we get an unclearable interrupt instead, and the system loops on the
interrupt handler.
To workaround this, introduce a WDC_NO_IDS compile option which runs
all polled commands (including reset) at splbio() and without sleeps,
so that the controller's interrupt is effectively disabled and
won't be reenabled before the interrupt can be cleared.
The conditions triggering this problem are speficic enough to handle
this via a compile-time option; no need for a run-time (e.g. a
config(9), device property or callback to disable interrupts) solution.
we can't use it here. Rssurect ATACH_TH_RUN, backing out
src/sys/dev/ata/ata.c 1.101
src/sys/dev/ata/ata_wdc.c 1.90
src/sys/dev/ata/atavar.h 1.77
src/sys/dev/ic/wdc.c 1.255
src/sys/dev/scsipi/atapi_wdc.c 1.108
Should fix kern/39927 and kern/39725.
The PIOBM is used by only one driver (will be added later,
stay tuned) and intruduce an attribute "ata_piobm" so that
it will be conditionally compiled in.
The "ata_dma" (busmastering transfer using ATA DMA mode) and
"ata_udma" (busmastering transfer using ATA Ultra DMA mode)
attributes are also added for consistency, but unused for now.
returns EINVAL, indicating that DMA cannot be done for this transfer.
Fall back to PIO in this case.
- Add a geodeide_dma_init() routine that checks to make sure that transfers
start on a 16 byte boundary, returning EINVAL if not. Works around a chip
bug that causes a hard system hang.
Problem reported and patch tested by Erik Fair.
- 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!
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.
just have to take an interrupt for each sector.
Tested with one laptop disk (which normally runs in DMA mode and was forced
to single-sector transfers) and 3 CF cards. Increases the performance of
the CF cards substantially (760KB/s->1240KB/s in one case, 410KB/s->750KB/s
in the other two cases).
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.
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.
the drive. This fixes (or rather, works around) a timing problem
with WD Raptor drives attached to a Sil3114 SATA controller.
Should fix PR 23808, it fixes the same problem for me.
- wdc_xfer to ata_xfer
- channel_queue to ata_queue
and move them to <dev/ata/atavar.h> so they can be used by non-wdc ATA
controllers. Clean up the member names of these structures while at it.