unsigned int action)
 {
        unsigned long flags;
+       struct ata_eh_info *ehi = &ap->eh_info;
+       struct ata_eh_context *ehc = &ap->eh_context;
 
        spin_lock_irqsave(ap->lock, flags);
 
-       ata_eh_clear_action(dev, &ap->eh_info, action);
+       /* Reset is represented by combination of actions and EHI
+        * flags.  Suck in all related bits before clearing eh_info to
+        * avoid losing requested action.
+        */
+       if (action & ATA_EH_RESET_MASK) {
+               ehc->i.action |= ehi->action & ATA_EH_RESET_MASK;
+               ehc->i.flags |= ehi->flags & ATA_EHI_RESET_MODIFIER_MASK;
+
+               /* make sure all reset actions are cleared & clear EHI flags */
+               action |= ATA_EH_RESET_MASK;
+               ehi->flags &= ~ATA_EHI_RESET_MODIFIER_MASK;
+       }
+
+       ata_eh_clear_action(dev, ehi, action);
 
-       if (!(ap->eh_context.i.flags & ATA_EHI_QUIET))
+       if (!(ehc->i.flags & ATA_EHI_QUIET))
                ap->pflags |= ATA_PFLAG_RECOVERED;
 
        spin_unlock_irqrestore(ap->lock, flags);
 static void ata_eh_done(struct ata_port *ap, struct ata_device *dev,
                        unsigned int action)
 {
+       /* if reset is complete, clear all reset actions & reset modifier */
+       if (action & ATA_EH_RESET_MASK) {
+               action |= ATA_EH_RESET_MASK;
+               ap->eh_context.i.flags &= ~ATA_EHI_RESET_MODIFIER_MASK;
+       }
+
        ata_eh_clear_action(dev, &ap->eh_context.i, action);
 }
 
        ata_reset_fn_t reset;
        int i, did_followup_srst, rc;
 
+       /* about to reset */
+       ata_eh_about_to_do(ap, NULL, ehc->i.action & ATA_EH_RESET_MASK);
+
        /* Determine which reset to use and record in ehc->i.action.
         * prereset() may examine and modify it.
         */
                ata_port_printk(ap, KERN_INFO, "%s resetting port\n",
                                reset == softreset ? "soft" : "hard");
 
-       /* reset */
-       ata_eh_about_to_do(ap, NULL, ATA_EH_RESET_MASK);
+       /* mark that this EH session started with reset */
        ehc->i.flags |= ATA_EHI_DID_RESET;
 
        rc = ata_do_reset(ap, reset, classes);
                        postreset(ap, classes);
 
                /* reset successful, schedule revalidation */
-               ata_eh_done(ap, NULL, ATA_EH_RESET_MASK);
+               ata_eh_done(ap, NULL, ehc->i.action & ATA_EH_RESET_MASK);
                ehc->i.action |= ATA_EH_REVALIDATE;
        }
 
 
 
        /* ata_eh_info->flags */
        ATA_EHI_HOTPLUGGED      = (1 << 0),  /* could have been hotplugged */
-       ATA_EHI_RESUME_LINK     = (1 << 1),  /* need to resume link */
+       ATA_EHI_RESUME_LINK     = (1 << 1),  /* resume link (reset modifier) */
        ATA_EHI_NO_AUTOPSY      = (1 << 2),  /* no autopsy */
        ATA_EHI_QUIET           = (1 << 3),  /* be quiet */
 
        ATA_EHI_DID_RESET       = (1 << 16), /* already reset this port */
 
+       ATA_EHI_RESET_MODIFIER_MASK = ATA_EHI_RESUME_LINK,
+
        /* max repeat if error condition is still set after ->error_handler */
        ATA_EH_MAX_REPEAT       = 5,