mirror of
https://git.proxmox.com/git/fwupd
synced 2025-06-05 08:36:40 +00:00
Retry the device ioctl for EAGAIN
This commit is contained in:
parent
e803ed30f5
commit
2fcdf352df
@ -1375,25 +1375,32 @@ fu_udev_device_close(FuDevice *device, GError **error)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fu_udev_device_ioctl:
|
* fu_udev_device_ioctl_full:
|
||||||
* @self: a #FuUdevDevice
|
* @self: a #FuUdevDevice
|
||||||
* @request: request number
|
* @request: request number
|
||||||
* @buf: a buffer to use, which *must* be large enough for the request
|
* @buf: a buffer to use, which *must* be large enough for the request
|
||||||
* @rc: (out) (nullable): the raw return value from the ioctl
|
* @rc: (out) (nullable): the raw return value from the ioctl
|
||||||
|
* @timeout: (nullable): timeout in ms for the retry action, see %FU_UDEV_DEVICE_FLAG_IOCTL_RETRY
|
||||||
* @error: (nullable): optional return location for an error
|
* @error: (nullable): optional return location for an error
|
||||||
*
|
*
|
||||||
* Control a device using a low-level request.
|
* Control a device using a low-level request.
|
||||||
*
|
*
|
||||||
* Returns: %TRUE for success
|
* Returns: %TRUE for success
|
||||||
*
|
*
|
||||||
* Since: 1.3.3
|
* Since: 1.8.1
|
||||||
**/
|
**/
|
||||||
gboolean
|
gboolean
|
||||||
fu_udev_device_ioctl(FuUdevDevice *self, gulong request, guint8 *buf, gint *rc, GError **error)
|
fu_udev_device_ioctl_full(FuUdevDevice *self,
|
||||||
|
gulong request,
|
||||||
|
guint8 *buf,
|
||||||
|
gint *rc,
|
||||||
|
guint timeout,
|
||||||
|
GError **error)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_IOCTL_H
|
#ifdef HAVE_IOCTL_H
|
||||||
FuUdevDevicePrivate *priv = GET_PRIVATE(self);
|
FuUdevDevicePrivate *priv = GET_PRIVATE(self);
|
||||||
gint rc_tmp;
|
gint rc_tmp;
|
||||||
|
g_autoptr(GTimer) timer = g_timer_new();
|
||||||
|
|
||||||
g_return_val_if_fail(FU_IS_UDEV_DEVICE(self), FALSE);
|
g_return_val_if_fail(FU_IS_UDEV_DEVICE(self), FALSE);
|
||||||
g_return_val_if_fail(request != 0x0, FALSE);
|
g_return_val_if_fail(request != 0x0, FALSE);
|
||||||
@ -1411,7 +1418,14 @@ fu_udev_device_ioctl(FuUdevDevice *self, gulong request, guint8 *buf, gint *rc,
|
|||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc_tmp = ioctl(priv->fd, request, buf);
|
/* poll if required up to the timeout */
|
||||||
|
do {
|
||||||
|
rc_tmp = ioctl(priv->fd, request, buf);
|
||||||
|
if (rc_tmp >= 0)
|
||||||
|
break;
|
||||||
|
} while ((priv->flags & FU_UDEV_DEVICE_FLAG_IOCTL_RETRY) &&
|
||||||
|
(errno == EINTR || errno == EAGAIN) &&
|
||||||
|
g_timer_elapsed(timer, NULL) < timeout * 1000.f);
|
||||||
if (rc != NULL)
|
if (rc != NULL)
|
||||||
*rc = rc_tmp;
|
*rc = rc_tmp;
|
||||||
if (rc_tmp < 0) {
|
if (rc_tmp < 0) {
|
||||||
@ -1443,6 +1457,26 @@ fu_udev_device_ioctl(FuUdevDevice *self, gulong request, guint8 *buf, gint *rc,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fu_udev_device_ioctl:
|
||||||
|
* @self: a #FuUdevDevice
|
||||||
|
* @request: request number
|
||||||
|
* @buf: a buffer to use, which *must* be large enough for the request
|
||||||
|
* @rc: (out) (nullable): the raw return value from the ioctl
|
||||||
|
* @error: (nullable): optional return location for an error
|
||||||
|
*
|
||||||
|
* Control a device using a low-level request.
|
||||||
|
*
|
||||||
|
* Returns: %TRUE for success
|
||||||
|
*
|
||||||
|
* Since: 1.3.3
|
||||||
|
**/
|
||||||
|
gboolean
|
||||||
|
fu_udev_device_ioctl(FuUdevDevice *self, gulong request, guint8 *buf, gint *rc, GError **error)
|
||||||
|
{
|
||||||
|
return fu_udev_device_ioctl_full(self, request, buf, rc, 0, error);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* fu_udev_device_pread_full:
|
* fu_udev_device_pread_full:
|
||||||
* @self: a #FuUdevDevice
|
* @self: a #FuUdevDevice
|
||||||
|
@ -34,6 +34,7 @@ struct _FuUdevDeviceClass {
|
|||||||
* @FU_UDEV_DEVICE_FLAG_USE_CONFIG: Read and write from the device config
|
* @FU_UDEV_DEVICE_FLAG_USE_CONFIG: Read and write from the device config
|
||||||
* @FU_UDEV_DEVICE_FLAG_OPEN_NONBLOCK: Open nonblocking, e.g. O_NONBLOCK
|
* @FU_UDEV_DEVICE_FLAG_OPEN_NONBLOCK: Open nonblocking, e.g. O_NONBLOCK
|
||||||
* @FU_UDEV_DEVICE_FLAG_OPEN_SYNC: Open sync, e.g. O_SYNC
|
* @FU_UDEV_DEVICE_FLAG_OPEN_SYNC: Open sync, e.g. O_SYNC
|
||||||
|
* @FU_UDEV_DEVICE_FLAG_IOCTL_RETRY: Retry the ioctl() call when required
|
||||||
*
|
*
|
||||||
* Flags used when opening the device using fu_device_open().
|
* Flags used when opening the device using fu_device_open().
|
||||||
**/
|
**/
|
||||||
@ -45,6 +46,7 @@ typedef enum {
|
|||||||
FU_UDEV_DEVICE_FLAG_USE_CONFIG = 1 << 3,
|
FU_UDEV_DEVICE_FLAG_USE_CONFIG = 1 << 3,
|
||||||
FU_UDEV_DEVICE_FLAG_OPEN_NONBLOCK = 1 << 4,
|
FU_UDEV_DEVICE_FLAG_OPEN_NONBLOCK = 1 << 4,
|
||||||
FU_UDEV_DEVICE_FLAG_OPEN_SYNC = 1 << 5,
|
FU_UDEV_DEVICE_FLAG_OPEN_SYNC = 1 << 5,
|
||||||
|
FU_UDEV_DEVICE_FLAG_IOCTL_RETRY = 1 << 6,
|
||||||
/*< private >*/
|
/*< private >*/
|
||||||
FU_UDEV_DEVICE_FLAG_LAST
|
FU_UDEV_DEVICE_FLAG_LAST
|
||||||
} FuUdevDeviceFlags;
|
} FuUdevDeviceFlags;
|
||||||
@ -102,6 +104,13 @@ gboolean
|
|||||||
fu_udev_device_ioctl(FuUdevDevice *self, gulong request, guint8 *buf, gint *rc, GError **error)
|
fu_udev_device_ioctl(FuUdevDevice *self, gulong request, guint8 *buf, gint *rc, GError **error)
|
||||||
G_GNUC_WARN_UNUSED_RESULT;
|
G_GNUC_WARN_UNUSED_RESULT;
|
||||||
gboolean
|
gboolean
|
||||||
|
fu_udev_device_ioctl_full(FuUdevDevice *self,
|
||||||
|
gulong request,
|
||||||
|
guint8 *buf,
|
||||||
|
gint *rc,
|
||||||
|
guint timeout,
|
||||||
|
GError **error) G_GNUC_WARN_UNUSED_RESULT;
|
||||||
|
gboolean
|
||||||
fu_udev_device_pwrite(FuUdevDevice *self, goffset port, guint8 data, GError **error)
|
fu_udev_device_pwrite(FuUdevDevice *self, goffset port, guint8 data, GError **error)
|
||||||
G_GNUC_WARN_UNUSED_RESULT;
|
G_GNUC_WARN_UNUSED_RESULT;
|
||||||
gboolean
|
gboolean
|
||||||
|
@ -1034,3 +1034,9 @@ LIBFWUPDPLUGIN_1.8.0 {
|
|||||||
fu_uswid_firmware_new;
|
fu_uswid_firmware_new;
|
||||||
local: *;
|
local: *;
|
||||||
} LIBFWUPDPLUGIN_1.7.7;
|
} LIBFWUPDPLUGIN_1.7.7;
|
||||||
|
|
||||||
|
LIBFWUPDPLUGIN_1.8.1 {
|
||||||
|
global:
|
||||||
|
fu_udev_device_ioctl_full;
|
||||||
|
local: *;
|
||||||
|
} LIBFWUPDPLUGIN_1.8.0;
|
||||||
|
Loading…
Reference in New Issue
Block a user