mirror of
https://github.com/AuxXxilium/linux_dsm_epyc7002.git
synced 2024-11-30 10:16:41 +07:00
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: Bartlomiej Zolnierkiewicz <bzolnier@gmail.com>
This commit is contained in:
parent
ae86afaee6
commit
efe0397eef
@ -742,12 +742,12 @@ void do_ide_request(struct request_queue *q)
|
|||||||
* set nIEN for previous port, drives in the
|
* set nIEN for previous port, drives in the
|
||||||
* quirk_list may not like intr setups/cleanups
|
* 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);
|
prev_port->tp_ops->set_irq(prev_port, 0);
|
||||||
|
|
||||||
hwif->host->cur_port = hwif;
|
hwif->host->cur_port = hwif;
|
||||||
}
|
}
|
||||||
hwgroup->drive = drive;
|
hwgroup->cur_dev = drive;
|
||||||
drive->dev_flags &= ~(IDE_DFLAG_SLEEPING | IDE_DFLAG_PARKED);
|
drive->dev_flags &= ~(IDE_DFLAG_SLEEPING | IDE_DFLAG_PARKED);
|
||||||
|
|
||||||
spin_unlock_irq(&hwgroup->lock);
|
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.
|
* Either way, we don't really want to complain about anything.
|
||||||
*/
|
*/
|
||||||
} else {
|
} else {
|
||||||
drive = hwgroup->drive;
|
drive = hwgroup->cur_dev;
|
||||||
if (!drive) {
|
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;
|
hwgroup->handler = NULL;
|
||||||
} else {
|
} else {
|
||||||
ide_hwif_t *hwif;
|
ide_hwif_t *hwif;
|
||||||
@ -1033,7 +1033,7 @@ static void unexpected_intr(int irq, ide_hwif_t *hwif)
|
|||||||
* places
|
* places
|
||||||
*
|
*
|
||||||
* hwif is the interface in the group currently performing
|
* 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
|
* the IRQ handler to call. As we issue a command the handlers
|
||||||
* step through multiple states, reassigning the handler to the
|
* step through multiple states, reassigning the handler to the
|
||||||
* next step in the process. Unlike a smart SCSI controller IDE
|
* 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;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
drive = hwgroup->drive;
|
drive = hwgroup->cur_dev;
|
||||||
if (!drive) {
|
if (!drive) {
|
||||||
/*
|
/*
|
||||||
* This should NEVER happen, and there isn't much
|
* This should NEVER happen, and there isn't much
|
||||||
|
@ -918,27 +918,9 @@ static int ide_init_queue(ide_drive_t *drive)
|
|||||||
return 0;
|
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:
|
* For any present drive:
|
||||||
* - allocate the block device queue
|
* - allocate the block device queue
|
||||||
* - link drive into the hwgroup
|
|
||||||
*/
|
*/
|
||||||
static int ide_port_setup_devices(ide_hwif_t *hwif)
|
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++;
|
j++;
|
||||||
|
|
||||||
ide_add_drive_to_hwgroup(drive);
|
|
||||||
}
|
}
|
||||||
mutex_unlock(&ide_cfg_mtx);
|
mutex_unlock(&ide_cfg_mtx);
|
||||||
|
|
||||||
@ -978,33 +958,9 @@ void ide_remove_port_from_hwgroup(ide_hwif_t *hwif)
|
|||||||
ide_ports[hwif->index] = NULL;
|
ide_ports[hwif->index] = NULL;
|
||||||
|
|
||||||
spin_lock_irq(&hwgroup->lock);
|
spin_lock_irq(&hwgroup->lock);
|
||||||
/*
|
/* Free the hwgroup if we were the only member. */
|
||||||
* Remove us from the hwgroup, and free
|
if (--hwgroup->port_count == 0)
|
||||||
* the hwgroup if we were the only member
|
|
||||||
*/
|
|
||||||
if (hwif->next == hwif) {
|
|
||||||
BUG_ON(hwgroup->hwif != hwif);
|
|
||||||
kfree(hwgroup);
|
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);
|
spin_unlock_irq(&hwgroup->lock);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1044,20 +1000,9 @@ static int init_irq (ide_hwif_t *hwif)
|
|||||||
if (match) {
|
if (match) {
|
||||||
hwgroup = match->hwgroup;
|
hwgroup = match->hwgroup;
|
||||||
hwif->hwgroup = 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);
|
spin_lock_irq(&hwgroup->lock);
|
||||||
hwif->next = hwgroup->hwif->next;
|
hwgroup->port_count++;
|
||||||
hwgroup->hwif->next = hwif;
|
|
||||||
BUG_ON(hwif->next == hwif);
|
|
||||||
spin_unlock_irq(&hwgroup->lock);
|
spin_unlock_irq(&hwgroup->lock);
|
||||||
} else {
|
} else {
|
||||||
hwgroup = kmalloc_node(sizeof(*hwgroup), GFP_KERNEL|__GFP_ZERO,
|
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);
|
spin_lock_init(&hwgroup->lock);
|
||||||
|
|
||||||
hwif->hwgroup = hwgroup;
|
hwif->hwgroup = hwgroup;
|
||||||
hwgroup->hwif = hwif->next = hwif;
|
|
||||||
|
hwgroup->port_count = 1;
|
||||||
|
|
||||||
init_timer(&hwgroup->timer);
|
init_timer(&hwgroup->timer);
|
||||||
hwgroup->timer.function = &ide_timer_expiry;
|
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);
|
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)
|
static void drive_release_dev (struct device *dev)
|
||||||
{
|
{
|
||||||
ide_drive_t *drive = container_of(dev, ide_drive_t, gendev);
|
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);
|
ide_proc_unregister_device(drive);
|
||||||
|
|
||||||
spin_lock_irq(&hwgroup->lock);
|
spin_lock_irq(&hwgroup->lock);
|
||||||
ide_remove_drive_from_hwgroup(drive);
|
|
||||||
kfree(drive->id);
|
kfree(drive->id);
|
||||||
drive->id = NULL;
|
drive->id = NULL;
|
||||||
drive->dev_flags &= ~IDE_DFLAG_PRESENT;
|
drive->dev_flags &= ~IDE_DFLAG_PRESENT;
|
||||||
|
@ -588,7 +588,6 @@ struct ide_drive_s {
|
|||||||
struct request_queue *queue; /* request queue */
|
struct request_queue *queue; /* request queue */
|
||||||
|
|
||||||
struct request *rq; /* current request */
|
struct request *rq; /* current request */
|
||||||
struct ide_drive_s *next; /* circular list of hwgroup drives */
|
|
||||||
void *driver_data; /* extra driver data */
|
void *driver_data; /* extra driver data */
|
||||||
u16 *id; /* identification info */
|
u16 *id; /* identification info */
|
||||||
#ifdef CONFIG_IDE_PROC_FS
|
#ifdef CONFIG_IDE_PROC_FS
|
||||||
@ -750,7 +749,6 @@ struct ide_dma_ops {
|
|||||||
struct ide_host;
|
struct ide_host;
|
||||||
|
|
||||||
typedef struct hwif_s {
|
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 hwif_s *mate; /* other hwif from same PCI chip */
|
||||||
struct hwgroup_s *hwgroup; /* actually (ide_hwgroup_t *) */
|
struct hwgroup_s *hwgroup; /* actually (ide_hwgroup_t *) */
|
||||||
struct proc_dir_entry *proc; /* /proc/ide/ directory entry */
|
struct proc_dir_entry *proc; /* /proc/ide/ directory entry */
|
||||||
@ -874,9 +872,7 @@ typedef struct hwgroup_s {
|
|||||||
unsigned int polling : 1;
|
unsigned int polling : 1;
|
||||||
|
|
||||||
/* current drive */
|
/* current drive */
|
||||||
ide_drive_t *drive;
|
ide_drive_t *cur_dev;
|
||||||
/* ptr to current hwif in linked-list */
|
|
||||||
ide_hwif_t *hwif;
|
|
||||||
|
|
||||||
/* current request */
|
/* current request */
|
||||||
struct request *rq;
|
struct request *rq;
|
||||||
@ -892,6 +888,8 @@ typedef struct hwgroup_s {
|
|||||||
int req_gen_timer;
|
int req_gen_timer;
|
||||||
|
|
||||||
spinlock_t lock;
|
spinlock_t lock;
|
||||||
|
|
||||||
|
int port_count;
|
||||||
} ide_hwgroup_t;
|
} ide_hwgroup_t;
|
||||||
|
|
||||||
typedef struct ide_driver_s ide_driver_t;
|
typedef struct ide_driver_s ide_driver_t;
|
||||||
@ -1622,12 +1620,7 @@ extern struct mutex ide_cfg_mtx;
|
|||||||
/*
|
/*
|
||||||
* Structure locking:
|
* 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->busy: hwgroup->lock
|
||||||
* ide_hwgroup_t->hwif: hwgroup->lock
|
|
||||||
* ide_hwif_t->{hwgroup,mate}: constant, no locking
|
* ide_hwif_t->{hwgroup,mate}: constant, no locking
|
||||||
* ide_drive_t->hwif: constant, no locking
|
* ide_drive_t->hwif: constant, no locking
|
||||||
*/
|
*/
|
||||||
|
Loading…
Reference in New Issue
Block a user