Skip to content

Commit e65b98b

Browse files
fyin1jren1
authored andcommitted
DM: lpc_deinit doesn't release all resources allocated.
Also refine the failure path of lpc_init to make sure all resources allocated get release. Signed-off-by: Yin Fengwei <fengwei.yin@intel.com> Acked-by: Anthony Xu <anthony.xu@intel.com>
1 parent 1a2a074 commit e65b98b

File tree

1 file changed

+44
-18
lines changed

1 file changed

+44
-18
lines changed

devicemodel/hw/pci/lpc.c

Lines changed: 44 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,38 @@ lpc_uart_io_handler(struct vmctx *ctx, int vcpu, int in, int port, int bytes,
155155
return 0;
156156
}
157157

158+
static void
159+
lpc_deinit(struct vmctx *ctx)
160+
{
161+
struct lpc_uart_vdev *lpc_uart;
162+
struct inout_port iop;
163+
const char *name;
164+
int unit;
165+
166+
/* COM1 and COM2 */
167+
for (unit = 0; unit < LPC_UART_NUM; unit++) {
168+
name = lpc_uart_names[unit];
169+
lpc_uart = &lpc_uart_vdev[unit];
170+
171+
if (lpc_uart->enabled == 0)
172+
continue;
173+
174+
bzero(&iop, sizeof(struct inout_port));
175+
iop.name = name;
176+
iop.port = lpc_uart->iobase;
177+
iop.size = UART_IO_BAR_SIZE;
178+
iop.flags = IOPORT_F_INOUT;
179+
unregister_inout(&iop);
180+
181+
uart_release_backend(lpc_uart->uart, lpc_uart->opts);
182+
uart_deinit(lpc_uart->uart);
183+
uart_legacy_dealloc(unit);
184+
lpc_uart->uart = NULL;
185+
lpc_uart->enabled = 0;
186+
}
187+
}
188+
189+
158190
static int
159191
lpc_init(struct vmctx *ctx)
160192
{
@@ -173,17 +205,24 @@ lpc_init(struct vmctx *ctx)
173205
&lpc_uart->irq) != 0) {
174206
fprintf(stderr, "Unable to allocate resources for "
175207
"LPC device %s\n", name);
176-
return -1;
208+
goto init_failed;
177209
}
178210
pci_irq_reserve(lpc_uart->irq);
179211

180212
lpc_uart->uart = uart_init(lpc_uart_intr_assert,
181213
lpc_uart_intr_deassert, lpc_uart);
182214

215+
if (lpc_uart->uart < 0) {
216+
uart_legacy_dealloc(unit);
217+
goto init_failed;
218+
}
219+
183220
if (uart_set_backend(lpc_uart->uart, lpc_uart->opts) != 0) {
184221
fprintf(stderr, "Unable to initialize backend '%s' "
185222
"for LPC device %s\n", lpc_uart->opts, name);
186-
return -1;
223+
uart_deinit(lpc_uart->uart);
224+
uart_legacy_dealloc(unit);
225+
goto init_failed;
187226
}
188227

189228
bzero(&iop, sizeof(struct inout_port));
@@ -200,23 +239,10 @@ lpc_init(struct vmctx *ctx)
200239
}
201240

202241
return 0;
203-
}
204-
205-
static void
206-
lpc_deinit(struct vmctx *ctx)
207-
{
208-
struct lpc_uart_vdev *lpc_uart;
209-
int unit;
210-
211-
/* COM1 and COM2 */
212-
for (unit = 0; unit < LPC_UART_NUM; unit++) {
213-
lpc_uart = &lpc_uart_vdev[unit];
214242

215-
uart_legacy_dealloc(unit);
216-
uart_deinit(lpc_uart->uart);
217-
lpc_uart->uart = NULL;
218-
lpc_uart->enabled = 0;
219-
}
243+
init_failed:
244+
lpc_deinit(ctx);
245+
return -1;
220246
}
221247

222248
static void

0 commit comments

Comments
 (0)