mirror of
https://git.proxmox.com/git/fwupd
synced 2025-06-03 13:41:12 +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
|
||||
* @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
|
||||
* @timeout: (nullable): timeout in ms for the retry action, see %FU_UDEV_DEVICE_FLAG_IOCTL_RETRY
|
||||
* @error: (nullable): optional return location for an error
|
||||
*
|
||||
* Control a device using a low-level request.
|
||||
*
|
||||
* Returns: %TRUE for success
|
||||
*
|
||||
* Since: 1.3.3
|
||||
* Since: 1.8.1
|
||||
**/
|
||||
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
|
||||
FuUdevDevicePrivate *priv = GET_PRIVATE(self);
|
||||
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(request != 0x0, FALSE);
|
||||
@ -1411,7 +1418,14 @@ fu_udev_device_ioctl(FuUdevDevice *self, gulong request, guint8 *buf, gint *rc,
|
||||
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)
|
||||
*rc = rc_tmp;
|
||||
if (rc_tmp < 0) {
|
||||
@ -1443,6 +1457,26 @@ fu_udev_device_ioctl(FuUdevDevice *self, gulong request, guint8 *buf, gint *rc,
|
||||
#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:
|
||||
* @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_OPEN_NONBLOCK: Open nonblocking, e.g. O_NONBLOCK
|
||||
* @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().
|
||||
**/
|
||||
@ -45,6 +46,7 @@ typedef enum {
|
||||
FU_UDEV_DEVICE_FLAG_USE_CONFIG = 1 << 3,
|
||||
FU_UDEV_DEVICE_FLAG_OPEN_NONBLOCK = 1 << 4,
|
||||
FU_UDEV_DEVICE_FLAG_OPEN_SYNC = 1 << 5,
|
||||
FU_UDEV_DEVICE_FLAG_IOCTL_RETRY = 1 << 6,
|
||||
/*< private >*/
|
||||
FU_UDEV_DEVICE_FLAG_LAST
|
||||
} FuUdevDeviceFlags;
|
||||
@ -102,6 +104,13 @@ gboolean
|
||||
fu_udev_device_ioctl(FuUdevDevice *self, gulong request, guint8 *buf, gint *rc, GError **error)
|
||||
G_GNUC_WARN_UNUSED_RESULT;
|
||||
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)
|
||||
G_GNUC_WARN_UNUSED_RESULT;
|
||||
gboolean
|
||||
|
@ -1034,3 +1034,9 @@ LIBFWUPDPLUGIN_1.8.0 {
|
||||
fu_uswid_firmware_new;
|
||||
local: *;
|
||||
} 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