GCC Code Coverage Report


Directory: ./
File: libfprint/drivers/aeslib.c
Date: 2024-05-04 14:54:39
Exec Total Coverage
Lines: 61 63 96.8%
Functions: 5 5 100.0%
Branches: 13 14 92.9%

Line Branch Exec Source
1 /*
2 * Shared functions between libfprint Authentec drivers
3 * Copyright (C) 2007-2008 Daniel Drake <dsd@gentoo.org>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 #define FP_COMPONENT "aeslib"
21
22 #include "drivers_api.h"
23
24 #include <errno.h>
25 #include <string.h>
26
27 #include "aeslib.h"
28
29 #define MAX_REGWRITES_PER_REQUEST 16
30
31 #define BULK_TIMEOUT 4000
32 #define EP_IN (1 | FPI_USB_ENDPOINT_IN)
33 #define EP_OUT (2 | FPI_USB_ENDPOINT_OUT)
34
35 struct write_regv_data
36 {
37 unsigned int num_regs;
38 const struct aes_regwrite *regs;
39 unsigned int offset;
40 aes_write_regv_cb callback;
41 void *user_data;
42 };
43
44 static void continue_write_regv (FpImageDevice *dev,
45 struct write_regv_data *wdata);
46
47 /* libusb bulk callback for regv write completion transfer. continues the
48 * transaction */
49 static void
50 2191 write_regv_trf_complete (FpiUsbTransfer *transfer, FpDevice *device,
51 gpointer user_data, GError *error)
52 {
53 2191 struct write_regv_data *wdata = user_data;
54
55
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2191 times.
2191 if (error)
56 {
57 wdata->callback (FP_IMAGE_DEVICE (device), error, wdata->user_data);
58 g_free (wdata);
59 }
60 else
61 {
62 2191 continue_write_regv (FP_IMAGE_DEVICE (device), wdata);
63 }
64 2191 }
65
66 /* write from wdata->offset to upper_bound (inclusive) of wdata->regs */
67 static void
68 2191 do_write_regv (FpImageDevice *dev, struct write_regv_data *wdata, int upper_bound)
69 {
70 2191 unsigned int offset = wdata->offset;
71 2191 unsigned int num = upper_bound - offset + 1;
72 2191 size_t alloc_size = num * 2;
73 2191 unsigned int i;
74 2191 size_t data_offset = 0;
75 2191 FpiUsbTransfer *transfer = fpi_usb_transfer_new (FP_DEVICE (dev));
76
77 2191 fpi_usb_transfer_fill_bulk (transfer, EP_OUT, alloc_size);
78
79
2/2
✓ Branch 1 taken 16013 times.
✓ Branch 2 taken 2191 times.
20395 for (i = offset; i < offset + num; i++)
80 {
81 16013 const struct aes_regwrite *regwrite = &wdata->regs[i];
82 16013 transfer->buffer[data_offset++] = regwrite->reg;
83 16013 transfer->buffer[data_offset++] = regwrite->value;
84 }
85
86 2191 transfer->short_is_error = TRUE;
87 2191 fpi_usb_transfer_submit (transfer, BULK_TIMEOUT, NULL,
88 write_regv_trf_complete, wdata);
89 2191 }
90
91 /* write the next batch of registers to be written, or if there are no more,
92 * indicate completion to the caller */
93 static void
94 2954 continue_write_regv (FpImageDevice *dev, struct write_regv_data *wdata)
95 {
96 2954 unsigned int offset = wdata->offset;
97 3673 unsigned int regs_remaining;
98 3673 unsigned int limit;
99 3673 unsigned int upper_bound;
100 3673 int i;
101
102 /* skip all zeros and ensure there is still work to do */
103 4392 while (TRUE)
104 {
105
2/2
✓ Branch 0 taken 763 times.
✓ Branch 1 taken 2910 times.
3673 if (offset >= wdata->num_regs)
106 {
107 763 fp_dbg ("all registers written");
108 763 wdata->callback (dev, 0, wdata->user_data);
109 763 g_free (wdata);
110 763 return;
111 }
112
2/2
✓ Branch 0 taken 719 times.
✓ Branch 1 taken 2191 times.
2910 if (wdata->regs[offset].reg)
113 break;
114 719 offset++;
115 }
116
117 2191 wdata->offset = offset;
118 2191 regs_remaining = wdata->num_regs - offset;
119 2191 limit = MIN (regs_remaining, MAX_REGWRITES_PER_REQUEST);
120 2191 upper_bound = offset + limit - 1;
121
122 /* determine if we can write the entire of the regs at once, or if there
123 * is a zero dividing things up */
124
2/2
✓ Branch 0 taken 16731 times.
✓ Branch 1 taken 1473 times.
18204 for (i = offset; i <= upper_bound; i++)
125
2/2
✓ Branch 0 taken 718 times.
✓ Branch 1 taken 16013 times.
16731 if (!wdata->regs[i].reg)
126 {
127 718 upper_bound = i - 1;
128 718 break;
129 }
130
131 2191 do_write_regv (dev, wdata, upper_bound);
132
133 2191 wdata->offset = upper_bound + 1;
134 }
135
136 /* write a load of registers to the device, combining multiple writes in a
137 * single URB up to a limit. insert writes to non-existent register 0 to force
138 * specific groups of writes to be separated by different URBs. */
139 void
140 763 aes_write_regv (FpImageDevice *dev, const struct aes_regwrite *regs,
141 unsigned int num_regs, aes_write_regv_cb callback,
142 void *user_data)
143 {
144 763 struct write_regv_data *wdata;
145
146 763 fp_dbg ("write %d regs", num_regs);
147 763 wdata = g_malloc (sizeof (*wdata));
148 763 wdata->num_regs = num_regs;
149 763 wdata->regs = regs;
150 763 wdata->offset = 0;
151 763 wdata->callback = callback;
152 763 wdata->user_data = user_data;
153 763 continue_write_regv (dev, wdata);
154 763 }
155
156 unsigned char
157 83520000 aes_get_pixel (struct fpi_frame_asmbl_ctx *ctx,
158 struct fpi_frame *frame,
159 unsigned int x,
160 unsigned int y)
161 {
162 83520000 unsigned char ret;
163
164 83520000 ret = frame->data[x * (ctx->frame_height >> 1) + (y >> 1)];
165
2/2
✓ Branch 0 taken 41760000 times.
✓ Branch 1 taken 41760000 times.
83520000 ret = y % 2 ? ret >> 4 : ret & 0xf;
166 83520000 ret *= 17;
167
168 83520000 return ret;
169 }
170