Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit efe0397e authored by Bartlomiej Zolnierkiewicz's avatar Bartlomiej Zolnierkiewicz
Browse files

ide: remove hwgroup->hwif and {drive,hwif}->next



* Add 'int port_count' field to ide_hwgroup_t to keep the track
  of the number of ports in the hwgroup.  Then update init_irq()
  and ide_remove_port_from_hwgroup() to use it.

* Remove no longer needed hwgroup->hwif, {drive,hwif}->next,
  ide_add_drive_to_hwgroup() and ide_remove_drive_from_hwgroup()
  (hwgroup->drive now only denotes the currently active device
   in the hwgroup).

* Update locking documentation in <linux/ide.h>.

While at it:

* Rename ->drive field in ide_hwgroup_t to ->cur_dev.

* Use __func__ in ide_timer_expiry().

Signed-off-by: default avatarBartlomiej Zolnierkiewicz <bzolnier@gmail.com>
parent ae86afae
Loading
Loading
Loading
Loading
+6 −6
Original line number Diff line number Diff line
@@ -742,12 +742,12 @@ void do_ide_request(struct request_queue *q)
			 * 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);
@@ -913,9 +913,9 @@ void ide_timer_expiry (unsigned long data)
		 * 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;
@@ -1033,7 +1033,7 @@ static void unexpected_intr(int irq, 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
@@ -1105,7 +1105,7 @@ irqreturn_t ide_intr (int irq, void *dev_id)
		goto out;
	}

	drive = hwgroup->drive;
	drive = hwgroup->cur_dev;
	if (!drive) {
		/*
		 * This should NEVER happen, and there isn't much
+6 −84
Original line number Diff line number Diff line
@@ -918,27 +918,9 @@ static int ide_init_queue(ide_drive_t *drive)
	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)
{
@@ -961,8 +943,6 @@ static int ide_port_setup_devices(ide_hwif_t *hwif)
		}

		j++;

		ide_add_drive_to_hwgroup(drive);
	}
	mutex_unlock(&ide_cfg_mtx);

@@ -978,33 +958,9 @@ void ide_remove_port_from_hwgroup(ide_hwif_t *hwif)
	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);
}

@@ -1044,20 +1000,9 @@ static int init_irq (ide_hwif_t *hwif)
	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,
@@ -1068,7 +1013,8 @@ static int init_irq (ide_hwif_t *hwif)
		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;
@@ -1191,29 +1137,6 @@ void ide_init_disk(struct gendisk *disk, ide_drive_t *drive)

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);
@@ -1222,7 +1145,6 @@ static void drive_release_dev (struct device *dev)
	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;
+3 −10
Original line number Diff line number Diff line
@@ -588,7 +588,6 @@ struct ide_drive_s {
	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
@@ -750,7 +749,6 @@ struct ide_dma_ops {
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 */
@@ -874,9 +872,7 @@ typedef struct hwgroup_s {
	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;
@@ -892,6 +888,8 @@ typedef struct hwgroup_s {
	int req_gen_timer;

	spinlock_t lock;

	int port_count;
} ide_hwgroup_t;

typedef struct ide_driver_s ide_driver_t;
@@ -1622,12 +1620,7 @@ extern struct mutex ide_cfg_mtx;
/*
 * 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
 */