return 0;
}
-static int ata_eh_followup_srst_needed(int rc, int classify,
- const unsigned int *classes)
+static int ata_eh_followup_srst_needed(struct ata_port *ap, int rc,
+ int classify, const unsigned int *classes)
{
+ if (ap->flags & ATA_FLAG_NO_SRST)
+ return 0;
if (rc == -EAGAIN)
return 1;
if (rc != 0)
*/
action = ehc->i.action;
ehc->i.action &= ~ATA_EH_RESET_MASK;
- if (softreset && (!hardreset || (!sata_set_spd_needed(ap) &&
+ if (softreset && (!hardreset || (!(ap->flags & ATA_FLAG_NO_SRST) &&
+ !sata_set_spd_needed(ap) &&
!(action & ATA_EH_HARDRESET))))
ehc->i.action |= ATA_EH_SOFTRESET;
else
rc = ata_do_reset(ap, reset, classes, deadline);
if (reset == hardreset &&
- ata_eh_followup_srst_needed(rc, classify, classes)) {
+ ata_eh_followup_srst_needed(ap, rc, classify, classes)) {
/* okay, let's do follow-up softreset */
reset = softreset;
ata_eh_about_to_do(ap, NULL, ATA_EH_RESET_MASK);
rc = ata_do_reset(ap, reset, classes, deadline);
- if (rc == 0 && classify &&
- classes[0] == ATA_DEV_UNKNOWN) {
+ if (rc == 0 && classify && classes[0] == ATA_DEV_UNKNOWN &&
+ !(ap->flags & ATA_FLAG_ASSUME_ATA)) {
ata_port_printk(ap, KERN_ERR,
"classification failed\n");
rc = -EINVAL;
}
}
+ /* if we skipped follow-up srst, clear rc */
+ if (rc == -EAGAIN)
+ rc = 0;
+
if (rc && try < ARRAY_SIZE(ata_eh_reset_timeouts)) {
unsigned long now = jiffies;
/* After the reset, the device state is PIO 0 and the
* controller state is undefined. Record the mode.
*/
- for (i = 0; i < ATA_MAX_DEVICES; i++)
- ap->device[i].pio_mode = XFER_PIO_0;
+ for (i = 0; i < ata_port_max_devices(ap); i++) {
+ struct ata_device *dev = &ap->device[i];
+
+ dev->pio_mode = XFER_PIO_0;
+
+ if (ata_port_offline(ap))
+ continue;
+
+ if (ap->flags & ATA_FLAG_ASSUME_ATA)
+ classes[dev->devno] = ATA_DEV_ATA;
+ }
/* record current link speed */
if (sata_scr_read(ap, SCR_STATUS, &sstatus) == 0)
ATA_FLAG_IGN_SIMPLEX = (1 << 15), /* ignore SIMPLEX */
ATA_FLAG_NO_IORDY = (1 << 16), /* controller lacks iordy */
ATA_FLAG_ACPI_SATA = (1 << 17), /* need native SATA ACPI layout */
+ ATA_FLAG_NO_SRST = (1 << 18),
+ ATA_FLAG_ASSUME_ATA = (1 << 19),
/* The following flag belongs to ap->pflags but is kept in
* ap->flags because it's referenced in many LLDs and will be