Skip to content
Snippets Groups Projects
Commit 0a91a240 authored by Wesley W. Terpstra's avatar Wesley W. Terpstra
Browse files

Clarify the error codes returned to the callback function.

parent 6610acce
Branches
Tags
No related merge requests found
...@@ -280,17 +280,19 @@ EB_PUBLIC ...@@ -280,17 +280,19 @@ EB_PUBLIC
void eb_device_flush(eb_device_t device); void eb_device_flush(eb_device_t device);
/* Begin a wishbone cycle on the remote device. /* Begin a wishbone cycle on the remote device.
* Read/write phases within a cycle hold the device locked. * Read/write operations within a cycle hold the device locked.
* Read/write operations are executed in the order they are queued. * Read/write operations are executed in the order they are queued.
* Until the cycle is closed and flushed, the operations are not sent. * Until the cycle is closed and flushed, the operations are not sent.
* If there is insufficient memory, EB_NULL is returned. * If there is insufficient memory to begin a cycle, EB_NULL is returned.
* *
* Your callback is called from either eb_socket_poll or eb_device_flush. * Your callback is called from either eb_socket_poll or eb_device_flush.
* It receives these arguments: (user_data, operations, status) * It receives these arguments: (user_data, operations, status)
* *
* If status != OK, the cycle was never sent to the remote bus. * If status != OK, the cycle was never sent to the remote bus.
* If status == OK, the cycle was sent. * If status == OK, the cycle was sent.
* Individual wishbone operation error status is reported by 'operations'. *
* When status == EB_OK, 'operations' report the wishbone ERR flag.
* When status != EB_OK, 'operations' points to the offending operation.
* *
* Status codes: * Status codes:
* OK - operation completed successfully * OK - operation completed successfully
...@@ -298,7 +300,7 @@ void eb_device_flush(eb_device_t device); ...@@ -298,7 +300,7 @@ void eb_device_flush(eb_device_t device);
* WIDTH - a specified value exceeded device bus port width * WIDTH - a specified value exceeded device bus port width
* OVERFLOW - too many operations queued for this cycle (wire limit) * OVERFLOW - too many operations queued for this cycle (wire limit)
* TIMEOUT - remote system never responded to EB request * TIMEOUT - remote system never responded to EB request
* FAIL - underlying transport has broken connection * FAIL - remote host violated protocol
* OOM - out of memory while queueing operations to the cycle * OOM - out of memory while queueing operations to the cycle
*/ */
EB_PUBLIC EB_PUBLIC
......
...@@ -62,22 +62,31 @@ void eb_device_flush(eb_device_t devicep) { ...@@ -62,22 +62,31 @@ void eb_device_flush(eb_device_t devicep) {
struct eb_response* response; struct eb_response* response;
eb_cycle_t cyclep, nextp, prevp; eb_cycle_t cyclep, nextp, prevp;
eb_response_t responsep; eb_response_t responsep;
eb_width_t biggest, data; eb_width_t biggest, data, width;
eb_data_t data_mask;
eb_address_t address_mask;
uint8_t buffer[sizeof(eb_max_align_t)*(255+255+1+1)+8]; /* big enough for worst-case record */ uint8_t buffer[sizeof(eb_max_align_t)*(255+255+1+1)+8]; /* big enough for worst-case record */
uint8_t * wptr, * cptr, * eob; uint8_t * wptr, * cptr, * eob;
int alignment, record_alignment, header_alignment, stride, mtu, readback; int alignment, record_alignment, header_alignment, stride, mtu, readback;
device = EB_DEVICE(devicep); device = EB_DEVICE(devicep);
transport = EB_TRANSPORT(device->transport); transport = EB_TRANSPORT(device->transport);
width = device->widths;
/* /*
assert (device->passive != devicep); assert (device->passive != devicep);
assert (eb_width_refined(device->widths) != 0); assert (eb_width_refined(width) != 0);
*/ */
/* Determine alignment and masking sets */
data_mask = ((eb_data_t)1) << (((width&EB_DATAX)<<3)-1);
data_mask = (data_mask-1) << 1 | 1;
address_mask = ((eb_address_t)1) << (((width&EB_ADDRX)>>1)-1);
address_mask = (address_mask-1) << 1 | 1;
/* Calculate alignment values */ /* Calculate alignment values */
data = device->widths & EB_DATAX; data = width & EB_DATAX;
biggest = (device->widths >> 4) | data; biggest = (width >> 4) | data;
alignment = 2; alignment = 2;
alignment += (biggest >= EB_DATA32)*2; alignment += (biggest >= EB_DATA32)*2;
alignment += (biggest >= EB_DATA64)*4; alignment += (biggest >= EB_DATA64)*4;
...@@ -93,7 +102,7 @@ void eb_device_flush(eb_device_t devicep) { ...@@ -93,7 +102,7 @@ void eb_device_flush(eb_device_t devicep) {
buffer[0] = 0x4E; buffer[0] = 0x4E;
buffer[1] = 0x6F; buffer[1] = 0x6F;
buffer[2] = 0x10; /* V1. no probe. */ buffer[2] = 0x10; /* V1. no probe. */
buffer[3] = device->widths; buffer[3] = width;
cptr = wptr = &buffer[header_alignment]; cptr = wptr = &buffer[header_alignment];
eob = &buffer[mtu]; eob = &buffer[mtu];
} else { } else {
...@@ -117,6 +126,7 @@ void eb_device_flush(eb_device_t devicep) { ...@@ -117,6 +126,7 @@ void eb_device_flush(eb_device_t devicep) {
eb_operation_t scanp; eb_operation_t scanp;
int needs_check, cycle_end; int needs_check, cycle_end;
unsigned int ops, maxops; unsigned int ops, maxops;
eb_status_t reason;
cycle = EB_CYCLE(cyclep); cycle = EB_CYCLE(cyclep);
nextp = cycle->next; nextp = cycle->next;
...@@ -137,6 +147,38 @@ void eb_device_flush(eb_device_t devicep) { ...@@ -137,6 +147,38 @@ void eb_device_flush(eb_device_t devicep) {
continue; continue;
} }
/* Are there out of range widths? */
reason = EB_OK; /* silence warning */
for (operationp = cycle->first; operationp != EB_NULL; operationp = operation->next) {
operation = EB_OPERATION(operationp);
/* Is the address too big for a bus op? */
if ((operation->flags & EB_OP_CFG_SPACE) == 0 &&
(operation->address & address_mask) != operation->address) {
reason = EB_ADDRESS;
break;
}
/* Is the address too big for a cfg op? */
if ((operation->flags & EB_OP_CFG_SPACE) != 0 &&
(operation->address & 0xFFFFU) != operation->address) {
reason = EB_ADDRESS;
break;
}
/* Is the data too big for the port? */
if ((operation->flags & EB_OP_MASK) == EB_OP_WRITE &&
(operation->write_value & data_mask) != operation->write_value) {
reason = EB_WIDTH;
break;
}
}
if (operationp != EB_NULL) {
/* Report the bad operation to the user */
if (cycle->callback)
(*cycle->callback)(cycle->user_data, operationp, reason);
eb_cycle_destroy(cyclep);
eb_free_cycle(cyclep);
continue;
}
/* Record to hook it into socket */ /* Record to hook it into socket */
responsep = eb_new_response(); /* invalidates: cycle device transport */ responsep = eb_new_response(); /* invalidates: cycle device transport */
if (responsep == EB_NULL) { if (responsep == EB_NULL) {
...@@ -310,7 +352,7 @@ void eb_device_flush(eb_device_t devicep) { ...@@ -310,7 +352,7 @@ void eb_device_flush(eb_device_t devicep) {
if (length > eob - wptr) { if (length > eob - wptr) {
/* Blow up in the face of the user */ /* Blow up in the face of the user */
if (cycle->callback) if (cycle->callback)
(*cycle->callback)(cycle->user_data, cycle->first, EB_OVERFLOW); (*cycle->callback)(cycle->user_data, operationp, EB_OVERFLOW);
eb_cycle_destroy(cyclep); eb_cycle_destroy(cyclep);
eb_free_cycle(cyclep); eb_free_cycle(cyclep);
eb_free_response(responsep); eb_free_response(responsep);
......
...@@ -184,7 +184,7 @@ eb_status_t eb_socket_close(eb_socket_t socketp) { ...@@ -184,7 +184,7 @@ eb_status_t eb_socket_close(eb_socket_t socketp) {
/* Report the cycle callback */ /* Report the cycle callback */
cycle = EB_CYCLE(response->cycle); cycle = EB_CYCLE(response->cycle);
if (cycle->callback) if (cycle->callback)
(*cycle->callback)(cycle->user_data, cycle->first, EB_FAIL); /* invalidate: socket response cycle */ (*cycle->callback)(cycle->user_data, cycle->first, EB_TIMEOUT); /* invalidate: socket response cycle */
socket = EB_SOCKET(socketp); socket = EB_SOCKET(socketp);
response = EB_RESPONSE(tmp); response = EB_RESPONSE(tmp);
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment