* set nIEN for previous port, drives in the
                         * quirk_list may not like intr setups/cleanups
                         */
-                       if (prev_port && hwgroup->drive->quirk_list == 0)
+                       if (prev_port && hwgroup->cur_dev->quirk_list == 0)
                                prev_port->tp_ops->set_irq(prev_port, 0);
 
                        hwif->host->cur_port = hwif;
                }
-               hwgroup->drive = drive;
+               hwgroup->cur_dev = drive;
                drive->dev_flags &= ~(IDE_DFLAG_SLEEPING | IDE_DFLAG_PARKED);
 
                spin_unlock_irq(&hwgroup->lock);
                 * Either way, we don't really want to complain about anything.
                 */
        } else {
-               drive = hwgroup->drive;
+               drive = hwgroup->cur_dev;
                if (!drive) {
-                       printk(KERN_ERR "ide_timer_expiry: hwgroup->drive was NULL\n");
+                       printk(KERN_ERR "%s: ->cur_dev was NULL\n", __func__);
                        hwgroup->handler = NULL;
                } else {
                        ide_hwif_t *hwif;
  *     places
  *
  *     hwif is the interface in the group currently performing
- *     a command. hwgroup->drive is the drive and hwgroup->handler is
+ *     a command. hwgroup->cur_dev is the drive and hwgroup->handler is
  *     the IRQ handler to call. As we issue a command the handlers
  *     step through multiple states, reassigning the handler to the
  *     next step in the process. Unlike a smart SCSI controller IDE
                goto out;
        }
 
-       drive = hwgroup->drive;
+       drive = hwgroup->cur_dev;
        if (!drive) {
                /*
                 * This should NEVER happen, and there isn't much
 
        return 0;
 }
 
-static void ide_add_drive_to_hwgroup(ide_drive_t *drive)
-{
-       ide_hwgroup_t *hwgroup = drive->hwif->hwgroup;
-
-       spin_lock_irq(&hwgroup->lock);
-       if (!hwgroup->drive) {
-               /* first drive for hwgroup. */
-               drive->next = drive;
-               hwgroup->drive = drive;
-               hwgroup->hwif = HWIF(hwgroup->drive);
-       } else {
-               drive->next = hwgroup->drive->next;
-               hwgroup->drive->next = drive;
-       }
-       spin_unlock_irq(&hwgroup->lock);
-}
-
 /*
  * For any present drive:
  * - allocate the block device queue
- * - link drive into the hwgroup
  */
 static int ide_port_setup_devices(ide_hwif_t *hwif)
 {
                }
 
                j++;
-
-               ide_add_drive_to_hwgroup(drive);
        }
        mutex_unlock(&ide_cfg_mtx);
 
        ide_ports[hwif->index] = NULL;
 
        spin_lock_irq(&hwgroup->lock);
-       /*
-        * Remove us from the hwgroup, and free
-        * the hwgroup if we were the only member
-        */
-       if (hwif->next == hwif) {
-               BUG_ON(hwgroup->hwif != hwif);
+       /* Free the hwgroup if we were the only member. */
+       if (--hwgroup->port_count == 0)
                kfree(hwgroup);
-       } else {
-               /* There is another interface in hwgroup.
-                * Unlink us, and set hwgroup->drive and ->hwif to
-                * something sane.
-                */
-               ide_hwif_t *g = hwgroup->hwif;
-
-               while (g->next != hwif)
-                       g = g->next;
-               g->next = hwif->next;
-               if (hwgroup->hwif == hwif) {
-                       /* Chose a random hwif for hwgroup->hwif.
-                        * It's guaranteed that there are no drives
-                        * left in the hwgroup.
-                        */
-                       BUG_ON(hwgroup->drive != NULL);
-                       hwgroup->hwif = g;
-               }
-               BUG_ON(hwgroup->hwif == hwif);
-       }
        spin_unlock_irq(&hwgroup->lock);
 }
 
        if (match) {
                hwgroup = match->hwgroup;
                hwif->hwgroup = hwgroup;
-               /*
-                * Link us into the hwgroup.
-                * This must be done early, do ensure that unexpected_intr
-                * can find the hwif and prevent irq storms.
-                * No drives are attached to the new hwif, choose_drive
-                * can't do anything stupid (yet).
-                * Add ourself as the 2nd entry to the hwgroup->hwif
-                * linked list, the first entry is the hwif that owns
-                * hwgroup->handler - do not change that.
-                */
+
                spin_lock_irq(&hwgroup->lock);
-               hwif->next = hwgroup->hwif->next;
-               hwgroup->hwif->next = hwif;
-               BUG_ON(hwif->next == hwif);
+               hwgroup->port_count++;
                spin_unlock_irq(&hwgroup->lock);
        } else {
                hwgroup = kmalloc_node(sizeof(*hwgroup), GFP_KERNEL|__GFP_ZERO,
                spin_lock_init(&hwgroup->lock);
 
                hwif->hwgroup = hwgroup;
-               hwgroup->hwif = hwif->next = hwif;
+
+               hwgroup->port_count = 1;
 
                init_timer(&hwgroup->timer);
                hwgroup->timer.function = &ide_timer_expiry;
 
 EXPORT_SYMBOL_GPL(ide_init_disk);
 
-static void ide_remove_drive_from_hwgroup(ide_drive_t *drive)
-{
-       ide_hwgroup_t *hwgroup = drive->hwif->hwgroup;
-
-       if (drive == drive->next) {
-               /* special case: last drive from hwgroup. */
-               BUG_ON(hwgroup->drive != drive);
-               hwgroup->drive = NULL;
-       } else {
-               ide_drive_t *walk;
-
-               walk = hwgroup->drive;
-               while (walk->next != drive)
-                       walk = walk->next;
-               walk->next = drive->next;
-               if (hwgroup->drive == drive) {
-                       hwgroup->drive = drive->next;
-                       hwgroup->hwif = hwgroup->drive->hwif;
-               }
-       }
-       BUG_ON(hwgroup->drive == drive);
-}
-
 static void drive_release_dev (struct device *dev)
 {
        ide_drive_t *drive = container_of(dev, ide_drive_t, gendev);
        ide_proc_unregister_device(drive);
 
        spin_lock_irq(&hwgroup->lock);
-       ide_remove_drive_from_hwgroup(drive);
        kfree(drive->id);
        drive->id = NULL;
        drive->dev_flags &= ~IDE_DFLAG_PRESENT;
 
        struct request_queue    *queue; /* request queue */
 
        struct request          *rq;    /* current request */
-       struct ide_drive_s      *next;  /* circular list of hwgroup drives */
        void            *driver_data;   /* extra driver data */
        u16                     *id;    /* identification info */
 #ifdef CONFIG_IDE_PROC_FS
 struct ide_host;
 
 typedef struct hwif_s {
-       struct hwif_s *next;            /* for linked-list in ide_hwgroup_t */
        struct hwif_s *mate;            /* other hwif from same PCI chip */
        struct hwgroup_s *hwgroup;      /* actually (ide_hwgroup_t *) */
        struct proc_dir_entry *proc;    /* /proc/ide/ directory entry */
        unsigned int polling    : 1;
 
                /* current drive */
-       ide_drive_t *drive;
-               /* ptr to current hwif in linked-list */
-       ide_hwif_t *hwif;
+       ide_drive_t *cur_dev;
 
                /* current request */
        struct request *rq;
        int req_gen_timer;
 
        spinlock_t lock;
+
+       int port_count;
 } ide_hwgroup_t;
 
 typedef struct ide_driver_s ide_driver_t;
 /*
  * Structure locking:
  *
- * ide_cfg_mtx and hwgroup->lock together protect changes to
- * ide_hwif_t->next
- * ide_drive_t->next
- *
  * ide_hwgroup_t->busy: hwgroup->lock
- * ide_hwgroup_t->hwif: hwgroup->lock
  * ide_hwif_t->{hwgroup,mate}: constant, no locking
  * ide_drive_t->hwif: constant, no locking
  */