rlink: fix reply counter to enable sending full buffers
[openocd.git] / src / jtag / drivers / rlink.c
index 7111a20f44cd4547a0e2aaca7efadbe67cab2f65..d0b18b1ba94b0013c9ce4d29c6df859e7f8959f1 100644 (file)
@@ -678,6 +678,10 @@ dtc_queue_run(void) {
        uint8_t                 dtc_mask, tdo_mask;
        uint8_t                 reply_buffer[USB_EP2IN_SIZE];
 
+       assert((dtc_queue.rq_head != 0) == (dtc_queue.reply_index > 0));
+       assert(dtc_queue.cmd_index < USB_EP2BANK_SIZE);
+       assert(dtc_queue.reply_index <= USB_EP2IN_SIZE);
+
        retval = ERROR_OK;
 
        if (dtc_queue.cmd_index < 1) return(retval);
@@ -702,102 +706,101 @@ dtc_queue_run(void) {
                if (usb_err < 0) {
                        LOG_ERROR("dtc_run_download: %s", usb_strerror());
                        exit(1);
-               } else {
-                       /* process the reply, which empties the reply queue and frees its entries */
-                       dtc_p = reply_buffer;
+               }
 
-                       /* The rigamarole with the masks and doing it bit-by-bit is due to the fact that the scan buffer is LSb-first and the DTC code is MSb-first for hardware reasons.   It was that or craft a function to do the reversal, and that wouldn't work with bit-stuffing (supplying extra bits to use mostly byte operations), or any other scheme which would throw the byte alignment off. */
+               /* process the reply, which empties the reply queue and frees its entries */
+               dtc_p = reply_buffer;
 
-                       for (
-                                       rq_p = dtc_queue.rq_head;
-                                       rq_p != NULL;
-                                       rq_p = rq_next
-                       ) {
-                               tdo_p = rq_p->scan.buffer + (rq_p->scan.offset / 8);
-                               tdo_mask = 1 << (rq_p->scan.offset % 8);
+               /* The rigamarole with the masks and doing it bit-by-bit is due to the fact that the scan buffer is LSb-first and the DTC code is MSb-first for hardware reasons.   It was that or craft a function to do the reversal, and that wouldn't work with bit-stuffing (supplying extra bits to use mostly byte operations), or any other scheme which would throw the byte alignment off. */
 
+               for (
+                               rq_p = dtc_queue.rq_head;
+                               rq_p != NULL;
+                               rq_p = rq_next
+               ) {
+                       tdo_p = rq_p->scan.buffer + (rq_p->scan.offset / 8);
+                       tdo_mask = 1 << (rq_p->scan.offset % 8);
 
-                               bit_cnt = rq_p->scan.length;
-                               if (bit_cnt >= 8) {
-                                       /* bytes */
 
-                                       dtc_mask = 1 << (8 - 1);
+                       bit_cnt = rq_p->scan.length;
+                       if (bit_cnt >= 8) {
+                               /* bytes */
 
-                                       for (
-                                                       ;
-                                                       bit_cnt;
-                                                       bit_cnt--
-                                       ) {
-                                               if (*dtc_p & dtc_mask) {
-                                                       *tdo_p |= tdo_mask;
-                                               } else {
-                                                       *tdo_p &=~ tdo_mask;
-                                               }
-
-                                               dtc_mask >>= 1;
-                                               if (dtc_mask == 0) {
-                                                       dtc_p++;
-                                                       dtc_mask = 1 << (8 - 1);
-                                               }
-
-                                               tdo_mask <<= 1;
-                                               if (tdo_mask == 0) {
-                                                       tdo_p++;
-                                                       tdo_mask = 1;
-                                               }
-                                       }
-                               } else {
-                                       /*  extra bits or last bit */
-
-                                       x = *dtc_p++;
-                                       if ((
-                                                       rq_p->scan.type == SCAN_IN
-                                       ) && (
-                                                       rq_p->scan.offset != rq_p->scan.size - 1
-                                       )) {
-                                               /* extra bits were sent as a full byte with padding on the end */
-                                               dtc_mask = 1 << (8 - 1);
+                               dtc_mask = 1 << (8 - 1);
+
+                               for (
+                                               ;
+                                               bit_cnt;
+                                               bit_cnt--
+                               ) {
+                                       if (*dtc_p & dtc_mask) {
+                                               *tdo_p |= tdo_mask;
                                        } else {
-                                               dtc_mask = 1 << (bit_cnt - 1);
+                                               *tdo_p &=~ tdo_mask;
                                        }
 
-                                       for (
-                                                       ;
-                                                       bit_cnt;
-                                                       bit_cnt--
-                                       ) {
-                                               if (x & dtc_mask) {
-                                                       *tdo_p |= tdo_mask;
-                                               } else {
-                                                       *tdo_p &=~ tdo_mask;
-                                               }
-
-                                               dtc_mask >>= 1;
-
-                                               tdo_mask <<= 1;
-                                               if (tdo_mask == 0) {
-                                                       tdo_p++;
-                                                       tdo_mask = 1;
-                                               }
+                                       dtc_mask >>= 1;
+                                       if (dtc_mask == 0) {
+                                               dtc_p++;
+                                               dtc_mask = 1 << (8 - 1);
+                                       }
 
+                                       tdo_mask <<= 1;
+                                       if (tdo_mask == 0) {
+                                               tdo_p++;
+                                               tdo_mask = 1;
                                        }
                                }
+                       } else {
+                               /*  extra bits or last bit */
+
+                               x = *dtc_p++;
+                               if ((
+                                               rq_p->scan.type == SCAN_IN
+                               ) && (
+                                               rq_p->scan.offset != rq_p->scan.size - 1
+                               )) {
+                                       /* extra bits were sent as a full byte with padding on the end */
+                                       dtc_mask = 1 << (8 - 1);
+                               } else {
+                                       dtc_mask = 1 << (bit_cnt - 1);
+                               }
 
-                               if ((rq_p->scan.offset + rq_p->scan.length) >= rq_p->scan.size) {
-                                       /* feed scan buffer back into openocd and free it */
-                                       if (jtag_read_buffer(rq_p->scan.buffer, rq_p->cmd->cmd.scan) != ERROR_OK) {
-                                               retval = ERROR_JTAG_QUEUE_FAILED;
+                               for (
+                                               ;
+                                               bit_cnt;
+                                               bit_cnt--
+                               ) {
+                                       if (x & dtc_mask) {
+                                               *tdo_p |= tdo_mask;
+                                       } else {
+                                               *tdo_p &=~ tdo_mask;
                                        }
-                                       free(rq_p->scan.buffer);
+
+                                       dtc_mask >>= 1;
+
+                                       tdo_mask <<= 1;
+                                       if (tdo_mask == 0) {
+                                               tdo_p++;
+                                               tdo_mask = 1;
+                                       }
+
                                }
+                       }
 
-                               rq_next = rq_p->next;
-                               free(rq_p);
+                       if ((rq_p->scan.offset + rq_p->scan.length) >= rq_p->scan.size) {
+                               /* feed scan buffer back into openocd and free it */
+                               if (jtag_read_buffer(rq_p->scan.buffer, rq_p->cmd->cmd.scan) != ERROR_OK) {
+                                       retval = ERROR_JTAG_QUEUE_FAILED;
+                               }
+                               free(rq_p->scan.buffer);
                        }
-                       dtc_queue.rq_head = NULL;
-                       dtc_queue.rq_tail = NULL;
-               }
 
+                       rq_next = rq_p->next;
+                       free(rq_p);
+               }
+               dtc_queue.rq_head = NULL;
+               dtc_queue.rq_tail = NULL;
        }
 
 
@@ -808,8 +811,6 @@ dtc_queue_run(void) {
        return(retval);
 }
 
-
-
 static
 int
 tap_state_queue_init(void) {
@@ -1233,6 +1234,7 @@ rlink_scan(
                                LOG_ERROR("enqueuing DTC reply entry: %s", strerror(errno));
                                exit(1);
                        }
+                       dtc_queue.reply_index += (chunk_bits + 7) / 8;
 
                        tdi_bit_offset += chunk_bits;
                }
@@ -1265,7 +1267,6 @@ rlink_scan(
                                dtc_mask >>= 1;
                                if (dtc_mask == 0) {
                                        dtc_queue.cmd_buffer[dtc_queue.cmd_index++] = x;
-                                       dtc_queue.reply_index++;
                                        x = 0;
                                        dtc_mask = 1 << (8 - 1);
                                }
@@ -1299,6 +1300,8 @@ rlink_scan(
                        exit(1);
                }
 
+               dtc_queue.reply_index++;
+
                tdi_bit_offset += extra_bits;
 
                if (type == SCAN_IN) {
@@ -1328,40 +1331,36 @@ rlink_scan(
 
                        dtc_queue.cmd_buffer[dtc_queue.cmd_index++] = x;
                }
-
-               dtc_queue.reply_index++;
        }
 
        /* Schedule the last bit into the DTC command buffer */
-       {
-               /* make sure there's room for stop, and bit pair command */
-               if (
-                               (dtc_queue.cmd_index >= sizeof(dtc_queue.cmd_buffer) - (1 + 1))
-                               ||
-                               (dtc_queue.reply_index >= USB_EP2IN_SIZE - (1))
-               ) {
-                       dtc_queue_run();
-               }
+       /* make sure there's room for stop, and bit pair command */
+       if (
+                       (dtc_queue.cmd_index >= sizeof(dtc_queue.cmd_buffer) - (1 + 1))
+                       ||
+                       (dtc_queue.reply_index >= USB_EP2IN_SIZE - (1))
+       ) {
+               dtc_queue_run();
+       }
 
-               if (type == SCAN_OUT) {
-                       dtc_queue.cmd_buffer[dtc_queue.cmd_index++] =
-                                       DTC_CMD_SHIFT_TMS_TDI_BIT_PAIR(1, (*tdi_p & tdi_mask), 0);
+       if (type == SCAN_OUT) {
+               dtc_queue.cmd_buffer[dtc_queue.cmd_index++] =
+                               DTC_CMD_SHIFT_TMS_TDI_BIT_PAIR(1, (*tdi_p & tdi_mask), 0);
 
-               } else {
-                       if (dtc_queue_enqueue_reply(
-                                       type, buffer, scan_size, tdi_bit_offset,
-                                       1,
-                                       cmd
-                       ) == NULL) {
-                               LOG_ERROR("enqueuing DTC reply entry: %s", strerror(errno));
-                               exit(1);
-                       }
+       } else {
+               if (dtc_queue_enqueue_reply(
+                               type, buffer, scan_size, tdi_bit_offset,
+                               1,
+                               cmd
+               ) == NULL) {
+                       LOG_ERROR("enqueuing DTC reply entry: %s", strerror(errno));
+                       exit(1);
+               }
 
-                       dtc_queue.cmd_buffer[dtc_queue.cmd_index++] =
-                                       DTC_CMD_SHIFT_TMS_TDI_BIT_PAIR(1, (*tdi_p & tdi_mask), 1);
+               dtc_queue.reply_index++;
 
-                       dtc_queue.reply_index++;
-               }
+               dtc_queue.cmd_buffer[dtc_queue.cmd_index++] =
+                               DTC_CMD_SHIFT_TMS_TDI_BIT_PAIR(1, (*tdi_p & tdi_mask), 1);
        }
 
        /* Move to pause state */

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)