]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
Input: iforce - use guard notation when acquiring mutex and spinlock
authorDmitry Torokhov <dmitry.torokhov@gmail.com>
Wed, 4 Sep 2024 04:31:00 +0000 (21:31 -0700)
committerDmitry Torokhov <dmitry.torokhov@gmail.com>
Thu, 3 Oct 2024 16:07:31 +0000 (09:07 -0700)
Using guard notation makes the code more compact and error handling
more robust by ensuring that locks are released in all code paths
when control leaves critical section.

Link: https://lore.kernel.org/r/20240904043104.1030257-4-dmitry.torokhov@gmail.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
drivers/input/joystick/iforce/iforce-ff.c
drivers/input/joystick/iforce/iforce-packets.c
drivers/input/joystick/iforce/iforce-serio.c
drivers/input/joystick/iforce/iforce-usb.c

index 95c0348843e6b40ae35498f14c3c33872467365a..8c78cbe553c8ccd851923fe23129c8dfc1a28987 100644 (file)
@@ -21,14 +21,13 @@ static int make_magnitude_modifier(struct iforce* iforce,
        unsigned char data[3];
 
        if (!no_alloc) {
-               mutex_lock(&iforce->mem_mutex);
-               if (allocate_resource(&(iforce->device_memory), mod_chunk, 2,
-                       iforce->device_memory.start, iforce->device_memory.end, 2L,
-                       NULL, NULL)) {
-                       mutex_unlock(&iforce->mem_mutex);
+               guard(mutex)(&iforce->mem_mutex);
+
+               if (allocate_resource(&iforce->device_memory, mod_chunk, 2,
+                                     iforce->device_memory.start,
+                                     iforce->device_memory.end,
+                                     2L, NULL, NULL))
                        return -ENOSPC;
-               }
-               mutex_unlock(&iforce->mem_mutex);
        }
 
        data[0] = LO(mod_chunk->start);
@@ -54,14 +53,13 @@ static int make_period_modifier(struct iforce* iforce,
        period = TIME_SCALE(period);
 
        if (!no_alloc) {
-               mutex_lock(&iforce->mem_mutex);
-               if (allocate_resource(&(iforce->device_memory), mod_chunk, 0x0c,
-                       iforce->device_memory.start, iforce->device_memory.end, 2L,
-                       NULL, NULL)) {
-                       mutex_unlock(&iforce->mem_mutex);
+               guard(mutex)(&iforce->mem_mutex);
+
+               if (allocate_resource(&iforce->device_memory, mod_chunk, 0x0c,
+                                     iforce->device_memory.start,
+                                     iforce->device_memory.end,
+                                     2L, NULL, NULL))
                        return -ENOSPC;
-               }
-               mutex_unlock(&iforce->mem_mutex);
        }
 
        data[0] = LO(mod_chunk->start);
@@ -94,14 +92,13 @@ static int make_envelope_modifier(struct iforce* iforce,
        fade_duration = TIME_SCALE(fade_duration);
 
        if (!no_alloc) {
-               mutex_lock(&iforce->mem_mutex);
+               guard(mutex)(&iforce->mem_mutex);
+
                if (allocate_resource(&(iforce->device_memory), mod_chunk, 0x0e,
-                       iforce->device_memory.start, iforce->device_memory.end, 2L,
-                       NULL, NULL)) {
-                       mutex_unlock(&iforce->mem_mutex);
+                                     iforce->device_memory.start,
+                                     iforce->device_memory.end,
+                                     2L, NULL, NULL))
                        return -ENOSPC;
-               }
-               mutex_unlock(&iforce->mem_mutex);
        }
 
        data[0] = LO(mod_chunk->start);
@@ -131,14 +128,13 @@ static int make_condition_modifier(struct iforce* iforce,
        unsigned char data[10];
 
        if (!no_alloc) {
-               mutex_lock(&iforce->mem_mutex);
+               guard(mutex)(&iforce->mem_mutex);
+
                if (allocate_resource(&(iforce->device_memory), mod_chunk, 8,
-                       iforce->device_memory.start, iforce->device_memory.end, 2L,
-                       NULL, NULL)) {
-                       mutex_unlock(&iforce->mem_mutex);
+                                     iforce->device_memory.start,
+                                     iforce->device_memory.end,
+                                     2L, NULL, NULL))
                        return -ENOSPC;
-               }
-               mutex_unlock(&iforce->mem_mutex);
        }
 
        data[0] = LO(mod_chunk->start);
