Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F144934892
D6632.1776953283.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D6632.1776953283.diff
View Options
Index: head/sys/kern/bus_if.m
===================================================================
--- head/sys/kern/bus_if.m
+++ head/sys/kern/bus_if.m
@@ -418,6 +418,35 @@
};
/**
+ * @brief Map an interrupt
+ *
+ * This method is used to get an interrupt mapping data according to provided
+ * hints. The hints could be modified afterwards, but only if mapping data was
+ * allocated. This method is intended to be called before BUS_ALLOC_RESOURCE().
+ *
+ * @param _dev the parent device of @p _child
+ * @param _child the device which is requesting an allocation
+ * @param _rid a pointer to the resource identifier
+ * @param _start a pointer to the hint at the start of the resource
+ * range - pass @c 0 for any start address
+ * @param _end a pointer to the hint at the end of the resource
+ * range - pass @c ~0 for any end address
+ * @param _count a pointer to the hint at the size of resource
+ * range required - pass @c 1 for any size
+ * @param _imd a pointer to the interrupt mapping data which was
+ * allocated
+ */
+METHOD int map_intr {
+ device_t _dev;
+ device_t _child;
+ int *_rid;
+ rman_res_t *_start;
+ rman_res_t *_end;
+ rman_res_t *_count;
+ struct intr_map_data **_imd;
+} DEFAULT bus_generic_map_intr;
+
+/**
* @brief Install an interrupt handler
*
* This method is used to associate an interrupt handler function with
Index: head/sys/kern/subr_bus.c
===================================================================
--- head/sys/kern/subr_bus.c
+++ head/sys/kern/subr_bus.c
@@ -3951,6 +3951,23 @@
}
/**
+ * @brief Helper function for implementing BUS_MAP_INTR().
+ *
+ * This simple implementation of BUS_MAP_INTR() simply calls the
+ * BUS_MAP_INTR() method of the parent of @p dev.
+ */
+int
+bus_generic_map_intr(device_t dev, device_t child, int *rid, rman_res_t *start,
+ rman_res_t *end, rman_res_t *count, struct intr_map_data **imd)
+{
+ /* Propagate up the bus hierarchy until someone handles it. */
+ if (dev->parent)
+ return (BUS_MAP_INTR(dev->parent, child, rid, start, end, count,
+ imd));
+ return (EINVAL);
+}
+
+/**
* @brief Helper function for implementing BUS_SETUP_INTR().
*
* This simple implementation of BUS_SETUP_INTR() simply calls the
@@ -4405,6 +4422,41 @@
}
}
+#ifdef INTRNG
+/**
+ * @internal
+ *
+ * This can be converted to bus method later. (XXX)
+ */
+static struct intr_map_data *
+bus_extend_resource(device_t dev, int type, int *rid, rman_res_t *start,
+ rman_res_t *end, rman_res_t *count)
+{
+ struct intr_map_data *imd;
+ struct resource_list *rl;
+ int rv;
+
+ if (dev->parent == NULL)
+ return (NULL);
+ if (type != SYS_RES_IRQ)
+ return (NULL);
+
+ if (!RMAN_IS_DEFAULT_RANGE(*start, *end))
+ return (NULL);
+ rl = BUS_GET_RESOURCE_LIST(dev->parent, dev);
+ if (rl != NULL) {
+ if (resource_list_find(rl, type, *rid) != NULL)
+ return (NULL);
+ }
+ rv = BUS_MAP_INTR(dev->parent, dev, rid, start, end, count, &imd);
+ if (rv != 0)
+ return (NULL);
+ if (rl != NULL)
+ resource_list_add(rl, type, *rid, *start, *end, *count);
+ return (imd);
+}
+#endif
+
/**
* @brief Wrapper function for BUS_ALLOC_RESOURCE().
*
@@ -4412,13 +4464,31 @@
* parent of @p dev.
*/
struct resource *
-bus_alloc_resource(device_t dev, int type, int *rid, rman_res_t start, rman_res_t end,
- rman_res_t count, u_int flags)
+bus_alloc_resource(device_t dev, int type, int *rid, rman_res_t start,
+ rman_res_t end, rman_res_t count, u_int flags)
{
+ struct resource *res;
+#ifdef INTRNG
+ struct intr_map_data *imd;
+#endif
+
if (dev->parent == NULL)
return (NULL);
- return (BUS_ALLOC_RESOURCE(dev->parent, dev, type, rid, start, end,
- count, flags));
+
+#ifdef INTRNG
+ imd = bus_extend_resource(dev, type, rid, &start, &end, &count);
+#endif
+ res = BUS_ALLOC_RESOURCE(dev->parent, dev, type, rid, start, end,
+ count, flags);
+#ifdef INTRNG
+ if (imd != NULL) {
+ if (res != NULL && rman_get_virtual(res) == NULL)
+ rman_set_virtual(res, imd);
+ else
+ imd->destruct(imd);
+ }
+#endif
+ return (res);
}
/**
@@ -4503,9 +4573,23 @@
int
bus_release_resource(device_t dev, int type, int rid, struct resource *r)
{
+ int rv;
+#ifdef INTRNG
+ struct intr_map_data *imd;
+#endif
+
if (dev->parent == NULL)
return (EINVAL);
- return (BUS_RELEASE_RESOURCE(dev->parent, dev, type, rid, r));
+
+#ifdef INTRNG
+ imd = (type == SYS_RES_IRQ) ? rman_get_virtual(r) : NULL;
+#endif
+ rv = BUS_RELEASE_RESOURCE(dev->parent, dev, type, rid, r);
+#ifdef INTRNG
+ if (imd != NULL)
+ imd->destruct(imd);
+#endif
+ return (rv);
}
/**
Index: head/sys/kern/subr_intr.c
===================================================================
--- head/sys/kern/subr_intr.c
+++ head/sys/kern/subr_intr.c
@@ -560,7 +560,6 @@
mtx_unlock(&isrc_table_lock);
ddata->idd_data = (struct intr_map_data *)((uintptr_t)ddata + size);
- ddata->idd_data->size = extsize;
return (ddata);
}
Index: head/sys/sys/bus.h
===================================================================
--- head/sys/sys/bus.h
+++ head/sys/sys/bus.h
@@ -272,6 +272,17 @@
INTR_POLARITY_LOW = 2
};
+enum intr_map_data_type {
+ INTR_MAP_DATA_ACPI,
+ INTR_MAP_DATA_FDT,
+ INTR_MAP_DATA_GPIO,
+};
+
+struct intr_map_data {
+ enum intr_map_data_type type;
+ void (*destruct)(struct intr_map_data *);
+};
+
/**
* CPU sets supported by bus_get_cpus(). Note that not all sets may be
* supported for a given device. If a request is not supported by a
@@ -448,6 +459,9 @@
int type, int rid, struct resource *r);
int bus_generic_resume(device_t dev);
int bus_generic_resume_child(device_t dev, device_t child);
+int bus_generic_map_intr(device_t dev, device_t child, int *rid,
+ rman_res_t *start, rman_res_t *end,
+ rman_res_t *count, struct intr_map_data **imd);
int bus_generic_setup_intr(device_t dev, device_t child,
struct resource *irq, int flags,
driver_filter_t *filter, driver_intr_t *intr,
Index: head/sys/sys/intr.h
===================================================================
--- head/sys/sys/intr.h
+++ head/sys/sys/intr.h
@@ -34,17 +34,6 @@
#define INTR_IRQ_INVALID 0xFFFFFFFF
-enum intr_map_data_type {
- INTR_MAP_DATA_ACPI,
- INTR_MAP_DATA_FDT,
- INTR_MAP_DATA_GPIO,
-};
-
-struct intr_map_data {
- enum intr_map_data_type type;
- size_t size;
-};
-
#ifdef DEV_ACPI
struct intr_map_data_acpi {
struct intr_map_data hdr;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Apr 23, 2:08 PM (1 h, 47 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28417431
Default Alt Text
D6632.1776953283.diff (6 KB)
Attached To
Mode
D6632: INTRNG generalization step 2 - extending struct resource
Attached
Detach File
Event Timeline
Log In to Comment