diff options
author | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2009-01-06 11:20:49 -0500 |
---|---|---|
committer | Bartlomiej Zolnierkiewicz <bzolnier@gmail.com> | 2009-01-06 11:20:49 -0500 |
commit | efe0397eef544ac4bcca23d39aa8d5db154952e0 (patch) | |
tree | 25418872f1a813d3fd15237dad67797d93aa8ad3 /drivers/ide | |
parent | ae86afaee6a1c77c7a06d81dcc3bf872204d3bec (diff) |
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>
Diffstat (limited to 'drivers/ide')
-rw-r--r-- | drivers/ide/ide-io.c | 12 | ||||
-rw-r--r-- | drivers/ide/ide-probe.c | 90 |
2 files changed, 12 insertions, 90 deletions
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c index 1fc739f44154..4ce793c05629 100644 --- a/drivers/ide/ide-io.c +++ b/drivers/ide/ide-io.c | |||
@@ -742,12 +742,12 @@ repeat: | |||
742 | * set nIEN for previous port, drives in the | 742 | * set nIEN for previous port, drives in the |
743 | * quirk_list may not like intr setups/cleanups | 743 | * quirk_list may not like intr setups/cleanups |
744 | */ | 744 | */ |
745 | if (prev_port && hwgroup->drive->quirk_list == 0) | 745 | if (prev_port && hwgroup->cur_dev->quirk_list == 0) |
746 | prev_port->tp_ops->set_irq(prev_port, 0); | 746 | prev_port->tp_ops->set_irq(prev_port, 0); |
747 | 747 | ||
748 | hwif->host->cur_port = hwif; | 748 | hwif->host->cur_port = hwif; |
749 | } | 749 | } |
750 | hwgroup->drive = drive; | 750 | hwgroup->cur_dev = drive; |
751 | drive->dev_flags &= ~(IDE_DFLAG_SLEEPING | IDE_DFLAG_PARKED); | 751 | drive->dev_flags &= ~(IDE_DFLAG_SLEEPING | IDE_DFLAG_PARKED); |
752 | 752 | ||
753 | spin_unlock_irq(&hwgroup->lock); | 753 | spin_unlock_irq(&hwgroup->lock); |
@@ -913,9 +913,9 @@ void ide_timer_expiry (unsigned long data) | |||
913 | * Either way, we don't really want to complain about anything. | 913 | * Either way, we don't really want to complain about anything. |
914 | */ | 914 | */ |
915 | } else { | 915 | } else { |
916 | drive = hwgroup->drive; | 916 | drive = hwgroup->cur_dev; |
917 | if (!drive) { | 917 | if (!drive) { |
918 | printk(KERN_ERR "ide_timer_expiry: hwgroup->drive was NULL\n"); | 918 | printk(KERN_ERR "%s: ->cur_dev was NULL\n", __func__); |
919 | hwgroup->handler = NULL; | 919 | hwgroup->handler = NULL; |
920 | } else { | 920 | } else { |
921 | ide_hwif_t *hwif; | 921 | ide_hwif_t *hwif; |
@@ -1033,7 +1033,7 @@ static void unexpected_intr(int irq, ide_hwif_t *hwif) | |||
1033 | * places | 1033 | * places |
1034 | * | 1034 | * |
1035 | * hwif is the interface in the group currently performing | 1035 | * hwif is the interface in the group currently performing |
1036 | * a command. hwgroup->drive is the drive and hwgroup->handler is | 1036 | * a command. hwgroup->cur_dev is the drive and hwgroup->handler is |
1037 | * the IRQ handler to call. As we issue a command the handlers | 1037 | * the IRQ handler to call. As we issue a command the handlers |
1038 | * step through multiple states, reassigning the handler to the | 1038 | * step through multiple states, reassigning the handler to the |
1039 | * next step in the process. Unlike a smart SCSI controller IDE | 1039 | * next step in the process. Unlike a smart SCSI controller IDE |
@@ -1105,7 +1105,7 @@ irqreturn_t ide_intr (int irq, void *dev_id) | |||
1105 | goto out; | 1105 | goto out; |
1106 | } | 1106 | } |
1107 | 1107 | ||
1108 | drive = hwgroup->drive; | 1108 | drive = hwgroup->cur_dev; |
1109 | if (!drive) { | 1109 | if (!drive) { |
1110 | /* | 1110 | /* |
1111 | * This should NEVER happen, and there isn't much | 1111 | * This should NEVER happen, and there isn't much |
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c index 2752509531b7..68f3c87b8284 100644 --- a/drivers/ide/ide-probe.c +++ b/drivers/ide/ide-probe.c | |||
@@ -918,27 +918,9 @@ static int ide_init_queue(ide_drive_t *drive) | |||
918 | return 0; | 918 | return 0; |
919 | } | 919 | } |
920 | 920 | ||
921 | static void ide_add_drive_to_hwgroup(ide_drive_t *drive) | ||
922 | { | ||
923 | ide_hwgroup_t *hwgroup = drive->hwif->hwgroup; | ||
924 | |||
925 | spin_lock_irq(&hwgroup->lock); | ||
926 | if (!hwgroup->drive) { | ||
927 | /* first drive for hwgroup. */ | ||
928 | drive->next = drive; | ||
929 | hwgroup->drive = drive; | ||
930 | hwgroup->hwif = HWIF(hwgroup->drive); | ||
931 | } else { | ||
932 | drive->next = hwgroup->drive->next; | ||
933 | hwgroup->drive->next = drive; | ||
934 | } | ||
935 | spin_unlock_irq(&hwgroup->lock); | ||
936 | } | ||
937 | |||
938 | /* | 921 | /* |
939 | * For any present drive: | 922 | * For any present drive: |
940 | * - allocate the block device queue | 923 | * - allocate the block device queue |
941 | * - link drive into the hwgroup | ||
942 | */ | 924 | */ |
943 | static int ide_port_setup_devices(ide_hwif_t *hwif) | 925 | static int ide_port_setup_devices(ide_hwif_t *hwif) |
944 | { | 926 | { |
@@ -961,8 +943,6 @@ static int ide_port_setup_devices(ide_hwif_t *hwif) | |||
961 | } | 943 | } |
962 | 944 | ||
963 | j++; | 945 | j++; |
964 | |||
965 | ide_add_drive_to_hwgroup(drive); | ||
966 | } | 946 | } |
967 | mutex_unlock(&ide_cfg_mtx); | 947 | mutex_unlock(&ide_cfg_mtx); |
968 | 948 | ||
@@ -978,33 +958,9 @@ void ide_remove_port_from_hwgroup(ide_hwif_t *hwif) | |||
978 | ide_ports[hwif->index] = NULL; | 958 | ide_ports[hwif->index] = NULL; |
979 | 959 | ||
980 | spin_lock_irq(&hwgroup->lock); | 960 | spin_lock_irq(&hwgroup->lock); |
981 | /* | 961 | /* Free the hwgroup if we were the only member. */ |
982 | * Remove us from the hwgroup, and free | 962 | if (--hwgroup->port_count == 0) |
983 | * the hwgroup if we were the only member | ||
984 | */ | ||
985 | if (hwif->next == hwif) { | ||
986 | BUG_ON(hwgroup->hwif != hwif); | ||
987 | kfree(hwgroup); | 963 | kfree(hwgroup); |
988 | } else { | ||
989 | /* There is another interface in hwgroup. | ||
990 | * Unlink us, and set hwgroup->drive and ->hwif to | ||
991 | * something sane. | ||
992 | */ | ||
993 | ide_hwif_t *g = hwgroup->hwif; | ||
994 | |||
995 | while (g->next != hwif) | ||
996 | g = g->next; | ||
997 | g->next = hwif->next; | ||
998 | if (hwgroup->hwif == hwif) { | ||
999 | /* Chose a random hwif for hwgroup->hwif. | ||
1000 | * It's guaranteed that there are no drives | ||
1001 | * left in the hwgroup. | ||
1002 | */ | ||
1003 | BUG_ON(hwgroup->drive != NULL); | ||
1004 | hwgroup->hwif = g; | ||
1005 | } | ||
1006 | BUG_ON(hwgroup->hwif == hwif); | ||
1007 | } | ||
1008 | spin_unlock_irq(&hwgroup->lock); | 964 | spin_unlock_irq(&hwgroup->lock); |
1009 | } | 965 | } |
1010 | 966 | ||
@@ -1044,20 +1000,9 @@ static int init_irq (ide_hwif_t *hwif) | |||
1044 | if (match) { | 1000 | if (match) { |
1045 | hwgroup = match->hwgroup; | 1001 | hwgroup = match->hwgroup; |
1046 | hwif->hwgroup = hwgroup; | 1002 | hwif->hwgroup = hwgroup; |
1047 | /* | 1003 | |
1048 | * Link us into the hwgroup. | ||
1049 | * This must be done early, do ensure that unexpected_intr | ||
1050 | * can find the hwif and prevent irq storms. | ||
1051 | * No drives are attached to the new hwif, choose_drive | ||
1052 | * can't do anything stupid (yet). | ||
1053 | * Add ourself as the 2nd entry to the hwgroup->hwif | ||
1054 | * linked list, the first entry is the hwif that owns | ||
1055 | * hwgroup->handler - do not change that. | ||
1056 | */ | ||
1057 | spin_lock_irq(&hwgroup->lock); | 1004 | spin_lock_irq(&hwgroup->lock); |
1058 | hwif->next = hwgroup->hwif->next; | 1005 | hwgroup->port_count++; |
1059 | hwgroup->hwif->next = hwif; | ||
1060 | BUG_ON(hwif->next == hwif); | ||
1061 | spin_unlock_irq(&hwgroup->lock); | 1006 | spin_unlock_irq(&hwgroup->lock); |
1062 | } else { | 1007 | } else { |
1063 | hwgroup = kmalloc_node(sizeof(*hwgroup), GFP_KERNEL|__GFP_ZERO, | 1008 | hwgroup = kmalloc_node(sizeof(*hwgroup), GFP_KERNEL|__GFP_ZERO, |
@@ -1068,7 +1013,8 @@ static int init_irq (ide_hwif_t *hwif) | |||
1068 | spin_lock_init(&hwgroup->lock); | 1013 | spin_lock_init(&hwgroup->lock); |
1069 | 1014 | ||
1070 | hwif->hwgroup = hwgroup; | 1015 | hwif->hwgroup = hwgroup; |
1071 | hwgroup->hwif = hwif->next = hwif; | 1016 | |
1017 | hwgroup->port_count = 1; | ||
1072 | 1018 | ||
1073 | init_timer(&hwgroup->timer); | 1019 | init_timer(&hwgroup->timer); |
1074 | hwgroup->timer.function = &ide_timer_expiry; | 1020 | hwgroup->timer.function = &ide_timer_expiry; |
@@ -1191,29 +1137,6 @@ void ide_init_disk(struct gendisk *disk, ide_drive_t *drive) | |||
1191 | 1137 | ||
1192 | EXPORT_SYMBOL_GPL(ide_init_disk); | 1138 | EXPORT_SYMBOL_GPL(ide_init_disk); |
1193 | 1139 | ||
1194 | static void ide_remove_drive_from_hwgroup(ide_drive_t *drive) | ||
1195 | { | ||
1196 | ide_hwgroup_t *hwgroup = drive->hwif->hwgroup; | ||
1197 | |||
1198 | if (drive == drive->next) { | ||
1199 | /* special case: last drive from hwgroup. */ | ||
1200 | BUG_ON(hwgroup->drive != drive); | ||
1201 | hwgroup->drive = NULL; | ||
1202 | } else { | ||
1203 | ide_drive_t *walk; | ||
1204 | |||
1205 | walk = hwgroup->drive; | ||
1206 | while (walk->next != drive) | ||
1207 | walk = walk->next; | ||
1208 | walk->next = drive->next; | ||
1209 | if (hwgroup->drive == drive) { | ||
1210 | hwgroup->drive = drive->next; | ||
1211 | hwgroup->hwif = hwgroup->drive->hwif; | ||
1212 | } | ||
1213 | } | ||
1214 | BUG_ON(hwgroup->drive == drive); | ||
1215 | } | ||
1216 | |||
1217 | static void drive_release_dev (struct device *dev) | 1140 | static void drive_release_dev (struct device *dev) |
1218 | { | 1141 | { |
1219 | ide_drive_t *drive = container_of(dev, ide_drive_t, gendev); | 1142 | ide_drive_t *drive = container_of(dev, ide_drive_t, gendev); |
@@ -1222,7 +1145,6 @@ static void drive_release_dev (struct device *dev) | |||
1222 | ide_proc_unregister_device(drive); | 1145 | ide_proc_unregister_device(drive); |
1223 | 1146 | ||
1224 | spin_lock_irq(&hwgroup->lock); | 1147 | spin_lock_irq(&hwgroup->lock); |
1225 | ide_remove_drive_from_hwgroup(drive); | ||
1226 | kfree(drive->id); | 1148 | kfree(drive->id); |
1227 | drive->id = NULL; | 1149 | drive->id = NULL; |
1228 | drive->dev_flags &= ~IDE_DFLAG_PRESENT; | 1150 | drive->dev_flags &= ~IDE_DFLAG_PRESENT; |