PERFORCE change 127350 for review
Hans Petter Selasky
hselasky at FreeBSD.org
Tue Oct 9 14:16:36 PDT 2007
http://perforce.freebsd.org/chv.cgi?CH=127350
Change 127350 by hselasky at hselasky_laptop001 on 2007/10/09 21:16:21
This commit completes change 127347 . The change has been done
using the below attached script. Except for two places, manual
intervention was needed. One case was in "ugen.c" where
I added a check for "xfer->error == USBD_CANCELLED". The other
case was in the function "usbd_clear_stall_callback()" where
I need to change the argument to "USBD_GET_STATE()" into
"xfer1" instead of "xfer".
FYI; Patch size in bytes is 151766. Script size in bytes
is 9884 bytes. The gain factor and time saving of using
a script for this job was more than 10 : 1 .
/*
* Copyright (c) 2007 Hans Petter Selasky. All Rights Reserved.
* BSD License
*/
#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <string.h>
#include <sys/types.h>
#include <fcntl.h>
#include <err.h>
#include <errno.h>
#include <unistd.h>
static void *
load_file(const char *fname, char **ppEnd)
{
int f;
int err;
char *ptr;
off_t size;
off_t temp;
f = open(fname, O_RDONLY);
if (f < 0) return NULL;
size = lseek(f, 0, SEEK_END);
size += 2;
ptr = malloc(size);
if (ptr == NULL) {
error:
close(f);
return NULL;
}
size -= 2;
temp = lseek(f, 0, SEEK_SET);
err = read(f, ptr, size);
if (err != size) {
goto error;
}
close(f);
if (ppEnd) {
*ppEnd = ptr + size;
}
/* zero terminate */
ptr[size] = 0;
ptr[size+1] = 0;
/* convert \0 into space */
while (size--) {
if (ptr[size] == 0) {
ptr[size] = ' ';
}
}
return ptr;
}
static void
print_to(char **pp0, char *end, char echar)
{
char tchar;
tchar = *end;
*end = 0;
printf("%s", *pp0);
if (echar) {
printf("%c", echar);
}
*pp0 = end;
*end = tchar;
return;
}
static uint8_t
rewind_to(char **ppChar, char *pStart, char cStop)
{
char *ptr;
ptr = *ppChar;
while (1) {
if (pStart == ptr) {
break;
}
if (*ptr == cStop) {
*ppChar = ptr;
return 0; /* success */
}
ptr --;
}
return 1; /* failed */
}
static uint8_t
skipto(char **ppChar, char *pEnd, char cStop)
{
char *ptr;
ptr = *ppChar;
while (1) {
if (ptr == pEnd) {
break;
}
if (*ptr == 0) {
break;
}
if (*ptr == cStop) {
*ppChar = ptr;
return 0; /* success */
}
ptr ++;
}
return 1; /* failed */
}
static uint8_t
have_return_sub(char *from, char *to, const char *what) {
char etemp;
char *ptr = NULL;
char *ret = NULL;
char cprev = 0;
etemp = *to;
*to = 0;
while (1) {
ptr = strstr(from, what);
if (ptr) {
ret = ptr;
from = ptr + 1;
} else {
break;
}
}
if (ret) {
while (*ret) {
if ((cprev != '\n') && (*ret == '}')) {
/* restore end character */
*to = etemp;
return 0;
}
cprev = *ret;
ret++;
}
/* restore end character */
*to = etemp;
return 1;
}
/* restore end character */
*to = etemp;
return 0;
}
static uint8_t
have_return(char *from, char *to) {
return (have_return_sub(from,to," ""return") ||
have_return_sub(from,to,"\t""return") ||
have_return_sub(from,to,"\t""goto") ||
have_return_sub(from,to," ""goto"));
}
enum {
ST_FIRST,
ST_SETUP,
ST_ERROR,
ST_TRANSFERRED,
ST_END,
};
static const char *fstart = "\n{";
static const char *fend = "\n}";
static const char *ustatus = "USBD_CHECK_STATUS";
#define NEND ((void *)(0-1))
static struct states {
char *from;
char *to;
char *new_label[2];
char have_return;
char order;
char next_state;
char need_label;
} st_temp[ST_END];
static void
do_st_temp(uint8_t x)
{
printf("%s", st_temp[x].need_label ?
st_temp[x].new_label[0] :
st_temp[x].new_label[1]);
print_to(&st_temp[x].from, st_temp[x].to, 0);
return;
}
int
main(int argc, char **argv)
{
char *ptr;
char *end;
char *p0;
char *p1;
char *p3;
char *p4;
char *p5;
char *new_label[2];
char echar[6];
char *tr_error;
char *tr_transferred;
char *tr_setup;
uint8_t need_tr_error;
uint8_t need_tr_transferred;
uint8_t need_tr_setup;
uint8_t need_label;
uint8_t state;
uint8_t state_last;
uint8_t x;
uint8_t y;
char order;
if (argc < 2) {
return EINVAL;
}
ptr = load_file(argv[1], &end);
if (ptr == NULL) {
return EINVAL;
}
while (1) {
p0 = strstr(ptr, fstart);
if (p0 == NULL) {
/* end of file */
break;
}
p1 = strstr(p0, fend);
if (p1 == NULL) {
/* end of file */
break;
}
echar[1] = p1[1];
p1[1] = 0;
while (1) {
p3 = strstr(p0 + 1, fstart);
if (p3 == NULL) {
/* no more fstart */
break;
}
p0 = p3;
}
p3 = strstr(p0, ustatus);
/* find the last USBD_CHECK_STATUS() */
while (p3) {
p5 = strstr(p3+1, ustatus);
if (p5) {
p3 = p5;
} else {
break;
}
}
tr_error = strstr(p0, "tr_error:");
tr_setup = strstr(p0, "tr_setup:");
tr_transferred = strstr(p0, "tr_transferred:");
if ((p3 != NULL) &&
(tr_error > p3) &&
(tr_setup > p3) &&
(tr_transferred > p3)) {
need_tr_error = (strstr(p0, "goto tr_error;") != NULL);
need_tr_setup = (strstr(p0, "goto tr_setup;") != NULL);
need_tr_transferred = (strstr(p0, "goto tr_transferred;") != NULL);
if (rewind_to(&p3, p0, '\n') ||
rewind_to(&tr_error, p0, '\n') ||
rewind_to(&tr_setup, p0, '\n') ||
rewind_to(&tr_transferred, p0, '\n')) {
/* do nothing */
} else {
p3++;
tr_error ++;
tr_setup ++;
tr_transferred ++;
goto level2;
}
}
complete:
print_to(&ptr, p1 + 1, echar[1]);
ptr = p1 + 2;
continue;
level2:
order = 0;
new_label[0] = "";
new_label[1] = "";
need_label = 0;
state_last = ST_FIRST;
print_to(&ptr, p3, 0);
printf(" switch (USBD_GET_STATE(xfer)) {");
if (skipto(&p3, NULL, '\n')) {
goto complete;
}
p3++;
ptr = p3;
while (1) {
/* sort pointers */
if (tr_setup < tr_error) {
p4 = tr_setup;
state = ST_SETUP;
} else {
p4 = tr_error;
state = ST_ERROR;
}
if (tr_transferred < p4) {
p4 = tr_transferred;
state = ST_TRANSFERRED;
}
if (p4 == NEND) {
break;
}
switch (state) {
case ST_SETUP:
st_temp[state_last].from = ptr;
st_temp[state_last].to = tr_setup;
st_temp[state_last].new_label[0] = new_label[0];
st_temp[state_last].new_label[1] = new_label[1];
st_temp[state_last].order = order;
st_temp[state_last].next_state = state;
st_temp[state_last].need_label = need_label;
new_label[0] = " case USBD_ST_SETUP: tr_setup:";
new_label[1] = " case USBD_ST_SETUP: ";
need_label = need_tr_setup;
if (skipto(&tr_setup, NULL, '\n')) {
goto complete;
}
ptr = tr_setup;
tr_setup = NEND;
state_last = state;
break;
case ST_ERROR:
st_temp[state_last].from = ptr;
st_temp[state_last].to = tr_error;
st_temp[state_last].new_label[0] = new_label[0];
st_temp[state_last].new_label[1] = new_label[1];
st_temp[state_last].order = order;
st_temp[state_last].next_state = state;
st_temp[state_last].need_label = need_label;
new_label[0] = " default: tr_error:";
new_label[1] = " default: /* Error */";
need_label = need_tr_error;
if (skipto(&tr_error, NULL, '\n')) {
goto complete;
}
ptr = tr_error;
tr_error = NEND;
state_last = state;
break;
case ST_TRANSFERRED:
st_temp[state_last].from = ptr;
st_temp[state_last].to = tr_transferred;
st_temp[state_last].new_label[0] = new_label[0];
st_temp[state_last].new_label[1] = new_label[1];
st_temp[state_last].order = order;
st_temp[state_last].next_state = state;
st_temp[state_last].need_label = need_label;
new_label[0] = " case USBD_ST_TRANSFERRED: tr_transferred:";
new_label[1] = " case USBD_ST_TRANSFERRED: ";
need_label = need_tr_transferred;
if (skipto(&tr_transferred, NULL, '\n')) {
goto complete;
}
ptr = tr_transferred;
tr_transferred = NEND;
state_last = state;
break;
}
order ++;
}
p3 = p1 + 1;
st_temp[state_last].from = ptr;
st_temp[state_last].to = p3;
st_temp[state_last].new_label[0] = new_label[0];
st_temp[state_last].new_label[1] = new_label[1];
st_temp[state_last].order = order;
st_temp[state_last].next_state = ST_END;
st_temp[state_last].need_label = need_label;
for (x = 0; x < ST_END; x++) {
st_temp[x].have_return =
have_return(st_temp[x].from, st_temp[x].to);
}
/* override */
st_temp[ST_FIRST].have_return = 1;
state_last = 0;
/* figure out if "default:" is last */
if (st_temp[ST_ERROR].order == (ST_END-1)) {
/* change least possible if the order is correct */
for (x = 0; x < ST_END; x++) {
for (y = 0; y < ST_END; y++) {
if (st_temp[y].order == x) {
do_st_temp(y);
}
}
}
} else {
/* We need to change the order of the code.
* Make sure that we don't mess something up !
*/
if (!st_temp[ST_ERROR].have_return) {
st_temp[st_temp[ST_ERROR].next_state & 0xFF].need_label = 1;
}
for (x = 0; x < ST_END; x++) {
for (y = 0; y < ST_END; y++) {
if (st_temp[y].order == x) {
if (y == ST_ERROR) {
if (!st_temp[state_last].have_return) {
printf(" goto tr_error;\n");
st_temp[ST_ERROR].need_label = 1;
}
} else {
do_st_temp(y);
}
state_last = y;
}
}
}
if (!st_temp[state_last].have_return) {
printf(" return;\n");
}
printf("\n");
do_st_temp(ST_ERROR);
state_last = st_temp[ST_ERROR].next_state;
if (!st_temp[ST_ERROR].have_return) {
printf(" goto %s;\n",
(state_last == ST_SETUP) ? "tr_setup" :
(state_last == ST_TRANSFERRED) ? "tr_transferred" :
"super_invalid_label");
}
}
printf(" }\n");
ptr = p3;
goto complete;
}
print_to(&ptr, end, 0);
return 0;
}
Affected files ...
.. //depot/projects/usb/src/sys/dev/ata/ata-usb.c#20 edit
.. //depot/projects/usb/src/sys/dev/sound/usb/uaudio.c#19 edit
.. //depot/projects/usb/src/sys/dev/usb/README#19 edit
.. //depot/projects/usb/src/sys/dev/usb/if_aue.c#32 edit
.. //depot/projects/usb/src/sys/dev/usb/if_axe.c#33 edit
.. //depot/projects/usb/src/sys/dev/usb/if_cdce.c#26 edit
.. //depot/projects/usb/src/sys/dev/usb/if_cue.c#28 edit
.. //depot/projects/usb/src/sys/dev/usb/if_kue.c#30 edit
.. //depot/projects/usb/src/sys/dev/usb/if_rue.c#28 edit
.. //depot/projects/usb/src/sys/dev/usb/if_rum.c#11 edit
.. //depot/projects/usb/src/sys/dev/usb/if_udav.c#28 edit
.. //depot/projects/usb/src/sys/dev/usb/if_ural.c#35 edit
.. //depot/projects/usb/src/sys/dev/usb/if_zyd.c#17 edit
.. //depot/projects/usb/src/sys/dev/usb/uark.c#9 edit
.. //depot/projects/usb/src/sys/dev/usb/ubsa.c#25 edit
.. //depot/projects/usb/src/sys/dev/usb/ubser.c#18 edit
.. //depot/projects/usb/src/sys/dev/usb/ucycom.c#19 edit
.. //depot/projects/usb/src/sys/dev/usb/udbp.c#15 edit
.. //depot/projects/usb/src/sys/dev/usb/ufoma.c#25 edit
.. //depot/projects/usb/src/sys/dev/usb/uftdi.c#23 edit
.. //depot/projects/usb/src/sys/dev/usb/ugen.c#25 edit
.. //depot/projects/usb/src/sys/dev/usb/ugensa.c#10 edit
.. //depot/projects/usb/src/sys/dev/usb/uhid.c#20 edit
.. //depot/projects/usb/src/sys/dev/usb/uhub.c#19 edit
.. //depot/projects/usb/src/sys/dev/usb/uipaq.c#9 edit
.. //depot/projects/usb/src/sys/dev/usb/ukbd.c#23 edit
.. //depot/projects/usb/src/sys/dev/usb/ulpt.c#25 edit
.. //depot/projects/usb/src/sys/dev/usb/umass.c#26 edit
.. //depot/projects/usb/src/sys/dev/usb/umct.c#19 edit
.. //depot/projects/usb/src/sys/dev/usb/umodem.c#28 edit
.. //depot/projects/usb/src/sys/dev/usb/umoscom.c#7 edit
.. //depot/projects/usb/src/sys/dev/usb/ums.c#25 edit
.. //depot/projects/usb/src/sys/dev/usb/uplcom.c#26 edit
.. //depot/projects/usb/src/sys/dev/usb/urio.c#15 edit
.. //depot/projects/usb/src/sys/dev/usb/usb_compat_linux.c#8 edit
.. //depot/projects/usb/src/sys/dev/usb/usb_transfer.c#35 edit
.. //depot/projects/usb/src/sys/dev/usb/uscanner.c#12 edit
.. //depot/projects/usb/src/sys/dev/usb/uvisor.c#21 edit
.. //depot/projects/usb/src/sys/dev/usb/uvscom.c#26 edit
.. //depot/projects/usb/src/sys/netgraph/bluetooth/drivers/ubt/ng_ubt.c#16 edit
.. //depot/projects/usb/src/sys/netgraph/bluetooth/drivers/ubtbcmfw/ubtbcmfw.c#12 edit
Differences ...
==== //depot/projects/usb/src/sys/dev/ata/ata-usb.c#20 (text) ====
@@ -483,17 +483,12 @@
struct atausb_softc *sc = xfer->priv_sc;
usb_device_request_t req;
- USBD_CHECK_STATUS(xfer);
-
- tr_error:
- atausb_tr_error(xfer);
- return;
-
- tr_transferred:
+ switch (USBD_GET_STATE(xfer)) {
+ case USBD_ST_TRANSFERRED:
atausb_transfer_start(sc, ATAUSB_T_BBB_RESET2);
return;
- tr_setup:
+ case USBD_ST_SETUP:
req.bmRequestType = UT_WRITE_CLASS_INTERFACE;
req.bRequest = 0xff; /* bulk-only reset */
USETW(req.wValue, 0);
@@ -508,6 +503,12 @@
usbd_start_hardware(xfer);
return;
+
+ default: /* Error */
+ atausb_tr_error(xfer);
+ return;
+
+ }
}
static void
@@ -533,21 +534,22 @@
{
struct atausb_softc *sc = xfer->priv_sc;
- USBD_CHECK_STATUS(xfer);
-
- tr_error:
- atausb_tr_error(xfer);
- return;
-
- tr_transferred:
+ switch (USBD_GET_STATE(xfer)) {
+ case USBD_ST_TRANSFERRED: tr_transferred:
atausb_transfer_start(sc, next_xfer);
return;
- tr_setup:
+ case USBD_ST_SETUP:
if (usbd_clear_stall_callback(xfer, sc->xfer[stall_xfer])) {
goto tr_transferred;
}
return;
+
+ default: /* Error */
+ atausb_tr_error(xfer);
+ return;
+
+ }
}
static void
@@ -558,20 +560,15 @@
struct ata_channel *ch;
uint32_t tag;
- USBD_CHECK_STATUS(xfer);
-
- tr_error:
- atausb_tr_error(xfer);
- return;
-
- tr_transferred:
+ switch (USBD_GET_STATE(xfer)) {
+ case USBD_ST_TRANSFERRED:
atausb_transfer_start
(sc, ((request->flags & ATA_R_READ) ? ATAUSB_T_BBB_DATA_READ :
(request->flags & ATA_R_WRITE) ? ATAUSB_T_BBB_DATA_WRITE :
ATAUSB_T_BBB_STATUS));
return;
- tr_setup:
+ case USBD_ST_SETUP:
sc->status_try = 0;
@@ -597,6 +594,12 @@
usbd_start_hardware(xfer);
}
return;
+
+ default: /* Error */
+ atausb_tr_error(xfer);
+ return;
+
+ }
}
static void
@@ -605,17 +608,8 @@
struct atausb_softc *sc = xfer->priv_sc;
uint32_t max_bulk = xfer->max_data_length;
- USBD_CHECK_STATUS(xfer);
-
- tr_error:
- if (xfer->error == USBD_CANCELLED) {
- atausb_tr_error(xfer);
- } else {
- atausb_transfer_start(sc, ATAUSB_T_BBB_DATA_RD_CS);
- }
- return;
-
- tr_transferred:
+ switch (USBD_GET_STATE(xfer)) {
+ case USBD_ST_TRANSFERRED:
usbd_copy_out(&(xfer->buf_data), 0,
sc->ata_data, xfer->actlen);
@@ -629,7 +623,7 @@
sc->ata_bytecount = 0;
}
- tr_setup:
+ case USBD_ST_SETUP:
if (atausbdebug > 1) {
device_printf(sc->dev, "%s: max_bulk=%d, ata_bytecount=%d\n",
@@ -650,6 +644,16 @@
usbd_start_hardware(xfer);
return;
+
+ default: /* Error */
+ if (xfer->error == USBD_CANCELLED) {
+ atausb_tr_error(xfer);
+ } else {
+ atausb_transfer_start(sc, ATAUSB_T_BBB_DATA_RD_CS);
+ }
+ return;
+
+ }
}
static void
@@ -666,23 +670,14 @@
struct atausb_softc *sc = xfer->priv_sc;
uint32_t max_bulk = xfer->max_data_length;
- USBD_CHECK_STATUS(xfer);
+ switch (USBD_GET_STATE(xfer)) {
+ case USBD_ST_TRANSFERRED:
- tr_error:
- if (xfer->error == USBD_CANCELLED) {
- atausb_tr_error(xfer);
- } else {
- atausb_transfer_start(sc, ATAUSB_T_BBB_DATA_WR_CS);
- }
- return;
-
- tr_transferred:
-
sc->ata_bytecount -= xfer->actlen;
sc->ata_data += xfer->actlen;
sc->ata_donecount += xfer->actlen;
- tr_setup:
+ case USBD_ST_SETUP:
if (atausbdebug > 1) {
device_printf(sc->dev, "%s: max_bulk=%d, ata_bytecount=%d\n",
@@ -706,6 +701,16 @@
usbd_start_hardware(xfer);
return;
+
+ default: /* Error */
+ if (xfer->error == USBD_CANCELLED) {
+ atausb_tr_error(xfer);
+ } else {
+ atausb_transfer_start(sc, ATAUSB_T_BBB_DATA_WR_CS);
+ }
+ return;
+
+ }
}
static void
@@ -723,20 +728,9 @@
struct ata_request *request = sc->ata_request;
uint32_t residue;
- USBD_CHECK_STATUS(xfer);
-
- tr_error:
- if ((xfer->error == USBD_CANCELLED) ||
- (sc->status_try)) {
- atausb_tr_error(xfer);
- } else {
- sc->status_try = 1;
- atausb_transfer_start(sc, ATAUSB_T_BBB_DATA_RD_CS);
- }
- return;
+ switch (USBD_GET_STATE(xfer)) {
+ case USBD_ST_TRANSFERRED:
- tr_transferred:
-
if (xfer->actlen < sizeof(sc->csw)) {
bzero(&(sc->csw), sizeof(sc->csw));
}
@@ -815,10 +809,22 @@
mtx_lock(xfer->priv_mtx);
return;
- tr_setup:
+ case USBD_ST_SETUP:
xfer->frlengths[0] = xfer->max_data_length;
usbd_start_hardware(xfer);
return;
+
+ default: tr_error:
+ if ((xfer->error == USBD_CANCELLED) ||
+ (sc->status_try)) {
+ atausb_tr_error(xfer);
+ } else {
+ sc->status_try = 1;
+ atausb_transfer_start(sc, ATAUSB_T_BBB_DATA_RD_CS);
+ }
+ return;
+
+ }
}
static void
==== //depot/projects/usb/src/sys/dev/sound/usb/uaudio.c#19 (text+ko) ====
@@ -1226,14 +1226,8 @@
uint32_t total = (ch->bytes_per_frame * xfer->nframes);
uint32_t offset;
- USBD_CHECK_STATUS(xfer);
-
- tr_error:
- if (xfer->error == USBD_CANCELLED) {
- return;
- }
-
- tr_transferred:
+ switch (USBD_GET_STATE(xfer)) {
+ case USBD_ST_TRANSFERRED: tr_transferred:
if (xfer->actlen < xfer->sumlen) {
DPRINTF(0, "short transfer, "
"%d of %d bytes\n", xfer->actlen, total);
@@ -1241,7 +1235,7 @@
chn_intr(ch->pcm_ch);
- tr_setup:
+ case USBD_ST_SETUP:
if (ch->bytes_per_frame > xfer->max_frame_size) {
DPRINTF(0, "bytes per transfer, %d, "
"exceeds maximum, %d!\n",
@@ -1283,6 +1277,14 @@
usbd_start_hardware(xfer);
return;
+
+ default: /* Error */
+ if (xfer->error == USBD_CANCELLED) {
+ return;
+ }
+
+ goto tr_transferred;
+ }
}
static void
@@ -1296,14 +1298,8 @@
uint32_t offset0;
uint32_t offset1;
- USBD_CHECK_STATUS(xfer);
-
- tr_error:
- if (xfer->error == USBD_CANCELLED) {
- return;
- }
-
- tr_transferred:
+ switch (USBD_GET_STATE(xfer)) {
+ case USBD_ST_TRANSFERRED: tr_transferred:
if (xfer->actlen < total) {
DPRINTF(0, "short transfer, "
"%d of %d bytes\n", xfer->actlen, total);
@@ -1341,7 +1337,7 @@
chn_intr(ch->pcm_ch);
- tr_setup:
+ case USBD_ST_SETUP:
if (ch->bytes_per_frame > xfer->max_frame_size) {
DPRINTF(0, "bytes per transfer, %d, "
"exceeds maximum, %d!\n",
@@ -1361,6 +1357,14 @@
usbd_start_hardware(xfer);
return;
+
+ default: /* Error */
+ if (xfer->error == USBD_CANCELLED) {
+ return;
+ }
+
+ goto tr_transferred;
+ }
}
void *
@@ -3054,14 +3058,10 @@
uint8_t chan;
uint8_t buf[2];
- USBD_CHECK_STATUS(xfer);
+ switch (USBD_GET_STATE(xfer)) {
+ case USBD_ST_TRANSFERRED: tr_transferred:
+ case USBD_ST_SETUP: tr_setup:
- tr_error:
- DPRINTF(0, "error=%s\n", usbd_errstr(xfer->error));
-
- tr_transferred:
- tr_setup:
-
if (mc == NULL) {
mc = sc->sc_mixer_root;
sc->sc_mixer_curr = mc;
@@ -3117,6 +3117,12 @@
goto tr_setup;
}
return;
+
+ default: /* Error */
+ DPRINTF(0, "error=%s\n", usbd_errstr(xfer->error));
+
+ goto tr_transferred;
+ }
}
static usbd_status
@@ -3327,21 +3333,9 @@
uint8_t cn;
uint16_t pos;
- USBD_CHECK_STATUS(xfer);
+ switch (USBD_GET_STATE(xfer)) {
+ case USBD_ST_TRANSFERRED:
- tr_error:
-
- DPRINTF(0, "error=%s\n", usbd_errstr(xfer->error));
-
- if (xfer->error != USBD_CANCELLED) {
- /* try to clear stall first */
- chan->flags |= UMIDI_FLAG_READ_STALL;
- usbd_transfer_start(chan->xfer[3]);
- }
- return;
-
- tr_transferred:
-
DPRINTF(0, "actlen=%d bytes\n", xfer->actlen);
if (xfer->actlen == 0) {
@@ -3370,7 +3364,7 @@
pos += 4;
}
- tr_setup:
+ case USBD_ST_SETUP:
DPRINTF(0, "start\n");
if (chan->flags & UMIDI_FLAG_READ_STALL) {
@@ -3380,6 +3374,19 @@
xfer->frlengths[0] = xfer->max_data_length;
usbd_start_hardware(xfer);
return;
+
+ default: tr_error:
+
+ DPRINTF(0, "error=%s\n", usbd_errstr(xfer->error));
+
+ if (xfer->error != USBD_CANCELLED) {
+ /* try to clear stall first */
+ chan->flags |= UMIDI_FLAG_READ_STALL;
+ usbd_transfer_start(chan->xfer[3]);
+ }
+ return;
+
+ }
}
static void
@@ -3540,23 +3547,11 @@
uint8_t start_cable;
>>> TRUNCATED FOR MAIL (1000 lines) <<<
More information about the p4-projects
mailing list