index 763642c8cee9f538415524e48411c7da33a91f65..8c2531e2977c13fd5ab995d958d23718a6bd3e8e 100644 (file)
@@ -31,49 +31,42 @@ int iforce_send_packet(struct iforce *iforce, u16 cmd, unsigned char* data)
        int c;
        int empty;
        int head, tail;
-       unsigned long flags;
 
 /*
  * Update head and tail of xmit buffer
  */
-       spin_lock_irqsave(&iforce->xmit_lock, flags);
-
-       head = iforce->xmit.head;
-       tail = iforce->xmit.tail;
-
-
-       if (CIRC_SPACE(head, tail, XMIT_SIZE) < n+2) {
-               dev_warn(&iforce->dev->dev,
-                        "not enough space in xmit buffer to send new packet\n");
-               spin_unlock_irqrestore(&iforce->xmit_lock, flags);
-               return -1;
-       }
+       scoped_guard(spinlock_irqsave, &iforce->xmit_lock) {
+               head = iforce->xmit.head;
+               tail = iforce->xmit.tail;
+
+               if (CIRC_SPACE(head, tail, XMIT_SIZE) < n + 2) {
+                       dev_warn(&iforce->dev->dev,
+                                "not enough space in xmit buffer to send new packet\n");
+                       return -1;
+               }
 
-       empty = head == tail;
-       XMIT_INC(iforce->xmit.head, n+2);
+               empty = head == tail;
+               XMIT_INC(iforce->xmit.head, n + 2);
 
 /*
  * Store packet in xmit buffer
  */
-       iforce->xmit.buf[head] = HI(cmd);
-       XMIT_INC(head, 1);
-       iforce->xmit.buf[head] = LO(cmd);
-       XMIT_INC(head, 1);
-
-       c = CIRC_SPACE_TO_END(head, tail, XMIT_SIZE);
-       if (n < c) c=n;
-
-       memcpy(&iforce->xmit.buf[head],
-              data,
-              c);
-       if (n != c) {
-               memcpy(&iforce->xmit.buf[0],
-                      data + c,
-                      n - c);
+               iforce->xmit.buf[head] = HI(cmd);
+               XMIT_INC(head, 1);
+               iforce->xmit.buf[head] = LO(cmd);
+               XMIT_INC(head, 1);
+
+               c = CIRC_SPACE_TO_END(head, tail, XMIT_SIZE);
+               if (n < c)
+                       c = n;
+
+               memcpy(&iforce->xmit.buf[head], data, c);
+               if (n != c)
+                       memcpy(&iforce->xmit.buf[0], data + c, n - c);
+
+               XMIT_INC(head, n);
        }
-       XMIT_INC(head, n);
 
-       spin_unlock_irqrestore(&iforce->xmit_lock, flags);
 /*
  * If necessary, start the transmission
  */
index 2380546d79782d5b5dee309a65818f7299b6bff4..75b85c46dfa419d1b6892e4e3c95eb34d68fd0e3 100644 (file)
@@ -28,45 +28,39 @@ static void iforce_serio_xmit(struct iforce *iforce)
                                                         iforce);
        unsigned char cs;
        int i;
-       unsigned long flags;
 
        if (test_and_set_bit(IFORCE_XMIT_RUNNING, iforce->xmit_flags)) {
                set_bit(IFORCE_XMIT_AGAIN, iforce->xmit_flags);
                return;
        }
 
-       spin_lock_irqsave(&iforce->xmit_lock, flags);
+       guard(spinlock_irqsave)(&iforce->xmit_lock);
 
