1 // SPDX-License-Identifier: GPL-2.0-only
2 /* chmc.c: Driver for UltraSPARC-III memory controller.
4 * Copyright (C) 2001, 2007, 2008 David S. Miller (davem@davemloft.net)
7 #include <linux/module.h>
8 #include <linux/kernel.h>
9 #include <linux/types.h>
10 #include <linux/slab.h>
11 #include <linux/list.h>
12 #include <linux/string.h>
13 #include <linux/sched.h>
14 #include <linux/smp.h>
15 #include <linux/errno.h>
16 #include <linux/init.h>
18 #include <linux/of_platform.h>
19 #include <linux/platform_device.h>
20 #include <asm/spitfire.h>
21 #include <asm/chmctrl.h>
22 #include <asm/cpudata.h>
23 #include <asm/oplib.h>
27 #include <asm/memctrl.h>
29 #define DRV_MODULE_NAME "chmc"
30 #define PFX DRV_MODULE_NAME ": "
31 #define DRV_MODULE_VERSION "0.2"
33 MODULE_AUTHOR("David S. Miller <davem@davemloft.net>");
34 MODULE_DESCRIPTION("UltraSPARC-III memory controller driver");
35 MODULE_LICENSE("GPL");
36 MODULE_VERSION(DRV_MODULE_VERSION
);
39 #define MC_TYPE_SAFARI 1
40 #define MC_TYPE_JBUS 2
42 static dimm_printer_t us3mc_dimm_printer
;
44 #define CHMCTRL_NDGRPS 2
45 #define CHMCTRL_NDIMMS 4
47 #define CHMC_DIMMS_PER_MC (CHMCTRL_NDGRPS * CHMCTRL_NDIMMS)
49 /* OBP memory-layout property format. */
51 unsigned char dimm_map
[144];
52 unsigned char pin_map
[576];
55 #define DIMM_LABEL_SZ 8
57 struct chmc_obp_mem_layout
{
58 /* One max 8-byte string label per DIMM. Usually
59 * this matches the label on the motherboard where
62 char dimm_labels
[CHMC_DIMMS_PER_MC
][DIMM_LABEL_SZ
];
64 /* If symmetric use map[0], else it is
65 * asymmetric and map[1] should be used.
69 struct chmc_obp_map map
[2];
72 #define CHMCTRL_NBANKS 4
74 struct chmc_bank_info
{
90 struct list_head list
;
93 struct chmc_obp_mem_layout layout_prop
;
104 struct chmc_bank_info logical_banks
[CHMCTRL_NBANKS
];
107 #define JBUSMC_REGS_SIZE 8
109 #define JB_MC_REG1_DIMM2_BANK3 0x8000000000000000UL
110 #define JB_MC_REG1_DIMM1_BANK1 0x4000000000000000UL
111 #define JB_MC_REG1_DIMM2_BANK2 0x2000000000000000UL
112 #define JB_MC_REG1_DIMM1_BANK0 0x1000000000000000UL
113 #define JB_MC_REG1_XOR 0x0000010000000000UL
114 #define JB_MC_REG1_ADDR_GEN_2 0x000000e000000000UL
115 #define JB_MC_REG1_ADDR_GEN_2_SHIFT 37
116 #define JB_MC_REG1_ADDR_GEN_1 0x0000001c00000000UL
117 #define JB_MC_REG1_ADDR_GEN_1_SHIFT 34
118 #define JB_MC_REG1_INTERLEAVE 0x0000000001800000UL
119 #define JB_MC_REG1_INTERLEAVE_SHIFT 23
120 #define JB_MC_REG1_DIMM2_PTYPE 0x0000000000200000UL
121 #define JB_MC_REG1_DIMM2_PTYPE_SHIFT 21
122 #define JB_MC_REG1_DIMM1_PTYPE 0x0000000000100000UL
123 #define JB_MC_REG1_DIMM1_PTYPE_SHIFT 20
125 #define PART_TYPE_X8 0
126 #define PART_TYPE_X4 1
128 #define INTERLEAVE_NONE 0
129 #define INTERLEAVE_SAME 1
130 #define INTERLEAVE_INTERNAL 2
131 #define INTERLEAVE_BOTH 3
133 #define ADDR_GEN_128MB 0
134 #define ADDR_GEN_256MB 1
135 #define ADDR_GEN_512MB 2
136 #define ADDR_GEN_1GB 3
138 #define JB_NUM_DIMM_GROUPS 2
139 #define JB_NUM_DIMMS_PER_GROUP 2
140 #define JB_NUM_DIMMS (JB_NUM_DIMM_GROUPS * JB_NUM_DIMMS_PER_GROUP)
142 struct jbusmc_obp_map
{
143 unsigned char dimm_map
[18];
144 unsigned char pin_map
[144];
147 struct jbusmc_obp_mem_layout
{
148 /* One max 8-byte string label per DIMM. Usually
149 * this matches the label on the motherboard where
152 char dimm_labels
[JB_NUM_DIMMS
][DIMM_LABEL_SZ
];
154 /* If symmetric use map[0], else it is
155 * asymmetric and map[1] should be used.
159 struct jbusmc_obp_map map
;
164 struct jbusmc_dimm_group
{
165 struct jbusmc
*controller
;
175 struct jbusmc_obp_mem_layout layout
;
178 struct jbusmc_dimm_group dimm_groups
[JB_NUM_DIMM_GROUPS
];
179 struct list_head list
;
182 static DEFINE_SPINLOCK(mctrl_list_lock
);
183 static LIST_HEAD(mctrl_list
);
185 static void mc_list_add(struct list_head
*list
)
187 spin_lock(&mctrl_list_lock
);
188 list_add(list
, &mctrl_list
);
189 spin_unlock(&mctrl_list_lock
);
192 static void mc_list_del(struct list_head
*list
)
194 spin_lock(&mctrl_list_lock
);
196 spin_unlock(&mctrl_list_lock
);
199 #define SYNDROME_MIN -1
200 #define SYNDROME_MAX 144
202 /* Covert syndrome code into the way the bits are positioned
205 static int syndrome_to_qword_code(int syndrome_code
)
207 if (syndrome_code
< 128)
209 else if (syndrome_code
< 128 + 9)
210 syndrome_code
-= (128 - 7);
211 else if (syndrome_code
< (128 + 9 + 3))
212 syndrome_code
-= (128 + 9 - 4);
214 syndrome_code
-= (128 + 9 + 3);
215 return syndrome_code
;
218 /* All this magic has to do with how a cache line comes over the wire
219 * on Safari and JBUS. A 64-bit line comes over in 1 or more quadword
220 * cycles, each of which transmit ECC/MTAG info as well as the actual
223 #define L2_LINE_SIZE 64
224 #define L2_LINE_ADDR_MSK (L2_LINE_SIZE - 1)
225 #define QW_PER_LINE 4
226 #define QW_BYTES (L2_LINE_SIZE / QW_PER_LINE)
228 #define SAFARI_LAST_BIT (576 - 1)
229 #define JBUS_LAST_BIT (144 - 1)
231 static void get_pin_and_dimm_str(int syndrome_code
, unsigned long paddr
,
232 int *pin_p
, char **dimm_str_p
, void *_prop
,
233 int base_dimm_offset
)
235 int qword_code
= syndrome_to_qword_code(syndrome_code
);
236 int cache_line_offset
;
241 if (mc_type
== MC_TYPE_JBUS
) {
242 struct jbusmc_obp_mem_layout
*p
= _prop
;
245 cache_line_offset
= qword_code
;
246 offset_inverse
= (JBUS_LAST_BIT
- cache_line_offset
);
247 dimm_map_index
= offset_inverse
/ 8;
248 map_val
= p
->map
.dimm_map
[dimm_map_index
];
249 map_val
= ((map_val
>> ((7 - (offset_inverse
& 7)))) & 1);
250 *dimm_str_p
= p
->dimm_labels
[base_dimm_offset
+ map_val
];
251 *pin_p
= p
->map
.pin_map
[cache_line_offset
];
253 struct chmc_obp_mem_layout
*p
= _prop
;
254 struct chmc_obp_map
*mp
;
263 qword
= (paddr
& L2_LINE_ADDR_MSK
) / QW_BYTES
;
264 cache_line_offset
= ((3 - qword
) * QW_BITS
) + qword_code
;
265 offset_inverse
= (SAFARI_LAST_BIT
- cache_line_offset
);
266 dimm_map_index
= offset_inverse
>> 2;
267 map_val
= mp
->dimm_map
[dimm_map_index
];
268 map_val
= ((map_val
>> ((3 - (offset_inverse
& 3)) << 1)) & 0x3);
269 *dimm_str_p
= p
->dimm_labels
[base_dimm_offset
+ map_val
];
270 *pin_p
= mp
->pin_map
[cache_line_offset
];
274 static struct jbusmc_dimm_group
*jbusmc_find_dimm_group(unsigned long phys_addr
)
278 list_for_each_entry(p
, &mctrl_list
, list
) {
281 for (i
= 0; i
< p
->num_dimm_groups
; i
++) {
282 struct jbusmc_dimm_group
*dp
= &p
->dimm_groups
[i
];
284 if (phys_addr
< dp
->base_addr
||
285 (dp
->base_addr
+ dp
->size
) <= phys_addr
)
294 static int jbusmc_print_dimm(int syndrome_code
,
295 unsigned long phys_addr
,
296 char *buf
, int buflen
)
298 struct jbusmc_obp_mem_layout
*prop
;
299 struct jbusmc_dimm_group
*dp
;
303 dp
= jbusmc_find_dimm_group(phys_addr
);
305 syndrome_code
< SYNDROME_MIN
||
306 syndrome_code
> SYNDROME_MAX
) {
316 first_dimm
= dp
->index
* JB_NUM_DIMMS_PER_GROUP
;
318 if (syndrome_code
!= SYNDROME_MIN
) {
322 get_pin_and_dimm_str(syndrome_code
, phys_addr
, &pin
,
323 &dimm_str
, prop
, first_dimm
);
324 sprintf(buf
, "%s, pin %3d", dimm_str
, pin
);
328 /* Multi-bit error, we just dump out all the
329 * dimm labels associated with this dimm group.
331 for (dimm
= 0; dimm
< JB_NUM_DIMMS_PER_GROUP
; dimm
++) {
333 prop
->dimm_labels
[first_dimm
+ dimm
]);
341 static u64
jbusmc_dimm_group_size(u64 base
,
342 const struct linux_prom64_registers
*mem_regs
,
345 u64 max
= base
+ (8UL * 1024 * 1024 * 1024);
349 for (i
= 0; i
< num_mem_regs
; i
++) {
350 const struct linux_prom64_registers
*ent
;
355 this_base
= ent
->phys_addr
;
356 this_end
= this_base
+ ent
->reg_size
;
357 if (base
< this_base
|| base
>= this_end
)
361 if (this_end
> max_seen
)
365 return max_seen
- base
;
368 static void jbusmc_construct_one_dimm_group(struct jbusmc
*p
,
370 const struct linux_prom64_registers
*mem_regs
,
373 struct jbusmc_dimm_group
*dp
= &p
->dimm_groups
[index
];
378 dp
->base_addr
= (p
->portid
* (64UL * 1024 * 1024 * 1024));
379 dp
->base_addr
+= (index
* (8UL * 1024 * 1024 * 1024));
380 dp
->size
= jbusmc_dimm_group_size(dp
->base_addr
, mem_regs
, num_mem_regs
);
383 static void jbusmc_construct_dimm_groups(struct jbusmc
*p
,
384 const struct linux_prom64_registers
*mem_regs
,
387 if (p
->mc_reg_1
& JB_MC_REG1_DIMM1_BANK0
) {
388 jbusmc_construct_one_dimm_group(p
, 0, mem_regs
, num_mem_regs
);
389 p
->num_dimm_groups
++;
391 if (p
->mc_reg_1
& JB_MC_REG1_DIMM2_BANK2
) {
392 jbusmc_construct_one_dimm_group(p
, 1, mem_regs
, num_mem_regs
);
393 p
->num_dimm_groups
++;
397 static int jbusmc_probe(struct platform_device
*op
)
399 const struct linux_prom64_registers
*mem_regs
;
400 struct device_node
*mem_node
;
401 int err
, len
, num_mem_regs
;
407 mem_node
= of_find_node_by_path("/memory");
409 printk(KERN_ERR PFX
"Cannot find /memory node.\n");
412 mem_regs
= of_get_property(mem_node
, "reg", &len
);
414 printk(KERN_ERR PFX
"Cannot get reg property of /memory node.\n");
417 num_mem_regs
= len
/ sizeof(*mem_regs
);
420 p
= kzalloc(sizeof(*p
), GFP_KERNEL
);
422 printk(KERN_ERR PFX
"Cannot allocate struct jbusmc.\n");
426 INIT_LIST_HEAD(&p
->list
);
429 prop
= of_get_property(op
->dev
.of_node
, "portid", &len
);
430 if (!prop
|| len
!= 4) {
431 printk(KERN_ERR PFX
"Cannot find portid.\n");
437 prop
= of_get_property(op
->dev
.of_node
, "memory-control-register-1", &len
);
438 if (!prop
|| len
!= 8) {
439 printk(KERN_ERR PFX
"Cannot get memory control register 1.\n");
443 p
->mc_reg_1
= ((u64
)prop
[0] << 32) | (u64
) prop
[1];
446 p
->regs
= of_ioremap(&op
->resource
[0], 0, JBUSMC_REGS_SIZE
, "jbusmc");
448 printk(KERN_ERR PFX
"Cannot map jbusmc regs.\n");
453 ml
= of_get_property(op
->dev
.of_node
, "memory-layout", &p
->layout_len
);
455 printk(KERN_ERR PFX
"Cannot get memory layout property.\n");
458 if (p
->layout_len
> sizeof(p
->layout
)) {
459 printk(KERN_ERR PFX
"Unexpected memory-layout size %d\n",
463 memcpy(&p
->layout
, ml
, p
->layout_len
);
465 jbusmc_construct_dimm_groups(p
, mem_regs
, num_mem_regs
);
467 mc_list_add(&p
->list
);
469 printk(KERN_INFO PFX
"UltraSPARC-IIIi memory controller at %pOF\n",
472 dev_set_drvdata(&op
->dev
, p
);
480 of_iounmap(&op
->resource
[0], p
->regs
, JBUSMC_REGS_SIZE
);
487 /* Does BANK decode PHYS_ADDR? */
488 static int chmc_bank_match(struct chmc_bank_info
*bp
, unsigned long phys_addr
)
490 unsigned long upper_bits
= (phys_addr
& PA_UPPER_BITS
) >> PA_UPPER_BITS_SHIFT
;
491 unsigned long lower_bits
= (phys_addr
& PA_LOWER_BITS
) >> PA_LOWER_BITS_SHIFT
;
493 /* Bank must be enabled to match. */
497 /* Would BANK match upper bits? */
498 upper_bits
^= bp
->um
; /* What bits are different? */
499 upper_bits
= ~upper_bits
; /* Invert. */
500 upper_bits
|= bp
->uk
; /* What bits don't matter for matching? */
501 upper_bits
= ~upper_bits
; /* Invert. */
506 /* Would BANK match lower bits? */
507 lower_bits
^= bp
->lm
; /* What bits are different? */
508 lower_bits
= ~lower_bits
; /* Invert. */
509 lower_bits
|= bp
->lk
; /* What bits don't matter for matching? */
510 lower_bits
= ~lower_bits
; /* Invert. */
515 /* I always knew you'd be the one. */
519 /* Given PHYS_ADDR, search memory controller banks for a match. */
520 static struct chmc_bank_info
*chmc_find_bank(unsigned long phys_addr
)
524 list_for_each_entry(p
, &mctrl_list
, list
) {
527 for (bank_no
= 0; bank_no
< CHMCTRL_NBANKS
; bank_no
++) {
528 struct chmc_bank_info
*bp
;
530 bp
= &p
->logical_banks
[bank_no
];
531 if (chmc_bank_match(bp
, phys_addr
))
539 /* This is the main purpose of this driver. */
540 static int chmc_print_dimm(int syndrome_code
,
541 unsigned long phys_addr
,
542 char *buf
, int buflen
)
544 struct chmc_bank_info
*bp
;
545 struct chmc_obp_mem_layout
*prop
;
546 int bank_in_controller
, first_dimm
;
548 bp
= chmc_find_bank(phys_addr
);
550 syndrome_code
< SYNDROME_MIN
||
551 syndrome_code
> SYNDROME_MAX
) {
559 prop
= &bp
->p
->layout_prop
;
560 bank_in_controller
= bp
->bank_id
& (CHMCTRL_NBANKS
- 1);
561 first_dimm
= (bank_in_controller
& (CHMCTRL_NDGRPS
- 1));
562 first_dimm
*= CHMCTRL_NDIMMS
;
564 if (syndrome_code
!= SYNDROME_MIN
) {
568 get_pin_and_dimm_str(syndrome_code
, phys_addr
, &pin
,
569 &dimm_str
, prop
, first_dimm
);
570 sprintf(buf
, "%s, pin %3d", dimm_str
, pin
);
574 /* Multi-bit error, we just dump out all the
575 * dimm labels associated with this bank.
577 for (dimm
= 0; dimm
< CHMCTRL_NDIMMS
; dimm
++) {
579 prop
->dimm_labels
[first_dimm
+ dimm
]);
586 /* Accessing the registers is slightly complicated. If you want
587 * to get at the memory controller which is on the same processor
588 * the code is executing, you must use special ASI load/store else
589 * you go through the global mapping.
591 static u64
chmc_read_mcreg(struct chmc
*p
, unsigned long offset
)
593 unsigned long ret
, this_cpu
;
597 this_cpu
= real_hard_smp_processor_id();
599 if (p
->portid
== this_cpu
) {
600 __asm__
__volatile__("ldxa [%1] %2, %0"
602 : "r" (offset
), "i" (ASI_MCU_CTRL_REG
));
604 __asm__
__volatile__("ldxa [%1] %2, %0"
606 : "r" (p
->regs
+ offset
),
607 "i" (ASI_PHYS_BYPASS_EC_E
));
615 #if 0 /* currently unused */
616 static void chmc_write_mcreg(struct chmc
*p
, unsigned long offset
, u64 val
)
618 if (p
->portid
== smp_processor_id()) {
619 __asm__
__volatile__("stxa %0, [%1] %2"
621 "r" (offset
), "i" (ASI_MCU_CTRL_REG
));
623 __asm__
__volatile__("ldxa %0, [%1] %2"
625 "r" (p
->regs
+ offset
),
626 "i" (ASI_PHYS_BYPASS_EC_E
));
631 static void chmc_interpret_one_decode_reg(struct chmc
*p
, int which_bank
, u64 val
)
633 struct chmc_bank_info
*bp
= &p
->logical_banks
[which_bank
];
636 bp
->bank_id
= (CHMCTRL_NBANKS
* p
->portid
) + which_bank
;
638 bp
->valid
= (val
& MEM_DECODE_VALID
) >> MEM_DECODE_VALID_SHIFT
;
639 bp
->uk
= (val
& MEM_DECODE_UK
) >> MEM_DECODE_UK_SHIFT
;
640 bp
->um
= (val
& MEM_DECODE_UM
) >> MEM_DECODE_UM_SHIFT
;
641 bp
->lk
= (val
& MEM_DECODE_LK
) >> MEM_DECODE_LK_SHIFT
;
642 bp
->lm
= (val
& MEM_DECODE_LM
) >> MEM_DECODE_LM_SHIFT
;
645 bp
->base
&= ~(bp
->uk
);
646 bp
->base
<<= PA_UPPER_BITS_SHIFT
;
671 /* UK[10] is reserved, and UK[11] is not set for the SDRAM
672 * bank size definition.
674 bp
->size
= (((unsigned long)bp
->uk
&
675 ((1UL << 10UL) - 1UL)) + 1UL) << PA_UPPER_BITS_SHIFT
;
676 bp
->size
/= bp
->interleave
;
679 static void chmc_fetch_decode_regs(struct chmc
*p
)
681 if (p
->layout_size
== 0)
684 chmc_interpret_one_decode_reg(p
, 0,
685 chmc_read_mcreg(p
, CHMCTRL_DECODE1
));
686 chmc_interpret_one_decode_reg(p
, 1,
687 chmc_read_mcreg(p
, CHMCTRL_DECODE2
));
688 chmc_interpret_one_decode_reg(p
, 2,
689 chmc_read_mcreg(p
, CHMCTRL_DECODE3
));
690 chmc_interpret_one_decode_reg(p
, 3,
691 chmc_read_mcreg(p
, CHMCTRL_DECODE4
));
694 static int chmc_probe(struct platform_device
*op
)
696 struct device_node
*dp
= op
->dev
.of_node
;
704 __asm__ ("rdpr %%ver, %0" : "=r" (ver
));
705 if ((ver
>> 32UL) == __JALAPENO_ID
||
706 (ver
>> 32UL) == __SERRANO_ID
)
709 portid
= of_getintprop_default(dp
, "portid", -1);
713 pval
= of_get_property(dp
, "memory-layout", &len
);
714 if (pval
&& len
> sizeof(p
->layout_prop
)) {
715 printk(KERN_ERR PFX
"Unexpected memory-layout property "
721 p
= kzalloc(sizeof(*p
), GFP_KERNEL
);
723 printk(KERN_ERR PFX
"Could not allocate struct chmc.\n");
728 p
->layout_size
= len
;
732 memcpy(&p
->layout_prop
, pval
, len
);
734 p
->regs
= of_ioremap(&op
->resource
[0], 0, 0x48, "chmc");
736 printk(KERN_ERR PFX
"Could not map registers.\n");
740 if (p
->layout_size
!= 0UL) {
741 p
->timing_control1
= chmc_read_mcreg(p
, CHMCTRL_TCTRL1
);
742 p
->timing_control2
= chmc_read_mcreg(p
, CHMCTRL_TCTRL2
);
743 p
->timing_control3
= chmc_read_mcreg(p
, CHMCTRL_TCTRL3
);
744 p
->timing_control4
= chmc_read_mcreg(p
, CHMCTRL_TCTRL4
);
745 p
->memaddr_control
= chmc_read_mcreg(p
, CHMCTRL_MACTRL
);
748 chmc_fetch_decode_regs(p
);
750 mc_list_add(&p
->list
);
752 printk(KERN_INFO PFX
"UltraSPARC-III memory controller at %pOF [%s]\n",
754 (p
->layout_size
? "ACTIVE" : "INACTIVE"));
756 dev_set_drvdata(&op
->dev
, p
);
768 static int us3mc_probe(struct platform_device
*op
)
770 if (mc_type
== MC_TYPE_SAFARI
)
771 return chmc_probe(op
);
772 else if (mc_type
== MC_TYPE_JBUS
)
773 return jbusmc_probe(op
);
777 static void chmc_destroy(struct platform_device
*op
, struct chmc
*p
)
780 of_iounmap(&op
->resource
[0], p
->regs
, 0x48);
784 static void jbusmc_destroy(struct platform_device
*op
, struct jbusmc
*p
)
786 mc_list_del(&p
->list
);
787 of_iounmap(&op
->resource
[0], p
->regs
, JBUSMC_REGS_SIZE
);
791 static void us3mc_remove(struct platform_device
*op
)
793 void *p
= dev_get_drvdata(&op
->dev
);
796 if (mc_type
== MC_TYPE_SAFARI
)
798 else if (mc_type
== MC_TYPE_JBUS
)
799 jbusmc_destroy(op
, p
);
803 static const struct of_device_id us3mc_match
[] = {
805 .name
= "memory-controller",
809 MODULE_DEVICE_TABLE(of
, us3mc_match
);
811 static struct platform_driver us3mc_driver
= {
814 .of_match_table
= us3mc_match
,
816 .probe
= us3mc_probe
,
817 .remove_new
= us3mc_remove
,
820 static inline bool us3mc_platform(void)
822 if (tlb_type
== cheetah
|| tlb_type
== cheetah_plus
)
827 static int __init
us3mc_init(void)
832 if (!us3mc_platform())
835 __asm__
__volatile__("rdpr %%ver, %0" : "=r" (ver
));
836 if ((ver
>> 32UL) == __JALAPENO_ID
||
837 (ver
>> 32UL) == __SERRANO_ID
) {
838 mc_type
= MC_TYPE_JBUS
;
839 us3mc_dimm_printer
= jbusmc_print_dimm
;
841 mc_type
= MC_TYPE_SAFARI
;
842 us3mc_dimm_printer
= chmc_print_dimm
;
845 ret
= register_dimm_printer(us3mc_dimm_printer
);
848 ret
= platform_driver_register(&us3mc_driver
);
850 unregister_dimm_printer(us3mc_dimm_printer
);
855 static void __exit
us3mc_cleanup(void)
857 if (us3mc_platform()) {
858 unregister_dimm_printer(us3mc_dimm_printer
);
859 platform_driver_unregister(&us3mc_driver
);
863 module_init(us3mc_init
);
864 module_exit(us3mc_cleanup
);