This section discusses several important recovery actions.
Many controllers require its error registers to be cleared by error handler. Different controllers may have different requirements.
For SATA, it's strongly recommended to clear at least SError register during error handling.
During EH, resetting is necessary in the following cases.
HSM is in unknown or invalid state
HBA is in unknown or invalid state
EH needs to make HBA/device forget about in-flight commands
HBA/device behaves weirdly
Resetting during EH might be a good idea regardless of error condition to improve EH robustness. Whether to reset both or either one of HBA and device depends on situation but the following scheme is recommended.
When it's known that HBA is in ready state but ATA/ATAPI device is in unknown state, reset only device.
If HBA is in unknown state, reset both HBA and device.
HBA resetting is implementation specific. For a controller complying to taskfile/BMDMA PCI IDE, stopping active DMA transaction may be sufficient iff BMDMA state is the only HBA context. But even mostly taskfile/BMDMA PCI IDE complying controllers may have implementation specific requirements and mechanism to reset themselves. This must be addressed by specific drivers.
OTOH, ATA/ATAPI standard describes in detail ways to reset ATA/ATAPI devices.
This is hardware initiated device reset signalled with asserted PATA RESET- signal. There is no standard way to initiate hardware reset from software although some hardware provides registers that allow driver to directly tweak the RESET- signal.
This is achieved by turning CONTROL SRST bit on for at least 5us. Both PATA and SATA support it but, in case of SATA, this may require controller-specific support as the second Register FIS to clear SRST should be transmitted while BSY bit is still set. Note that on PATA, this resets both master and slave devices on a channel.
Although ATA/ATAPI standard doesn't describe exactly, EDD implies some level of resetting, possibly similar level with software reset. Host-side EDD protocol can be handled with normal command processing and most SATA controllers should be able to handle EDD's just like other commands. As in software reset, EDD affects both devices on a PATA bus.
Although EDD does reset devices, this doesn't suit error handling as EDD cannot be issued while BSY is set and it's unclear how it will act when device is in unknown/weird state.
This is very similar to software reset except that reset can be restricted to the selected device without affecting the other device sharing the cable.
This is the preferred way of resetting a SATA device. In effect, it's identical to PATA hardware reset. Note that this can be done with the standard SCR Control register. As such, it's usually easier to implement than software reset.
One more thing to consider when resetting devices is that resetting clears certain configuration parameters and they need to be set to their previous or newly adjusted values after reset.
Parameters affected are.
CHS set up with INITIALIZE DEVICE PARAMETERS (seldom used)
Parameters set with SET FEATURES including transfer mode setting
Block count set with SET MULTIPLE MODE
Other parameters (SET MAX, MEDIA LOCK...)
ATA/ATAPI standard specifies that some parameters must be maintained across hardware or software reset, but doesn't strictly specify all of them. Always reconfiguring needed parameters after reset is required for robustness. Note that this also applies when resuming from deep sleep (power-off).
Also, ATA/ATAPI standard requires that IDENTIFY DEVICE / IDENTIFY PACKET DEVICE is issued after any configuration parameter is updated or a hardware reset and the result used for further operation. OS driver is required to implement revalidation mechanism to support this.
For both PATA and SATA, a lot of corners are cut for cheap connectors, cables or controllers and it's quite common to see high transmission error rate. This can be mitigated by lowering transmission speed.
The following is a possible scheme Jeff Garzik suggested.
If more than $N (3?) transmission errors happen in 15 minutes,
if SATA, decrease SATA PHY speed. if speed cannot be decreased,
decrease UDMA xfer speed. if at UDMA0, switch to PIO4,
decrease PIO xfer speed. if at PIO3, complain, but continue