Commit efe0397eef544ac4bcca23d39aa8d5db154952e0
1 parent
ae86afaee6
Exists in
master
and in
7 other branches
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>
Showing 3 changed files with 15 additions and 100 deletions Side-by-side Diff
drivers/ide/ide-io.c
... | ... | @@ -742,12 +742,12 @@ |
742 | 742 | * set nIEN for previous port, drives in the |
743 | 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 | 746 | prev_port->tp_ops->set_irq(prev_port, 0); |
747 | 747 | |
748 | 748 | hwif->host->cur_port = hwif; |
749 | 749 | } |
750 | - hwgroup->drive = drive; | |
750 | + hwgroup->cur_dev = drive; | |
751 | 751 | drive->dev_flags &= ~(IDE_DFLAG_SLEEPING | IDE_DFLAG_PARKED); |
752 | 752 | |
753 | 753 | spin_unlock_irq(&hwgroup->lock); |
754 | 754 | |
... | ... | @@ -913,9 +913,9 @@ |
913 | 913 | * Either way, we don't really want to complain about anything. |
914 | 914 | */ |
915 | 915 | } else { |
916 | - drive = hwgroup->drive; | |
916 | + drive = hwgroup->cur_dev; | |
917 | 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 | 919 | hwgroup->handler = NULL; |
920 | 920 | } else { |
921 | 921 | ide_hwif_t *hwif; |
... | ... | @@ -1033,7 +1033,7 @@ |
1033 | 1033 | * places |
1034 | 1034 | * |
1035 | 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 | 1037 | * the IRQ handler to call. As we issue a command the handlers |
1038 | 1038 | * step through multiple states, reassigning the handler to the |
1039 | 1039 | * next step in the process. Unlike a smart SCSI controller IDE |
... | ... | @@ -1105,7 +1105,7 @@ |
1105 | 1105 | goto out; |
1106 | 1106 | } |
1107 | 1107 | |
1108 | - drive = hwgroup->drive; | |
1108 | + drive = hwgroup->cur_dev; | |
1109 | 1109 | if (!drive) { |
1110 | 1110 | /* |
1111 | 1111 | * This should NEVER happen, and there isn't much |
drivers/ide/ide-probe.c
... | ... | @@ -918,27 +918,9 @@ |
918 | 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 | 922 | * For any present drive: |
940 | 923 | * - allocate the block device queue |
941 | - * - link drive into the hwgroup | |
942 | 924 | */ |
943 | 925 | static int ide_port_setup_devices(ide_hwif_t *hwif) |
944 | 926 | { |
... | ... | @@ -961,8 +943,6 @@ |
961 | 943 | } |
962 | 944 | |
963 | 945 | j++; |
964 | - | |
965 | - ide_add_drive_to_hwgroup(drive); | |
966 | 946 | } |
967 | 947 | mutex_unlock(&ide_cfg_mtx); |
968 | 948 | |
969 | 949 | |
... | ... | @@ -978,33 +958,9 @@ |
978 | 958 | ide_ports[hwif->index] = NULL; |
979 | 959 | |
980 | 960 | spin_lock_irq(&hwgroup->lock); |
981 | - /* | |
982 | - * Remove us from the hwgroup, and free | |
983 | - * the hwgroup if we were the only member | |
984 | - */ | |
985 | - if (hwif->next == hwif) { | |
986 | - BUG_ON(hwgroup->hwif != hwif); | |
961 | + /* Free the hwgroup if we were the only member. */ | |
962 | + if (--hwgroup->port_count == 0) | |
987 | 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 | 964 | spin_unlock_irq(&hwgroup->lock); |
1009 | 965 | } |
1010 | 966 | |
1011 | 967 | |
... | ... | @@ -1044,20 +1000,9 @@ |
1044 | 1000 | if (match) { |
1045 | 1001 | hwgroup = match->hwgroup; |
1046 | 1002 | hwif->hwgroup = hwgroup; |
1047 | - /* | |
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 | - */ | |
1003 | + | |
1057 | 1004 | spin_lock_irq(&hwgroup->lock); |
1058 | - hwif->next = hwgroup->hwif->next; | |
1059 | - hwgroup->hwif->next = hwif; | |
1060 | - BUG_ON(hwif->next == hwif); | |
1005 | + hwgroup->port_count++; | |
1061 | 1006 | spin_unlock_irq(&hwgroup->lock); |
1062 | 1007 | } else { |
1063 | 1008 | hwgroup = kmalloc_node(sizeof(*hwgroup), GFP_KERNEL|__GFP_ZERO, |
1064 | 1009 | |
... | ... | @@ -1068,8 +1013,9 @@ |
1068 | 1013 | spin_lock_init(&hwgroup->lock); |
1069 | 1014 | |
1070 | 1015 | hwif->hwgroup = hwgroup; |
1071 | - hwgroup->hwif = hwif->next = hwif; | |
1072 | 1016 | |
1017 | + hwgroup->port_count = 1; | |
1018 | + | |
1073 | 1019 | init_timer(&hwgroup->timer); |
1074 | 1020 | hwgroup->timer.function = &ide_timer_expiry; |
1075 | 1021 | hwgroup->timer.data = (unsigned long) hwgroup; |
... | ... | @@ -1191,29 +1137,6 @@ |
1191 | 1137 | |
1192 | 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 | 1140 | static void drive_release_dev (struct device *dev) |
1218 | 1141 | { |
1219 | 1142 | ide_drive_t *drive = container_of(dev, ide_drive_t, gendev); |
... | ... | @@ -1222,7 +1145,6 @@ |
1222 | 1145 | ide_proc_unregister_device(drive); |
1223 | 1146 | |
1224 | 1147 | spin_lock_irq(&hwgroup->lock); |
1225 | - ide_remove_drive_from_hwgroup(drive); | |
1226 | 1148 | kfree(drive->id); |
1227 | 1149 | drive->id = NULL; |
1228 | 1150 | drive->dev_flags &= ~IDE_DFLAG_PRESENT; |
include/linux/ide.h
... | ... | @@ -588,7 +588,6 @@ |
588 | 588 | struct request_queue *queue; /* request queue */ |
589 | 589 | |
590 | 590 | struct request *rq; /* current request */ |
591 | - struct ide_drive_s *next; /* circular list of hwgroup drives */ | |
592 | 591 | void *driver_data; /* extra driver data */ |
593 | 592 | u16 *id; /* identification info */ |
594 | 593 | #ifdef CONFIG_IDE_PROC_FS |
... | ... | @@ -750,7 +749,6 @@ |
750 | 749 | struct ide_host; |
751 | 750 | |
752 | 751 | typedef struct hwif_s { |
753 | - struct hwif_s *next; /* for linked-list in ide_hwgroup_t */ | |
754 | 752 | struct hwif_s *mate; /* other hwif from same PCI chip */ |
755 | 753 | struct hwgroup_s *hwgroup; /* actually (ide_hwgroup_t *) */ |
756 | 754 | struct proc_dir_entry *proc; /* /proc/ide/ directory entry */ |
... | ... | @@ -874,9 +872,7 @@ |
874 | 872 | unsigned int polling : 1; |
875 | 873 | |
876 | 874 | /* current drive */ |
877 | - ide_drive_t *drive; | |
878 | - /* ptr to current hwif in linked-list */ | |
879 | - ide_hwif_t *hwif; | |
875 | + ide_drive_t *cur_dev; | |
880 | 876 | |
881 | 877 | /* current request */ |
882 | 878 | struct request *rq; |
... | ... | @@ -892,6 +888,8 @@ |
892 | 888 | int req_gen_timer; |
893 | 889 | |
894 | 890 | spinlock_t lock; |
891 | + | |
892 | + int port_count; | |
895 | 893 | } ide_hwgroup_t; |
896 | 894 | |
897 | 895 | typedef struct ide_driver_s ide_driver_t; |
898 | 896 | |
... | ... | @@ -1622,12 +1620,7 @@ |
1622 | 1620 | /* |
1623 | 1621 | * Structure locking: |
1624 | 1622 | * |
1625 | - * ide_cfg_mtx and hwgroup->lock together protect changes to | |
1626 | - * ide_hwif_t->next | |
1627 | - * ide_drive_t->next | |
1628 | - * | |
1629 | 1623 | * ide_hwgroup_t->busy: hwgroup->lock |
1630 | - * ide_hwgroup_t->hwif: hwgroup->lock | |
1631 | 1624 | * ide_hwif_t->{hwgroup,mate}: constant, no locking |
1632 | 1625 | * ide_drive_t->hwif: constant, no locking |
1633 | 1626 | */ |