Skip to content

Commit

Permalink
misc: samsung_modemctl: add timeouts to deal with modem crashes
Browse files Browse the repository at this point in the history
In the event the modem is not responsive during boot, ramdump, or
semaphore acquisition, we timeout and return an error to userspace,
so the RIL can reset the modem.

Signed-off-by: Brian Swetland <swetland@google.com>
  • Loading branch information
swetland authored and Simon Wilson committed Dec 7, 2010
1 parent 119403d commit 7035b75
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 12 deletions.
26 changes: 18 additions & 8 deletions drivers/misc/samsung_modemctl/modem_ctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,11 +132,18 @@ static int mmio_owner_p(struct modemctl *mc)

int modem_acquire_mmio(struct modemctl *mc)
{
if (modem_request_mmio(mc) == 0)
if (wait_event_interruptible(mc->wq, mmio_owner_p(mc))) {
if (modem_request_mmio(mc) == 0) {
int ret = wait_event_interruptible_timeout(
mc->wq, mmio_owner_p(mc), 5 * HZ);
if (ret == 0) {
pr_err("modem_acquire_mmio() TIMEOUT\n");
return -ENODEV;
}
if (ret < 0) {
modem_release_mmio(mc, 0);
return -ERESTARTSYS;
}
}
if (!modem_running(mc)) {
modem_release_mmio(mc, 0);
return -ENODEV;
Expand Down Expand Up @@ -205,7 +212,7 @@ static ssize_t modemctl_read(struct file *filp, char __user *buf,
pr_info("[MODEM] requesting more ram\n");
writel(0, mc->mmio + OFF_SEM);
writel(MODEM_CMD_RAMDUMP_MORE, mc->mmio + OFF_MBOX_AP);
wait_event(mc->wq, mc->ramdump_size != 0); /* TODO: timeout */
wait_event_timeout(mc->wq, mc->ramdump_size != 0, 10 * HZ);
} else {
pr_info("[MODEM] no more ram to dump\n");
mc->ramdump_size = 0;
Expand Down Expand Up @@ -275,6 +282,8 @@ static ssize_t modemctl_write(struct file *filp, const char __user *buf,

static int modem_start(struct modemctl *mc, int ramdump)
{
int ret;

pr_info("[MODEM] modem_start() %s\n",
ramdump ? "ramdump" : "normal");

Expand All @@ -300,17 +309,18 @@ static int modem_start(struct modemctl *mc, int ramdump)
mc->ramdump_pos = 0;
writel(MODEM_CMD_RAMDUMP_START, mc->mmio + OFF_MBOX_AP);

/* TODO: timeout and fail */
wait_event(mc->wq, mc->status == MODEM_DUMPING);
ret = wait_event_timeout(mc->wq, mc->status == MODEM_DUMPING, 25 * HZ);
if (ret == 0)
return -ENODEV;
} else {
mc->status = MODEM_BOOTING_NORMAL;
writel(MODEM_CMD_BINARY_LOAD, mc->mmio + OFF_MBOX_AP);

/* TODO: timeout and fail */
wait_event(mc->wq, modem_running(mc));
ret = wait_event_timeout(mc->wq, modem_running(mc), 25 * HZ);
if (ret == 0)
return -ENODEV;
}


pr_info("[MODEM] modem_start() DONE\n");
return 0;
}
Expand Down
11 changes: 7 additions & 4 deletions drivers/misc/samsung_modemctl/modem_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -235,10 +235,13 @@ static int modem_pipe_send(struct m_pipe *pipe, struct modem_io *io)
MODEM_COUNT(pipe->mc, pipe_tx_delayed);
modem_release_mmio(pipe->mc, 0);

ret = wait_event_interruptible(pipe->mc->wq,
(pipe->tx->avail >= size)
|| modem_offline(pipe->mc));
if (ret)
ret = wait_event_interruptible_timeout(
pipe->mc->wq,
(pipe->tx->avail >= size) || modem_offline(pipe->mc),
5 * HZ);
if (ret == 0)
return -ENODEV;
if (ret < 0)
return ret;
}
}
Expand Down

0 comments on commit 7035b75

Please sign in to comment.