From owner-p4-projects@FreeBSD.ORG Tue Oct 9 21:16:36 2007 Return-Path: Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id A979C16A468; Tue, 9 Oct 2007 21:16:36 +0000 (UTC) Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 3183716A417 for ; Tue, 9 Oct 2007 21:16:36 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 1F4B213C45A for ; Tue, 9 Oct 2007 21:16:36 +0000 (UTC) (envelope-from hselasky@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.1/8.14.1) with ESMTP id l99LGapP065668 for ; Tue, 9 Oct 2007 21:16:36 GMT (envelope-from hselasky@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.14.1/8.14.1/Submit) id l99LGZo6065665 for perforce@freebsd.org; Tue, 9 Oct 2007 21:16:35 GMT (envelope-from hselasky@FreeBSD.org) Date: Tue, 9 Oct 2007 21:16:35 GMT Message-Id: <200710092116.l99LGZo6065665@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to hselasky@FreeBSD.org using -f From: Hans Petter Selasky To: Perforce Change Reviews Cc: Subject: PERFORCE change 127350 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 09 Oct 2007 21:16:36 -0000 http://perforce.freebsd.org/chv.cgi?CH=127350 Change 127350 by hselasky@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 #include #include #include #include #include #include #include #include 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) <<<