aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ide/ide-probe.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ide/ide-probe.c')
-rw-r--r--drivers/ide/ide-probe.c90
1 files changed, 6 insertions, 84 deletions
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
921static 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 */
943static int ide_port_setup_devices(ide_hwif_t *hwif) 925static 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
1192EXPORT_SYMBOL_GPL(ide_init_disk); 1138EXPORT_SYMBOL_GPL(ide_init_disk);
1193 1139
1194static 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
1217static void drive_release_dev (struct device *dev) 1140static 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;