From af87b83d4cfa02864fdb178916f6aa127f0029f9 Mon Sep 17 00:00:00 2001 From: MacRsh Date: Fri, 26 Apr 2024 00:23:49 +0800 Subject: [PATCH] =?UTF-8?q?1.=E8=AE=BE=E5=A4=87=E6=94=AF=E6=8C=81=E6=8C=82?= =?UTF-8?q?=E8=BD=BD/=E5=8D=B8=E8=BD=BD=E6=A3=80=E6=B5=8B=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- device/pin/pin.c | 2 +- device/serial/serial.c | 5 ++-- include/mr_def.h | 3 +++ source/device.c | 52 ++++++++++++++++++++++++++++++++---------- 4 files changed, 46 insertions(+), 16 deletions(-) diff --git a/device/pin/pin.c b/device/pin/pin.c index 15dc48d..253ba84 100644 --- a/device/pin/pin.c +++ b/device/pin/pin.c @@ -288,7 +288,7 @@ int mr_pin_register(struct mr_pin *pin, const char *path, MR_ASSERT(path != NULL); MR_ASSERT((driver != NULL) && (driver->ops != NULL)); - /* Register the pin device */ + /* Register the pin */ return mr_device_register((struct mr_device *)pin, path, MR_DEVICE_TYPE_PIN | MR_DEVICE_TYPE_FULL_DUPLEX, &ops, driver); diff --git a/device/serial/serial.c b/device/serial/serial.c index efd1d58..f2ec72b 100644 --- a/device/serial/serial.c +++ b/device/serial/serial.c @@ -192,8 +192,7 @@ static ssize_t serial_write(struct mr_device *device, int pos, const void *buf, static int serial_ioctl(struct mr_device *device, int pos, int cmd, void *args) { struct mr_serial *serial = (struct mr_serial *)device; - struct mr_driver *driver = - _MR_DEVICE_DRIVER_GET((struct mr_device *)serial); + struct mr_driver *driver = _MR_DEVICE_DRIVER_GET(device); struct mr_serial_driver_ops *ops = _MR_DRIVER_OPS_GET(driver); switch (cmd) @@ -469,7 +468,7 @@ int mr_serial_register(struct mr_serial *serial, const char *path, serial->wfifo_size = MR_CFG_SERIAL_WR_FIFO_SIZE; serial->state = 0; - /* Register the serial device */ + /* Register the serial */ return mr_device_register( (struct mr_device *)serial, path, MR_DEVICE_TYPE_SERIAL | MR_DEVICE_TYPE_FULL_DUPLEX, &ops, driver); diff --git a/include/mr_def.h b/include/mr_def.h index 2206d84..e192839 100644 --- a/include/mr_def.h +++ b/include/mr_def.h @@ -214,6 +214,9 @@ struct mr_device_ops size_t count); int (*ioctl)(struct mr_device *device, int pos, int cmd, void *args); int (*isr)(struct mr_device *device, uint32_t event, void *args); + + int (*attach)(struct mr_device *device, struct mr_device *source); + int (*detach)(struct mr_device *device, struct mr_device *source); }; /** diff --git a/source/device.c b/source/device.c index e6c0947..535e9e0 100644 --- a/source/device.c +++ b/source/device.c @@ -110,6 +110,16 @@ static int _device_register_iter(struct mr_device *device, const char *path, return MR_EEXIST; } + /* Notify the parent device that the child device will be attached */ + if (parent->ops->attach != NULL) + { + int ret = parent->ops->attach(parent, device); + if (ret < 0) + { + return ret; + } + } + /* Register the device */ device->magic = _MAGIC_NUMBER; strncpy(device->name, path, sizeof(device->name)); @@ -292,7 +302,7 @@ MR_INLINE int _device_take(struct mr_device *device, int descriptor, uint32_t lock; int ret; - /* If the device is not FDX, the read/write must be locked */ + /* If the device is not FDX, the read/writing must be locked */ mask = (device->full_duplex == true) ? mask : _MR_OPERATE_MASK_ALL; /* Calculate the lock mask, since the descriptor can be 0, need to add 1 */ @@ -321,7 +331,7 @@ MR_INLINE int _device_take(struct mr_device *device, int descriptor, MR_INLINE void _device_release(struct mr_device *device, uint32_t mask) { - /* If the device is not FDX, the read/write must be locked */ + /* If the device is not FDX, the read/writing must be locked */ mask = (device->full_duplex == true) ? mask : _MR_OPERATE_MASK_ALL; /* Release the device lock */ @@ -418,28 +428,46 @@ static int _device_register(struct mr_device *device, const char *path, /* Critical section exit */ mr_critical_exit(); + return ret; } static int _device_unregister(struct mr_device *device) { + struct mr_device *parent = device->parent; int ret; /* Critical section enter */ mr_critical_enter(); /* Unregister the device only when there are no more references to it */ - if (device->ref_count == 0) - { - device->magic = 0; - mr_list_remove(&device->list); - device->parent = NULL; - ret = MR_EOK; - } else + if (device->ref_count > 0) { ret = MR_EBUSY; + goto _exit; } + /* Try to detach the device from its parent */ + mr_list_remove(&device->list); + + /* Notify the parent device that the child device will be detached */ + if (parent->ops->detach != NULL) + { + ret = parent->ops->detach(parent, device); + if (ret < 0) + { + /* Revert the list operation */ + mr_list_insert_before(&parent->clist, &device->list); + goto _exit; + } + } + + /* Unregister the device */ + device->magic = 0; + device->parent = NULL; + ret = MR_EOK; + +_exit: /* Critical section exit */ mr_critical_exit(); return ret; @@ -513,7 +541,7 @@ static int _device_open(const char *path, uint32_t flags) return ret; } - /* Device will only be opened the first time it is accessed */ + /* The Device will only be opened the first time it is accessed */ if ((device->ref_count == 0) && (device->ops->open != NULL)) { ret = device->ops->open(device); @@ -555,7 +583,7 @@ static int _device_close(int descriptor) return ret; } - /* Device will only be closed the last time it is accessed */ + /* The Device will only be closed the last time it is accessed */ if ((device->ref_count == 1) && (device->ops->close != NULL)) { ret = device->ops->close(device); @@ -651,7 +679,7 @@ static ssize_t _device_write(int descriptor, const void *buf, size_t count) /* Get the position */ pos = _descriptor_map[descriptor].pos; - /* Async or sync write */ + /* Async or sync writes */ if (_descriptor_flags_is_valid(descriptor, MR_FLAG_WRONLY_ASYNC) == true) { /* Async write */