greybus: bootrom: Enhance timeout error message

The timeout message is very generic today and there are several requests
we can be timing out waiting for.

Update bootrom driver to also track the next expected request and
enhance the error message based on that to confirm the request we timed
out waiting for.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Reviewed-by: Johan Hovold <johan@hovoldconsulting.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
Viresh Kumar 2016-06-22 14:46:39 +05:30 committed by Greg Kroah-Hartman
parent fd6d6f61d8
commit a4293e1d4e
1 changed files with 49 additions and 5 deletions

View File

@ -17,11 +17,19 @@
/* Timeout, in jiffies, within which the next request must be received */ /* Timeout, in jiffies, within which the next request must be received */
#define NEXT_REQ_TIMEOUT_J msecs_to_jiffies(1000) #define NEXT_REQ_TIMEOUT_J msecs_to_jiffies(1000)
enum next_request_type {
NEXT_REQ_FIRMWARE_SIZE,
NEXT_REQ_GET_FIRMWARE,
NEXT_REQ_READY_TO_BOOT,
NEXT_REQ_MODE_SWITCH,
};
struct gb_bootrom { struct gb_bootrom {
struct gb_connection *connection; struct gb_connection *connection;
const struct firmware *fw; const struct firmware *fw;
u8 protocol_major; u8 protocol_major;
u8 protocol_minor; u8 protocol_minor;
enum next_request_type next_request;
struct delayed_work dwork; struct delayed_work dwork;
struct mutex mutex; /* Protects bootrom->fw */ struct mutex mutex; /* Protects bootrom->fw */
}; };
@ -40,8 +48,28 @@ static void gb_bootrom_timedout(struct work_struct *work)
struct delayed_work *dwork = to_delayed_work(work); struct delayed_work *dwork = to_delayed_work(work);
struct gb_bootrom *bootrom = container_of(dwork, struct gb_bootrom, dwork); struct gb_bootrom *bootrom = container_of(dwork, struct gb_bootrom, dwork);
struct device *dev = &bootrom->connection->bundle->dev; struct device *dev = &bootrom->connection->bundle->dev;
const char *reason;
dev_err(dev, "Timed out waiting for request from the Module\n"); switch (bootrom->next_request) {
case NEXT_REQ_FIRMWARE_SIZE:
reason = "Firmware Size Request";
break;
case NEXT_REQ_GET_FIRMWARE:
reason = "Get Firmware Request";
break;
case NEXT_REQ_READY_TO_BOOT:
reason = "Ready to Boot Request";
break;
case NEXT_REQ_MODE_SWITCH:
reason = "Interface Mode Switch";
break;
default:
reason = NULL;
dev_err(dev, "Invalid next-request: %u", bootrom->next_request);
break;
}
dev_err(dev, "Timed out waiting for %s from the Module\n", reason);
mutex_lock(&bootrom->mutex); mutex_lock(&bootrom->mutex);
free_firmware(bootrom); free_firmware(bootrom);
@ -50,6 +78,13 @@ static void gb_bootrom_timedout(struct work_struct *work)
/* TODO: Power-off Module ? */ /* TODO: Power-off Module ? */
} }
static void gb_bootrom_set_timeout(struct gb_bootrom *bootrom,
enum next_request_type next, unsigned long timeout)
{
bootrom->next_request = next;
schedule_delayed_work(&bootrom->dwork, timeout);
}
/* /*
* The es2 chip doesn't have VID/PID programmed into the hardware and we need to * The es2 chip doesn't have VID/PID programmed into the hardware and we need to
* hack that up to distinguish different modules and their firmware blobs. * hack that up to distinguish different modules and their firmware blobs.
@ -175,7 +210,8 @@ static int gb_bootrom_firmware_size_request(struct gb_operation *op)
queue_work: queue_work:
/* Refresh timeout */ /* Refresh timeout */
schedule_delayed_work(&bootrom->dwork, NEXT_REQ_TIMEOUT_J); gb_bootrom_set_timeout(bootrom, NEXT_REQ_GET_FIRMWARE,
NEXT_REQ_TIMEOUT_J);
return ret; return ret;
} }
@ -188,6 +224,7 @@ static int gb_bootrom_get_firmware(struct gb_operation *op)
struct gb_bootrom_get_firmware_response *firmware_response; struct gb_bootrom_get_firmware_response *firmware_response;
struct device *dev = &op->connection->bundle->dev; struct device *dev = &op->connection->bundle->dev;
unsigned int offset, size; unsigned int offset, size;
enum next_request_type next_request;
int ret = 0; int ret = 0;
/* Disable timeouts */ /* Disable timeouts */
@ -239,7 +276,12 @@ static int gb_bootrom_get_firmware(struct gb_operation *op)
queue_work: queue_work:
/* Refresh timeout */ /* Refresh timeout */
schedule_delayed_work(&bootrom->dwork, NEXT_REQ_TIMEOUT_J); if (!ret && (offset + size == fw->size))
next_request = NEXT_REQ_READY_TO_BOOT;
else
next_request = NEXT_REQ_GET_FIRMWARE;
gb_bootrom_set_timeout(bootrom, next_request, NEXT_REQ_TIMEOUT_J);
return ret; return ret;
} }
@ -284,7 +326,8 @@ static int gb_bootrom_ready_to_boot(struct gb_operation *op)
* send a new hotplug request, which shall get rid of the bootrom * send a new hotplug request, which shall get rid of the bootrom
* connection. As that can take some time, increase the timeout a bit. * connection. As that can take some time, increase the timeout a bit.
*/ */
schedule_delayed_work(&bootrom->dwork, 5 * NEXT_REQ_TIMEOUT_J); gb_bootrom_set_timeout(bootrom, NEXT_REQ_MODE_SWITCH,
5 * NEXT_REQ_TIMEOUT_J);
return ret; return ret;
} }
@ -403,7 +446,8 @@ static int gb_bootrom_probe(struct gb_bundle *bundle,
} }
/* Refresh timeout */ /* Refresh timeout */
schedule_delayed_work(&bootrom->dwork, NEXT_REQ_TIMEOUT_J); gb_bootrom_set_timeout(bootrom, NEXT_REQ_FIRMWARE_SIZE,
NEXT_REQ_TIMEOUT_J);
dev_dbg(&bundle->dev, "AP_READY sent\n"); dev_dbg(&bundle->dev, "AP_READY sent\n");