diff options
author | Dean Nelson <dcn@sgi.com> | 2008-07-30 01:34:04 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2008-07-30 12:41:49 -0400 |
commit | bc63d387e4f5dbbe4ea0c5ade862c38073fd7fa3 (patch) | |
tree | ebeb9a381224a935fc50697902fcc38b9df47d90 /drivers/misc/sgi-xp/xpc_main.c | |
parent | 78ce1bbe446e9b46dcd6c1e60a4768448a8ce355 (diff) |
sgi-xp: support runtime selection of xp_max_npartitions
Support runtime selection of the max number of partitions based on the
hardware being run on.
Signed-off-by: Dean Nelson <dcn@sgi.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/misc/sgi-xp/xpc_main.c')
-rw-r--r-- | drivers/misc/sgi-xp/xpc_main.c | 103 |
1 files changed, 50 insertions, 53 deletions
diff --git a/drivers/misc/sgi-xp/xpc_main.c b/drivers/misc/sgi-xp/xpc_main.c index c3b4227f48a5..a05c7c7da228 100644 --- a/drivers/misc/sgi-xp/xpc_main.c +++ b/drivers/misc/sgi-xp/xpc_main.c | |||
@@ -433,7 +433,7 @@ xpc_activating(void *__partid) | |||
433 | struct xpc_partition *part = &xpc_partitions[partid]; | 433 | struct xpc_partition *part = &xpc_partitions[partid]; |
434 | unsigned long irq_flags; | 434 | unsigned long irq_flags; |
435 | 435 | ||
436 | DBUG_ON(partid <= 0 || partid >= XP_MAX_PARTITIONS); | 436 | DBUG_ON(partid < 0 || partid >= xp_max_npartitions); |
437 | 437 | ||
438 | spin_lock_irqsave(&part->act_lock, irq_flags); | 438 | spin_lock_irqsave(&part->act_lock, irq_flags); |
439 | 439 | ||
@@ -544,7 +544,7 @@ xpc_notify_IRQ_handler(int irq, void *dev_id) | |||
544 | short partid = (short)(u64)dev_id; | 544 | short partid = (short)(u64)dev_id; |
545 | struct xpc_partition *part = &xpc_partitions[partid]; | 545 | struct xpc_partition *part = &xpc_partitions[partid]; |
546 | 546 | ||
547 | DBUG_ON(partid <= 0 || partid >= XP_MAX_PARTITIONS); | 547 | DBUG_ON(partid < 0 || partid >= xp_max_npartitions); |
548 | 548 | ||
549 | if (xpc_part_ref(part)) { | 549 | if (xpc_part_ref(part)) { |
550 | xpc_check_for_channel_activity(part); | 550 | xpc_check_for_channel_activity(part); |
@@ -815,7 +815,7 @@ xpc_disconnect_wait(int ch_number) | |||
815 | int wakeup_channel_mgr; | 815 | int wakeup_channel_mgr; |
816 | 816 | ||
817 | /* now wait for all callouts to the caller's function to cease */ | 817 | /* now wait for all callouts to the caller's function to cease */ |
818 | for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) { | 818 | for (partid = 0; partid < xp_max_npartitions; partid++) { |
819 | part = &xpc_partitions[partid]; | 819 | part = &xpc_partitions[partid]; |
820 | 820 | ||
821 | if (!xpc_part_ref(part)) | 821 | if (!xpc_part_ref(part)) |
@@ -895,7 +895,7 @@ xpc_do_exit(enum xp_retval reason) | |||
895 | do { | 895 | do { |
896 | active_part_count = 0; | 896 | active_part_count = 0; |
897 | 897 | ||
898 | for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) { | 898 | for (partid = 0; partid < xp_max_npartitions; partid++) { |
899 | part = &xpc_partitions[partid]; | 899 | part = &xpc_partitions[partid]; |
900 | 900 | ||
901 | if (xpc_partition_disengaged(part) && | 901 | if (xpc_partition_disengaged(part) && |
@@ -956,11 +956,8 @@ xpc_do_exit(enum xp_retval reason) | |||
956 | DBUG_ON(xpc_vars->heartbeating_to_mask != 0); | 956 | DBUG_ON(xpc_vars->heartbeating_to_mask != 0); |
957 | 957 | ||
958 | if (reason == xpUnloading) { | 958 | if (reason == xpUnloading) { |
959 | /* take ourselves off of the reboot_notifier_list */ | ||
960 | (void)unregister_reboot_notifier(&xpc_reboot_notifier); | ||
961 | |||
962 | /* take ourselves off of the die_notifier list */ | ||
963 | (void)unregister_die_notifier(&xpc_die_notifier); | 959 | (void)unregister_die_notifier(&xpc_die_notifier); |
960 | (void)unregister_reboot_notifier(&xpc_reboot_notifier); | ||
964 | } | 961 | } |
965 | 962 | ||
966 | /* close down protections for IPI operations */ | 963 | /* close down protections for IPI operations */ |
@@ -972,6 +969,7 @@ xpc_do_exit(enum xp_retval reason) | |||
972 | if (xpc_sysctl) | 969 | if (xpc_sysctl) |
973 | unregister_sysctl_table(xpc_sysctl); | 970 | unregister_sysctl_table(xpc_sysctl); |
974 | 971 | ||
972 | kfree(xpc_partitions); | ||
975 | kfree(xpc_remote_copy_buffer_base); | 973 | kfree(xpc_remote_copy_buffer_base); |
976 | } | 974 | } |
977 | 975 | ||
@@ -1017,7 +1015,7 @@ xpc_die_disengage(void) | |||
1017 | 1015 | ||
1018 | xpc_vars->heartbeating_to_mask = 0; /* indicate we're deactivated */ | 1016 | xpc_vars->heartbeating_to_mask = 0; /* indicate we're deactivated */ |
1019 | 1017 | ||
1020 | for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) { | 1018 | for (partid = 0; partid < xp_max_npartitions; partid++) { |
1021 | part = &xpc_partitions[partid]; | 1019 | part = &xpc_partitions[partid]; |
1022 | 1020 | ||
1023 | if (!XPC_SUPPORTS_DISENGAGE_REQUEST(part-> | 1021 | if (!XPC_SUPPORTS_DISENGAGE_REQUEST(part-> |
@@ -1053,7 +1051,8 @@ xpc_die_disengage(void) | |||
1053 | 1051 | ||
1054 | time = rtc_time(); | 1052 | time = rtc_time(); |
1055 | if (time >= disengage_request_timeout) { | 1053 | if (time >= disengage_request_timeout) { |
1056 | for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) { | 1054 | for (partid = 0; partid < xp_max_npartitions; |
1055 | partid++) { | ||
1057 | if (engaged & (1UL << partid)) { | 1056 | if (engaged & (1UL << partid)) { |
1058 | dev_info(xpc_part, "disengage from " | 1057 | dev_info(xpc_part, "disengage from " |
1059 | "remote partition %d timed " | 1058 | "remote partition %d timed " |
@@ -1132,18 +1131,26 @@ xpc_init(void) | |||
1132 | if (!ia64_platform_is("sn2")) | 1131 | if (!ia64_platform_is("sn2")) |
1133 | return -ENODEV; | 1132 | return -ENODEV; |
1134 | 1133 | ||
1134 | snprintf(xpc_part->bus_id, BUS_ID_SIZE, "part"); | ||
1135 | snprintf(xpc_chan->bus_id, BUS_ID_SIZE, "chan"); | ||
1136 | |||
1135 | buf_size = max(XPC_RP_VARS_SIZE, | 1137 | buf_size = max(XPC_RP_VARS_SIZE, |
1136 | XPC_RP_HEADER_SIZE + XP_NASID_MASK_BYTES); | 1138 | XPC_RP_HEADER_SIZE + XP_NASID_MASK_BYTES); |
1137 | xpc_remote_copy_buffer = xpc_kmalloc_cacheline_aligned(buf_size, | 1139 | xpc_remote_copy_buffer = xpc_kmalloc_cacheline_aligned(buf_size, |
1138 | GFP_KERNEL, | 1140 | GFP_KERNEL, |
1139 | &xpc_remote_copy_buffer_base); | 1141 | &xpc_remote_copy_buffer_base); |
1140 | if (xpc_remote_copy_buffer == NULL) | 1142 | if (xpc_remote_copy_buffer == NULL) { |
1143 | dev_err(xpc_part, "can't get memory for remote copy buffer\n"); | ||
1141 | return -ENOMEM; | 1144 | return -ENOMEM; |
1145 | } | ||
1142 | 1146 | ||
1143 | snprintf(xpc_part->bus_id, BUS_ID_SIZE, "part"); | 1147 | xpc_partitions = kzalloc(sizeof(struct xpc_partition) * |
1144 | snprintf(xpc_chan->bus_id, BUS_ID_SIZE, "chan"); | 1148 | xp_max_npartitions, GFP_KERNEL); |
1145 | 1149 | if (xpc_partitions == NULL) { | |
1146 | xpc_sysctl = register_sysctl_table(xpc_sys_dir); | 1150 | dev_err(xpc_part, "can't get memory for partition structure\n"); |
1151 | ret = -ENOMEM; | ||
1152 | goto out_1; | ||
1153 | } | ||
1147 | 1154 | ||
1148 | /* | 1155 | /* |
1149 | * The first few fields of each entry of xpc_partitions[] need to | 1156 | * The first few fields of each entry of xpc_partitions[] need to |
@@ -1153,7 +1160,7 @@ xpc_init(void) | |||
1153 | * ENTRIES ARE MEANINGFUL UNTIL AFTER AN ENTRY'S CORRESPONDING | 1160 | * ENTRIES ARE MEANINGFUL UNTIL AFTER AN ENTRY'S CORRESPONDING |
1154 | * PARTITION HAS BEEN ACTIVATED. | 1161 | * PARTITION HAS BEEN ACTIVATED. |
1155 | */ | 1162 | */ |
1156 | for (partid = 1; partid < XP_MAX_PARTITIONS; partid++) { | 1163 | for (partid = 0; partid < xp_max_npartitions; partid++) { |
1157 | part = &xpc_partitions[partid]; | 1164 | part = &xpc_partitions[partid]; |
1158 | 1165 | ||
1159 | DBUG_ON((u64)part != L1_CACHE_ALIGN((u64)part)); | 1166 | DBUG_ON((u64)part != L1_CACHE_ALIGN((u64)part)); |
@@ -1173,6 +1180,8 @@ xpc_init(void) | |||
1173 | atomic_set(&part->references, 0); | 1180 | atomic_set(&part->references, 0); |
1174 | } | 1181 | } |
1175 | 1182 | ||
1183 | xpc_sysctl = register_sysctl_table(xpc_sys_dir); | ||
1184 | |||
1176 | /* | 1185 | /* |
1177 | * Open up protections for IPI operations (and AMO operations on | 1186 | * Open up protections for IPI operations (and AMO operations on |
1178 | * Shub 1.1 systems). | 1187 | * Shub 1.1 systems). |
@@ -1196,14 +1205,8 @@ xpc_init(void) | |||
1196 | if (ret != 0) { | 1205 | if (ret != 0) { |
1197 | dev_err(xpc_part, "can't register ACTIVATE IRQ handler, " | 1206 | dev_err(xpc_part, "can't register ACTIVATE IRQ handler, " |
1198 | "errno=%d\n", -ret); | 1207 | "errno=%d\n", -ret); |
1199 | 1208 | ret = -EBUSY; | |
1200 | xpc_restrict_IPI_ops(); | 1209 | goto out_2; |
1201 | |||
1202 | if (xpc_sysctl) | ||
1203 | unregister_sysctl_table(xpc_sysctl); | ||
1204 | |||
1205 | kfree(xpc_remote_copy_buffer_base); | ||
1206 | return -EBUSY; | ||
1207 | } | 1210 | } |
1208 | 1211 | ||
1209 | /* | 1212 | /* |
@@ -1213,16 +1216,9 @@ xpc_init(void) | |||
1213 | */ | 1216 | */ |
1214 | xpc_rsvd_page = xpc_rsvd_page_init(); | 1217 | xpc_rsvd_page = xpc_rsvd_page_init(); |
1215 | if (xpc_rsvd_page == NULL) { | 1218 | if (xpc_rsvd_page == NULL) { |
1216 | dev_err(xpc_part, "could not setup our reserved page\n"); | 1219 | dev_err(xpc_part, "can't setup our reserved page\n"); |
1217 | 1220 | ret = -EBUSY; | |
1218 | free_irq(SGI_XPC_ACTIVATE, NULL); | 1221 | goto out_3; |
1219 | xpc_restrict_IPI_ops(); | ||
1220 | |||
1221 | if (xpc_sysctl) | ||
1222 | unregister_sysctl_table(xpc_sysctl); | ||
1223 | |||
1224 | kfree(xpc_remote_copy_buffer_base); | ||
1225 | return -EBUSY; | ||
1226 | } | 1222 | } |
1227 | 1223 | ||
1228 | /* add ourselves to the reboot_notifier_list */ | 1224 | /* add ourselves to the reboot_notifier_list */ |
@@ -1245,25 +1241,8 @@ xpc_init(void) | |||
1245 | kthread = kthread_run(xpc_hb_checker, NULL, XPC_HB_CHECK_THREAD_NAME); | 1241 | kthread = kthread_run(xpc_hb_checker, NULL, XPC_HB_CHECK_THREAD_NAME); |
1246 | if (IS_ERR(kthread)) { | 1242 | if (IS_ERR(kthread)) { |
1247 | dev_err(xpc_part, "failed while forking hb check thread\n"); | 1243 | dev_err(xpc_part, "failed while forking hb check thread\n"); |
1248 | 1244 | ret = -EBUSY; | |
1249 | /* indicate to others that our reserved page is uninitialized */ | 1245 | goto out_4; |
1250 | xpc_rsvd_page->vars_pa = 0; | ||
1251 | |||
1252 | /* take ourselves off of the reboot_notifier_list */ | ||
1253 | (void)unregister_reboot_notifier(&xpc_reboot_notifier); | ||
1254 | |||
1255 | /* take ourselves off of the die_notifier list */ | ||
1256 | (void)unregister_die_notifier(&xpc_die_notifier); | ||
1257 | |||
1258 | del_timer_sync(&xpc_hb_timer); | ||
1259 | free_irq(SGI_XPC_ACTIVATE, NULL); | ||
1260 | xpc_restrict_IPI_ops(); | ||
1261 | |||
1262 | if (xpc_sysctl) | ||
1263 | unregister_sysctl_table(xpc_sysctl); | ||
1264 | |||
1265 | kfree(xpc_remote_copy_buffer_base); | ||
1266 | return -EBUSY; | ||
1267 | } | 1246 | } |
1268 | 1247 | ||
1269 | /* | 1248 | /* |
@@ -1290,6 +1269,24 @@ xpc_init(void) | |||
1290 | xpc_initiate_partid_to_nasids); | 1269 | xpc_initiate_partid_to_nasids); |
1291 | 1270 | ||
1292 | return 0; | 1271 | return 0; |
1272 | |||
1273 | /* initialization was not successful */ | ||
1274 | out_4: | ||
1275 | /* indicate to others that our reserved page is uninitialized */ | ||
1276 | xpc_rsvd_page->vars_pa = 0; | ||
1277 | del_timer_sync(&xpc_hb_timer); | ||
1278 | (void)unregister_die_notifier(&xpc_die_notifier); | ||
1279 | (void)unregister_reboot_notifier(&xpc_reboot_notifier); | ||
1280 | out_3: | ||
1281 | free_irq(SGI_XPC_ACTIVATE, NULL); | ||
1282 | out_2: | ||
1283 | xpc_restrict_IPI_ops(); | ||
1284 | if (xpc_sysctl) | ||
1285 | unregister_sysctl_table(xpc_sysctl); | ||
1286 | kfree(xpc_partitions); | ||
1287 | out_1: | ||
1288 | kfree(xpc_remote_copy_buffer_base); | ||
1289 | return ret; | ||
1293 | } | 1290 | } |
1294 | 1291 | ||
1295 | module_init(xpc_init); | 1292 | module_init(xpc_init); |