void ata_dev_init(struct ata_device *dev)
 {
        struct ata_port *ap = dev->ap;
+       unsigned long flags;
+
+       /* High bits of dev->flags are used to record warm plug
+        * requests which occur asynchronously.  Synchronize using
+        * host_set lock.
+        */
+       spin_lock_irqsave(&ap->host_set->lock, flags);
+       dev->flags &= ~ATA_DFLAG_INIT_MASK;
+       spin_unlock_irqrestore(&ap->host_set->lock, flags);
 
-       memset((void *)dev, 0, sizeof(*dev));
-       dev->devno = dev - ap->device;
+       memset((void *)dev + ATA_DEVICE_CLEAR_OFFSET, 0,
+              sizeof(*dev) - ATA_DEVICE_CLEAR_OFFSET);
        dev->pio_mask = UINT_MAX;
        dev->mwdma_mask = UINT_MAX;
        dev->udma_mask = UINT_MAX;
        for (i = 0; i < ATA_MAX_DEVICES; i++) {
                struct ata_device *dev = &ap->device[i];
                dev->ap = ap;
+               dev->devno = i;
                ata_dev_init(dev);
        }
 
 
        ATA_DFLAG_CFG_MASK      = (1 << 8) - 1,
 
        ATA_DFLAG_PIO           = (1 << 8), /* device currently in PIO mode */
+       ATA_DFLAG_INIT_MASK     = (1 << 16) - 1,
 
        ATA_DFLAG_DETACH        = (1 << 16),
        ATA_DFLAG_DETACHED      = (1 << 17),
 
 struct ata_device {
        struct ata_port         *ap;
-       u64                     n_sectors;      /* size of device, if ATA */
+       unsigned int            devno;          /* 0 or 1 */
        unsigned long           flags;          /* ATA_DFLAG_xxx */
+       /* n_sector is used as CLEAR_OFFSET, read comment above CLEAR_OFFSET */
+       u64                     n_sectors;      /* size of device, if ATA */
        unsigned int            class;          /* ATA_DEV_xxx */
-       unsigned int            devno;          /* 0 or 1 */
        u16                     id[ATA_ID_WORDS]; /* IDENTIFY xxx DEVICE data */
        u8                      pio_mode;
        u8                      dma_mode;
        struct ata_ering        ering;
 };
 
+/* Offset into struct ata_device.  Fields above it are maintained
+ * acress device init.  Fields below are zeroed.
+ */
+#define ATA_DEVICE_CLEAR_OFFSET                offsetof(struct ata_device, n_sectors)
+
 struct ata_eh_info {
        struct ata_device       *dev;           /* offending device */
        u32                     serror;         /* SError from LLDD */