Page MenuHomeFreeBSD

D32504.id97088.diff
No OneTemporary

D32504.id97088.diff

Index: sys/arm/mv/gpio.c
===================================================================
--- sys/arm/mv/gpio.c
+++ sys/arm/mv/gpio.c
@@ -430,7 +430,7 @@
} else if (sc->gpio_setup[pin].gp_flags & MV_GPIO_IN_IRQ_DOUBLE_EDGE)
mv_gpio_double_edge_init(dev, pin);
MV_GPIO_UNLOCK();
- error = intr_event_create(&event, (void *)s, 0, pin,
+ error = intr_event_create(&event, (void *)s, 0,
(void (*)(void *))mv_gpio_intr_mask,
(void (*)(void *))mv_gpio_intr_unmask,
(void (*)(void *))mv_gpio_int_ack,
Index: sys/compat/linuxkpi/common/include/linux/hardirq.h
===================================================================
--- sys/compat/linuxkpi/common/include/linux/hardirq.h
+++ sys/compat/linuxkpi/common/include/linux/hardirq.h
@@ -37,7 +37,8 @@
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/interrupt.h>
+#include <sys/intr_compat.h>
-#define synchronize_irq(irq) _intr_drain((irq))
+#define synchronize_irq(irq) _intr_drain(intr_get_event(irq))
#endif /* _LINUX_HARDIRQ_H_ */
Index: sys/compat/linuxkpi/common/include/linux/interrupt.h
===================================================================
--- sys/compat/linuxkpi/common/include/linux/interrupt.h
+++ sys/compat/linuxkpi/common/include/linux/interrupt.h
@@ -39,6 +39,7 @@
#include <sys/param.h>
#include <sys/interrupt.h>
+#include <sys/intr_compat.h>
typedef irqreturn_t (*irq_handler_t)(int, void *);
@@ -116,9 +117,11 @@
int error;
if (mask != NULL)
- error = intr_setaffinity(vector, CPU_WHICH_IRQ, mask);
+ error = intr_setaffinity(intr_get_event(vector), CPU_WHICH_IRQ,
+ mask);
else
- error = intr_setaffinity(vector, CPU_WHICH_IRQ, cpuset_root);
+ error = intr_setaffinity(intr_get_event(vector), CPU_WHICH_IRQ,
+ cpuset_root);
return (-error);
}
Index: sys/dev/mlx5/mlx5_en/mlx5_en_main.c
===================================================================
--- sys/dev/mlx5/mlx5_en/mlx5_en_main.c
+++ sys/dev/mlx5/mlx5_en/mlx5_en_main.c
@@ -31,6 +31,7 @@
#include <sys/eventhandler.h>
#include <sys/sockio.h>
+#include <sys/intr_compat.h>
#include <machine/atomic.h>
#include <net/debugnet.h>
@@ -2463,7 +2464,8 @@
CPU_ZERO(&cpuset);
CPU_SET(cpu, &cpuset);
- intr_setaffinity(irq, CPU_WHICH_INTRHANDLER, &cpuset);
+ intr_setaffinity(intr_get_event(irq),
+ CPU_WHICH_INTRHANDLER, &cpuset);
}
}
Index: sys/kern/kern_cpuset.c
===================================================================
--- sys/kern/kern_cpuset.c
+++ sys/kern/kern_cpuset.c
@@ -60,6 +60,7 @@
#include <sys/limits.h>
#include <sys/bus.h>
#include <sys/interrupt.h>
+#include <sys/intr_compat.h>
#include <sys/vmmeter.h>
#include <vm/uma.h>
@@ -1957,7 +1958,7 @@
case CPU_WHICH_IRQ:
case CPU_WHICH_INTRHANDLER:
case CPU_WHICH_ITHREAD:
- error = intr_getaffinity(id, which, mask);
+ error = intr_getaffinity(intr_get_event(id), which, mask);
break;
case CPU_WHICH_DOMAIN:
if (id < 0 || id >= MAXMEMDOM)
@@ -2090,7 +2091,7 @@
case CPU_WHICH_IRQ:
case CPU_WHICH_INTRHANDLER:
case CPU_WHICH_ITHREAD:
- error = intr_setaffinity(id, which, mask);
+ error = intr_setaffinity(intr_get_event(id), which, mask);
break;
default:
error = EINVAL;
Index: sys/kern/kern_intr.c
===================================================================
--- sys/kern/kern_intr.c
+++ sys/kern/kern_intr.c
@@ -280,7 +280,7 @@
}
int
-intr_event_create(struct intr_event **event, void *source, int flags, int irq,
+intr_event_create(struct intr_event **event, void *source, int flags,
void (*pre_ithread)(void *), void (*post_ithread)(void *),
void (*post_filter)(void *), int (*assign_cpu)(void *, int),
const char *fmt, ...)
@@ -298,7 +298,6 @@
ie->ie_post_filter = post_filter;
ie->ie_assign_cpu = assign_cpu;
ie->ie_flags = flags;
- ie->ie_irq = irq;
ie->ie_cpu = NOCPU;
CK_SLIST_INIT(&ie->ie_handlers);
mtx_init(&ie->ie_lock, "intr event", NULL, MTX_DEF);
@@ -431,25 +430,9 @@
return (ENODEV);
}
-static struct intr_event *
-intr_lookup(int irq)
-{
- struct intr_event *ie;
-
- mtx_lock(&event_lock);
- TAILQ_FOREACH(ie, &event_list, ie_list)
- if (ie->ie_irq == irq &&
- (ie->ie_flags & IE_SOFT) == 0 &&
- CK_SLIST_FIRST(&ie->ie_handlers) != NULL)
- break;
- mtx_unlock(&event_lock);
- return (ie);
-}
-
int
-intr_setaffinity(int irq, int mode, void *m)
+intr_setaffinity(struct intr_event *ie, int mode, void *m)
{
- struct intr_event *ie;
cpuset_t *mask;
int cpu, n;
@@ -468,7 +451,6 @@
cpu = n;
}
}
- ie = intr_lookup(irq);
if (ie == NULL)
return (ESRCH);
switch (mode) {
@@ -484,9 +466,8 @@
}
int
-intr_getaffinity(int irq, int mode, void *m)
+intr_getaffinity(struct intr_event *ie, int mode, void *m)
{
- struct intr_event *ie;
struct thread *td;
struct proc *p;
cpuset_t *mask;
@@ -494,7 +475,6 @@
int error;
mask = m;
- ie = intr_lookup(irq);
if (ie == NULL)
return (ESRCH);
@@ -814,13 +794,11 @@
* Do not use in BSD code.
*/
void
-_intr_drain(int irq)
+_intr_drain(struct intr_event *ie)
{
- struct intr_event *ie;
struct intr_thread *ithd;
struct thread *td;
- ie = intr_lookup(irq);
if (ie == NULL)
return;
if (ie->ie_thread == NULL)
@@ -1069,8 +1047,8 @@
if (!(ie->ie_flags & IE_SOFT))
return (EINVAL);
} else {
- error = intr_event_create(&ie, NULL, IE_SOFT, 0,
- NULL, NULL, NULL, swi_assign_cpu, "swi%d:", pri);
+ error = intr_event_create(&ie, NULL, IE_SOFT, NULL, NULL, NULL,
+ swi_assign_cpu, "swi%d:", pri);
if (error)
return (error);
if (eventp != NULL)
Index: sys/kern/subr_intr.c
===================================================================
--- sys/kern/subr_intr.c
+++ sys/kern/subr_intr.c
@@ -51,6 +51,7 @@
#include <sys/queue.h>
#include <sys/bus.h>
#include <sys/interrupt.h>
+#include <sys/intr_compat.h>
#include <sys/taskqueue.h>
#include <sys/tree.h>
#include <sys/conf.h>
@@ -511,6 +512,29 @@
return (error);
}
+/*
+ * Lookup an interrupt source by number.
+ */
+struct intr_irqsrc *
+intr_isrc_lookup(u_int irq)
+{
+ if (irq >= intr_nirq)
+ return (NULL);
+ return (irq_sources[irq]);
+}
+
+/*
+ * Retrieve a pointer to an interrupt's event.
+ */
+struct intr_event **
+intr_get_eventp(u_int irq)
+{
+ struct intr_irqsrc *const isrc = intr_isrc_lookup(irq);
+ if (isrc == NULL)
+ return (NULL);
+ return (&isrc->isrc_event);
+}
+
#ifdef SMP
/*
* A support function for a PIC to decide if provided ISRC should be inited
@@ -650,8 +674,8 @@
struct intr_event *ie;
int error;
- error = intr_event_create(&ie, isrc, 0, isrc->isrc_irq,
- intr_isrc_pre_ithread, intr_isrc_post_ithread, intr_isrc_post_filter,
+ error = intr_event_create(&ie, isrc, 0, intr_isrc_pre_ithread,
+ intr_isrc_post_ithread, intr_isrc_post_filter,
intr_isrc_assign_cpu, "%s:", isrc->isrc_name);
if (error)
return (error);
Index: sys/mips/atheros/apb.c
===================================================================
--- sys/mips/atheros/apb.c
+++ sys/mips/atheros/apb.c
@@ -298,10 +298,8 @@
event = sc->sc_eventstab[irq];
if (event == NULL) {
- error = intr_event_create(&event, (void *)irq, 0, irq,
- apb_mask_irq, apb_unmask_irq,
- NULL, NULL,
- "apb intr%d:", irq);
+ error = intr_event_create(&event, (void *)irq, 0, apb_mask_irq,
+ apb_unmask_irq, NULL, NULL, "apb intr%d:", irq);
if (error == 0) {
sc->sc_eventstab[irq] = event;
Index: sys/mips/atheros/ar531x/apb.c
===================================================================
--- sys/mips/atheros/ar531x/apb.c
+++ sys/mips/atheros/ar531x/apb.c
@@ -408,9 +408,9 @@
irq = rman_get_start(ires);
isrc = PIC_INTR_ISRC(sc, irq);
if(isrc->isrc_event == 0) {
- error = intr_event_create(&isrc->isrc_event, (void *)irq,
- 0, irq, apb_mask_irq, apb_unmask_irq,
- NULL, NULL, "apb intr%d:", irq);
+ error = intr_event_create(&isrc->isrc_event, (void *)irq, 0,
+ apb_mask_irq, apb_unmask_irq, NULL, NULL,
+ "apb intr%d:", irq);
if(error != 0)
return(error);
}
@@ -426,10 +426,8 @@
event = sc->sc_eventstab[irq];
if (event == NULL) {
- error = intr_event_create(&event, (void *)irq, 0, irq,
- apb_mask_irq, apb_unmask_irq,
- NULL, NULL,
- "apb intr%d:", irq);
+ error = intr_event_create(&event, (void *)irq, 0, apb_mask_irq,
+ apb_unmask_irq, NULL, NULL, "apb intr%d:", irq);
if (error == 0) {
sc->sc_eventstab[irq] = event;
Index: sys/mips/atheros/ar71xx_pci.c
===================================================================
--- sys/mips/atheros/ar71xx_pci.c
+++ sys/mips/atheros/ar71xx_pci.c
@@ -568,7 +568,7 @@
event = sc->sc_eventstab[irq];
if (event == NULL) {
- error = intr_event_create(&event, (void *)irq, 0, irq,
+ error = intr_event_create(&event, (void *)irq, 0,
ar71xx_pci_mask_irq, ar71xx_pci_unmask_irq, NULL, NULL,
"pci intr%d:", irq);
Index: sys/mips/atheros/ar724x_pci.c
===================================================================
--- sys/mips/atheros/ar724x_pci.c
+++ sys/mips/atheros/ar724x_pci.c
@@ -542,7 +542,7 @@
event = sc->sc_eventstab[irq];
if (event == NULL) {
- error = intr_event_create(&event, (void *)irq, 0, irq,
+ error = intr_event_create(&event, (void *)irq, 0,
ar724x_pci_mask_irq, ar724x_pci_unmask_irq, NULL, NULL,
"pci intr%d:", irq);
Index: sys/mips/atheros/qca955x_pci.c
===================================================================
--- sys/mips/atheros/qca955x_pci.c
+++ sys/mips/atheros/qca955x_pci.c
@@ -469,11 +469,8 @@
sc->sc_pci_irq[irq].sc = sc;
sc->sc_pci_irq[irq].irq = irq;
error = intr_event_create(&event, (void *)&sc->sc_pci_irq[irq],
- 0, irq,
- qca955x_pci_mask_irq,
- qca955x_pci_unmask_irq,
- NULL, NULL,
- "pci intr%d:", irq);
+ 0, qca955x_pci_mask_irq, qca955x_pci_unmask_irq,
+ NULL, NULL, "pci intr%d:", irq);
if (error == 0) {
sc->sc_eventstab[irq] = event;
Index: sys/mips/cavium/ciu.c
===================================================================
--- sys/mips/cavium/ciu.c
+++ sys/mips/cavium/ciu.c
@@ -240,7 +240,7 @@
if ((event = *eventp) == NULL) {
error = intr_event_create(eventp, (void *)(uintptr_t)irq, 0,
- irq, mask_func, unmask_func, NULL, bind_func, "int%d", irq);
+ mask_func, unmask_func, NULL, bind_func, "int%d", irq);
if (error != 0)
return (error);
Index: sys/mips/malta/gt_pci.c
===================================================================
--- sys/mips/malta/gt_pci.c
+++ sys/mips/malta/gt_pci.c
@@ -708,9 +708,8 @@
sc->sc_intr_cookies[irq].sc = sc;
if (event == NULL) {
error = intr_event_create(&event,
- (void *)&sc->sc_intr_cookies[irq], 0, irq,
- gt_pci_mask_irq, gt_pci_unmask_irq,
- NULL, NULL, "gt_pci intr%d:", irq);
+ (void *)&sc->sc_intr_cookies[irq], 0, gt_pci_mask_irq,
+ gt_pci_unmask_irq, NULL, NULL, "gt_pci intr%d:", irq);
if (error)
return 0;
sc->sc_eventstab[irq] = event;
Index: sys/mips/mediatek/mtk_pcie.c
===================================================================
--- sys/mips/mediatek/mtk_pcie.c
+++ sys/mips/mediatek/mtk_pcie.c
@@ -543,7 +543,7 @@
event = sc->sc_eventstab[irqidx];
if (event == NULL) {
- error = intr_event_create(&event, (void *)irq, 0, irq,
+ error = intr_event_create(&event, (void *)irq, 0,
mtk_pci_mask_irq, mtk_pci_unmask_irq, NULL, NULL,
"pci intr%d:", irq);
Index: sys/mips/mips/intr_machdep.c
===================================================================
--- sys/mips/mips/intr_machdep.c
+++ sys/mips/mips/intr_machdep.c
@@ -194,7 +194,7 @@
event = hardintr_events[irq];
if (event == NULL) {
error = intr_event_create(&event, (void *)(uintptr_t)irq, 0,
- irq, hardintr_mask_func, hardintr_unmask_func,
+ hardintr_mask_func, hardintr_unmask_func,
NULL, NULL, "int%d", irq);
if (error)
return;
@@ -227,7 +227,7 @@
event = softintr_events[irq];
if (event == NULL) {
error = intr_event_create(&event, (void *)(uintptr_t)irq, 0,
- irq, mips_mask_soft_irq, mips_unmask_soft_irq,
+ mips_mask_soft_irq, mips_unmask_soft_irq,
NULL, NULL, "sint%d:", irq);
if (error)
return;
Index: sys/mips/nlm/intr_machdep.c
===================================================================
--- sys/mips/nlm/intr_machdep.c
+++ sys/mips/nlm/intr_machdep.c
@@ -200,13 +200,13 @@
* components need additional acks (e.g. PCI)
*/
if (XLP_IRQ_IS_PICINTR(irq))
- errcode = intr_event_create(&ie, src, 0, irq,
+ errcode = intr_event_create(&ie, src, 0,
xlp_pre_ithread, xlp_post_ithread, xlp_post_filter,
NULL, "hard intr%d:", irq);
else {
if (filt == NULL)
panic("Unsupported non filter percpu intr %d", irq);
- errcode = intr_event_create(&ie, src, 0, irq,
+ errcode = intr_event_create(&ie, src, 0,
NULL, NULL, NULL, NULL, "hard intr%d:", irq);
}
if (errcode) {
Index: sys/powerpc/powerpc/intr_machdep.c
===================================================================
--- sys/powerpc/powerpc/intr_machdep.c
+++ sys/powerpc/powerpc/intr_machdep.c
@@ -71,6 +71,7 @@
#include <sys/bus.h>
#include <sys/cpuset.h>
#include <sys/interrupt.h>
+#include <sys/intr_compat.h>
#include <sys/ktr.h>
#include <sys/lock.h>
#include <sys/malloc.h>
@@ -290,6 +291,21 @@
return (i);
}
+extern struct intr_event **
+intr_get_eventp(u_int intr)
+{
+ struct powerpc_intr *i;
+ int vector;
+
+ for (vector = 0; vector < nvectors; vector++) {
+ i = powerpc_intrs[vector];
+ if (i != NULL && i->irq == intr)
+ return (&i->event);
+ }
+
+ return (NULL);
+}
+
static int
powerpc_map_irq(struct powerpc_intr *i)
{
@@ -527,7 +543,7 @@
return (ENOMEM);
if (i->event == NULL) {
- error = intr_event_create(&i->event, (void *)i, 0, irq,
+ error = intr_event_create(&i->event, (void *)i, 0,
powerpc_intr_pre_ithread, powerpc_intr_post_ithread,
powerpc_intr_eoi, powerpc_assign_intr_cpu, "irq%u:", irq);
if (error)
Index: sys/riscv/riscv/intr_machdep.c
===================================================================
--- sys/riscv/riscv/intr_machdep.c
+++ sys/riscv/riscv/intr_machdep.c
@@ -126,7 +126,7 @@
isrc = &isrcs[irq].isrc;
if (isrc->isrc_event == NULL) {
- error = intr_event_create(&isrc->isrc_event, isrc, 0, irq,
+ error = intr_event_create(&isrc->isrc_event, isrc, 0,
riscv_mask_irq, riscv_unmask_irq, NULL, NULL, "int%d", irq);
if (error)
return (error);
Index: sys/sys/interrupt.h
===================================================================
--- sys/sys/interrupt.h
+++ sys/sys/interrupt.h
@@ -123,7 +123,6 @@
int ie_count; /* Loop counter. */
int ie_warncnt; /* Rate-check interrupt storm warns. */
struct timeval ie_warntm;
- int ie_irq; /* Physical irq number if !SOFT. */
int ie_cpu; /* CPU this event is bound to. */
volatile int ie_phase; /* Switched to establish a barrier. */
volatile int ie_active[2]; /* Filters in ISR context. */
@@ -175,11 +174,10 @@
struct _cpuset;
int intr_event_bind_ithread_cpuset(struct intr_event *ie,
struct _cpuset *mask);
-int intr_event_create(struct intr_event **event, void *source,
- int flags, int irq, void (*pre_ithread)(void *),
- void (*post_ithread)(void *), void (*post_filter)(void *),
- int (*assign_cpu)(void *, int), const char *fmt, ...)
- __printflike(9, 10);
+int intr_event_create(struct intr_event **event, void *source, int flags,
+ void (*pre_ithread)(void *), void (*post_ithread)(void *),
+ void (*post_filter)(void *), int (*assign_cpu)(void *, int),
+ const char *fmt, ...) __printflike(8, 9);
int intr_event_describe_handler(struct intr_event *ie, void *cookie,
const char *descr);
int intr_event_destroy(struct intr_event *ie);
@@ -187,10 +185,10 @@
int intr_event_remove_handler(void *cookie);
int intr_event_suspend_handler(void *cookie);
int intr_event_resume_handler(void *cookie);
-int intr_getaffinity(int irq, int mode, void *mask);
+int intr_getaffinity(struct intr_event *ie, int mode, void *mask);
void *intr_handler_source(void *cookie);
-int intr_setaffinity(int irq, int mode, void *mask);
-void _intr_drain(int irq); /* LinuxKPI only. */
+int intr_setaffinity(struct intr_event *ie, int mode, void *mask);
+void _intr_drain(struct intr_event *ie); /* LinuxKPI only. */
int swi_add(struct intr_event **eventp, const char *name,
driver_intr_t handler, void *arg, int pri, enum intr_type flags,
void **cookiep);
Index: sys/sys/intr.h
===================================================================
--- sys/sys/intr.h
+++ sys/sys/intr.h
@@ -102,6 +102,7 @@
int intr_isrc_deregister(struct intr_irqsrc *);
int intr_isrc_register(struct intr_irqsrc *, device_t, u_int, const char *, ...)
__printflike(4, 5);
+struct intr_irqsrc *intr_isrc_lookup(u_int irq);
#ifdef SMP
bool intr_isrc_init_on_cpu(struct intr_irqsrc *isrc, u_int cpu);
Index: sys/sys/intr_compat.h
===================================================================
--- /dev/null
+++ sys/sys/intr_compat.h
@@ -0,0 +1,43 @@
+/*
+ * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+ *
+ * Copyright (c) 2021 Elliott Mitchell
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef _SYS_INTR_COMPAT_H_
+#define _SYS_INTR_COMPAT_H_
+
+#include <sys/interrupt.h>
+
+/*
+ * Retrieve a pointer to a pointer to an interrupt's event structure
+ */
+extern struct intr_event **intr_get_eventp(u_int intr);
+
+/*
+ * Retrieve a pointer to an interrupt's event structure
+ */
+#define intr_get_event(irq) ({ struct intr_event **pp=intr_get_eventp(irq); pp == NULL ? NULL : *pp; })
+
+#endif
Index: sys/x86/x86/intr_machdep.c
===================================================================
--- sys/x86/x86/intr_machdep.c
+++ sys/x86/x86/intr_machdep.c
@@ -42,6 +42,7 @@
#include <sys/param.h>
#include <sys/bus.h>
#include <sys/interrupt.h>
+#include <sys/intr_compat.h>
#include <sys/ktr.h>
#include <sys/kernel.h>
#include <sys/lock.h>
@@ -230,7 +231,7 @@
return (EINVAL);
if (interrupt_sources[vector] != NULL)
return (EEXIST);
- error = intr_event_create(&isrc->is_event, isrc, 0, vector,
+ error = intr_event_create(&isrc->is_event, isrc, 0,
intr_disable_src, (mask_fn)isrc->is_pic->pic_enable_source,
(mask_fn)isrc->is_pic->pic_eoi_source, intr_assign_cpu, "irq%d:",
vector);
@@ -258,6 +259,15 @@
return (interrupt_sources[vector]);
}
+struct intr_event **
+intr_get_eventp(u_int irq)
+{
+ struct intsrc *const isrc = intr_lookup_source(irq);
+ if (isrc == NULL)
+ return (NULL);
+ return (&isrc->is_event);
+}
+
int
intr_add_handler(const char *name, int vector, driver_filter_t filter,
driver_intr_t handler, void *arg, enum intr_type flags, void **cookiep,

File Metadata

Mime Type
text/plain
Expires
Wed, Oct 22, 8:34 PM (1 h, 34 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
24066546
Default Alt Text
D32504.id97088.diff (19 KB)

Event Timeline