-again:
-       if (iforce->xmit.head == iforce->xmit.tail) {
-               iforce_clear_xmit_and_wake(iforce);
-               spin_unlock_irqrestore(&iforce->xmit_lock, flags);
-               return;
-       }
+       do {
+               if (iforce->xmit.head == iforce->xmit.tail)
+                       break;
 
-       cs = 0x2b;
+               cs = 0x2b;
 
-       serio_write(iforce_serio->serio, 0x2b);
+               serio_write(iforce_serio->serio, 0x2b);
 
-       serio_write(iforce_serio->serio, iforce->xmit.buf[iforce->xmit.tail]);
-       cs ^= iforce->xmit.buf[iforce->xmit.tail];
-       XMIT_INC(iforce->xmit.tail, 1);
-
-       for (i=iforce->xmit.buf[iforce->xmit.tail]; i >= 0; --i) {
                serio_write(iforce_serio->serio,
                            iforce->xmit.buf[iforce->xmit.tail]);
                cs ^= iforce->xmit.buf[iforce->xmit.tail];
                XMIT_INC(iforce->xmit.tail, 1);
-       }
 
-       serio_write(iforce_serio->serio, cs);
+               for (i = iforce->xmit.buf[iforce->xmit.tail]; i >= 0; --i) {
+                       serio_write(iforce_serio->serio,
+                                   iforce->xmit.buf[iforce->xmit.tail]);
+                       cs ^= iforce->xmit.buf[iforce->xmit.tail];
+                       XMIT_INC(iforce->xmit.tail, 1);
+               }
 
-       if (test_and_clear_bit(IFORCE_XMIT_AGAIN, iforce->xmit_flags))
-               goto again;
+               serio_write(iforce_serio->serio, cs);
 
-       iforce_clear_xmit_and_wake(iforce);
+       } while (test_and_clear_bit(IFORCE_XMIT_AGAIN, iforce->xmit_flags));
 
-       spin_unlock_irqrestore(&iforce->xmit_lock, flags);
+       iforce_clear_xmit_and_wake(iforce);
 }
 
 static int iforce_serio_get_id(struct iforce *iforce, u8 id,
index cba92bd590a8d83b4ded836059b5d882fb8751b2..1f00f76b01745d3f7e11888129acc1ac532d98ec 100644 (file)
@@ -25,13 +25,11 @@ static void __iforce_usb_xmit(struct iforce *iforce)
        struct iforce_usb *iforce_usb = container_of(iforce, struct iforce_usb,
                                                     iforce);
        int n, c;
-       unsigned long flags;
 
-       spin_lock_irqsave(&iforce->xmit_lock, flags);
+       guard(spinlock_irqsave)(&iforce->xmit_lock);
 
        if (iforce->xmit.head == iforce->xmit.tail) {
                iforce_clear_xmit_and_wake(iforce);
-               spin_unlock_irqrestore(&iforce->xmit_lock, flags);
                return;
        }
 
@@ -45,7 +43,8 @@ static void __iforce_usb_xmit(struct iforce *iforce)
 
        /* Copy rest of data then */
        c = CIRC_CNT_TO_END(iforce->xmit.head, iforce->xmit.tail, XMIT_SIZE);
-       if (n < c) c=n;
+       if (n < c)
+               c = n;
 
        memcpy(iforce_usb->out->transfer_buffer + 1,
               &iforce->xmit.buf[iforce->xmit.tail],
@@ -53,11 +52,12 @@ static void __iforce_usb_xmit(struct iforce *iforce)
        if (n != c) {
                memcpy(iforce_usb->out->transfer_buffer + 1 + c,
                       &iforce->xmit.buf[0],
-                      n-c);
+                      n - c);
        }
        XMIT_INC(iforce->xmit.tail, n);
 
-       if ( (n=usb_submit_urb(iforce_usb->out, GFP_ATOMIC)) ) {
+       n=usb_submit_urb(iforce_usb->out, GFP_ATOMIC);
+       if (n) {
                dev_warn(&iforce_usb->intf->dev,
                         "usb_submit_urb failed %d\n", n);
                iforce_clear_xmit_and_wake(iforce);
@@ -66,7 +66,6 @@ static void __iforce_usb_xmit(struct iforce *iforce)
        /* The IFORCE_XMIT_RUNNING bit is not cleared here. That's intended.
         * As long as the urb completion handler is not called, the transmiting
         * is considered to be running */
-       spin_unlock_irqrestore(&iforce->xmit_lock, flags);
 }
 
 static void iforce_usb_xmit(struct iforce *iforce)