|
@@ -53,6 +53,137 @@ void rt_dm_secondary_cpu_init(void)
|
|
|
}
|
|
|
#endif /* RT_USING_SMP */
|
|
|
|
|
|
+/**
|
|
|
+ * @brief This function will alloc an id in an IDA object
|
|
|
+ *
|
|
|
+ * @param ida is the IDA object
|
|
|
+ *
|
|
|
+ * @return the id or -RT_EEMPTY
|
|
|
+ */
|
|
|
+int rt_dm_ida_alloc(struct rt_dm_ida *ida)
|
|
|
+{
|
|
|
+ int id;
|
|
|
+ RT_ASSERT(ida != RT_NULL);
|
|
|
+
|
|
|
+ rt_spin_lock(&ida->lock);
|
|
|
+
|
|
|
+ id = rt_bitmap_next_clear_bit(ida->map, 0, RT_DM_IDA_NUM);
|
|
|
+
|
|
|
+ if (id != RT_DM_IDA_NUM)
|
|
|
+ {
|
|
|
+ rt_bitmap_set_bit(ida->map, id);
|
|
|
+ }
|
|
|
+
|
|
|
+ rt_spin_unlock(&ida->lock);
|
|
|
+
|
|
|
+ if (id != RT_DM_IDA_NUM)
|
|
|
+ {
|
|
|
+ return id;
|
|
|
+ }
|
|
|
+
|
|
|
+ return -RT_EEMPTY;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * @brief This function will take (force) an id in an IDA object
|
|
|
+ *
|
|
|
+ * @param ida is the IDA object
|
|
|
+ *
|
|
|
+ * @param id is the id that want to take
|
|
|
+ *
|
|
|
+ * @return the result of taking
|
|
|
+ */
|
|
|
+rt_bool_t rt_dm_ida_take(struct rt_dm_ida *ida, int id)
|
|
|
+{
|
|
|
+ RT_ASSERT(ida != RT_NULL);
|
|
|
+ RT_ASSERT(id >= 0);
|
|
|
+
|
|
|
+ rt_spin_lock(&ida->lock);
|
|
|
+
|
|
|
+ if (!rt_bitmap_test_bit(ida->map, id))
|
|
|
+ {
|
|
|
+ rt_bitmap_set_bit(ida->map, id);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ id = RT_DM_IDA_NUM;
|
|
|
+ }
|
|
|
+
|
|
|
+ rt_spin_unlock(&ida->lock);
|
|
|
+
|
|
|
+ return id != RT_DM_IDA_NUM;
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * @brief This function will release an id in an IDA object
|
|
|
+ *
|
|
|
+ * @param ida is the IDA object
|
|
|
+ *
|
|
|
+ * @param id is the id of IDA object
|
|
|
+ */
|
|
|
+void rt_dm_ida_free(struct rt_dm_ida *ida, int id)
|
|
|
+{
|
|
|
+ RT_ASSERT(ida != RT_NULL);
|
|
|
+ RT_ASSERT(id >= 0);
|
|
|
+
|
|
|
+ rt_spin_lock(&ida->lock);
|
|
|
+
|
|
|
+ rt_bitmap_clear_bit(ida->map, id);
|
|
|
+
|
|
|
+ rt_spin_unlock(&ida->lock);
|
|
|
+}
|
|
|
+
|
|
|
+/**
|
|
|
+ * @brief This function will return the specified master id and device id of device.
|
|
|
+ *
|
|
|
+ * @param master_id is the master id (0, 255] of device
|
|
|
+ *
|
|
|
+ * @param device_id is the device id [-1, 255] of device, when device_id is -1,
|
|
|
+ * the function will end when find the first device.
|
|
|
+ *
|
|
|
+ * @return the device object or RT_NULL
|
|
|
+ */
|
|
|
+rt_device_t rt_dm_device_find(int master_id, int device_id)
|
|
|
+{
|
|
|
+ struct rt_device *dev, *ret_dev = RT_NULL;
|
|
|
+ struct rt_object_information *information = RT_NULL;
|
|
|
+
|
|
|
+ if (master_id <= 0 || device_id > 255)
|
|
|
+ {
|
|
|
+ return RT_NULL;
|
|
|
+ }
|
|
|
+
|
|
|
+ information = rt_object_get_information(RT_Object_Class_Device);
|
|
|
+
|
|
|
+ /* parameter check */
|
|
|
+ if (!information)
|
|
|
+ {
|
|
|
+ return RT_NULL;
|
|
|
+ }
|
|
|
+
|
|
|
+ /* which is invoke in interrupt status */
|
|
|
+ RT_DEBUG_NOT_IN_INTERRUPT;
|
|
|
+
|
|
|
+ /* enter critical */
|
|
|
+ rt_enter_critical();
|
|
|
+
|
|
|
+ /* try to find object */
|
|
|
+ rt_list_for_each_entry(dev, &information->object_list, parent.list)
|
|
|
+ {
|
|
|
+ if (master_id == dev->master_id &&
|
|
|
+ (device_id == -1 || device_id == dev->device_id))
|
|
|
+ {
|
|
|
+ ret_dev = dev;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /* leave critical */
|
|
|
+ rt_exit_critical();
|
|
|
+
|
|
|
+ return ret_dev;
|
|
|
+}
|
|
|
+
|
|
|
struct prefix_track
|
|
|
{
|
|
|
rt_list_t list;
|