Date: Sat, 22 Sep 2007 10:57:32 GMT From: Hans Petter Selasky <hselasky@FreeBSD.org> To: Perforce Change Reviews <perforce@FreeBSD.org> Subject: PERFORCE change 126689 for review Message-ID: <200709221057.l8MAvWVM079107@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=126689 Change 126689 by hselasky@hselasky_laptop001 on 2007/09/22 10:57:10 Changes to USB mass storage drivers: - Removed watchdog and reset count, use the "interval" field in "struct usbd_xfer" instead to limit infinite loops. - Factor out command cancel code into "atausb_cancel_request()" and "umass_cancel_request()" - Convert kernel USB flags into a bitmap (scripted) - Add transfer pre-delay to not stress the mass storage device when something goes wrong: - add 500ms delay before BBB reset - add 50ms delay before each clear stall command - Enable new "proxy_buffer" flag on data transport BULK transfers, so that we can use a smaller buffer to transfer large data transfers seamlessly. The proxy buffer size to use is kept in "xfer->max_data_length". - Passing a mutex to "usbd_do_request_flags()" and all "usbreq_xxx()" functions is now mandatory. - New UMASS/ATA-USB statemachine teardown mechanism: - If "sc->sc_xfer[...]" is NULL when a transfer is started the current mass storage command, if any, will be aborted. See "atausb_transfer_start()" and "umass_transfer_start()". - Transform "xfer->length" into "xfer->frlenghts[]". This is the new way to set the transfer length. - "xfer->actlen < xfer->sumlen" is the new way to check if a USB transfer is short. - One space to tab conversion. - "usbreq_set_interface()" has been renamed "usbd_set_alt_interface_index()" to clearly show that this function does more than just an USB control request. Affected files ... .. //depot/projects/usb/src/sys/dev/ata/ata-usb.c#16 edit .. //depot/projects/usb/src/sys/dev/usb/umass.c#21 edit Differences ... ==== //depot/projects/usb/src/sys/dev/ata/ata-usb.c#16 (text) ==== @@ -86,7 +86,6 @@ struct bbb_cbw cbw; struct bbb_csw csw; struct mtx locked_mtx; - struct __callout watchdog; struct ata_channel *locked_ch; struct ata_channel *restart_ch; @@ -114,7 +113,6 @@ u_int32_t ata_bytecount; u_int8_t last_xfer_no; - u_int8_t reset_count; u_int8_t usb_speed; u_int8_t intr_stalled; u_int8_t maxlun; @@ -141,8 +139,7 @@ static usbd_callback_t atausb_t_bbb_status_callback; static usbd_callback_t atausb_tr_error; -static void -atausb_watchdog(void *arg); +static void atausb_cancel_request(struct atausb_softc *sc); static void atausb_transfer_start(struct atausb_softc *sc, u_int8_t xfer_no); @@ -175,9 +172,10 @@ .endpoint = 0x00, /* Control pipe */ .direction = UE_DIR_ANY, .bufsize = sizeof(usb_device_request_t), - .flags = USBD_USE_DMA, + .flags = { }, .callback = &atausb_t_bbb_reset1_callback, .timeout = 5000, /* 5 seconds */ + .interval = 500, /* 500 milliseconds */ }, [ATAUSB_T_BBB_RESET2] = { @@ -185,9 +183,10 @@ .endpoint = 0x00, /* Control pipe */ .direction = UE_DIR_ANY, .bufsize = sizeof(usb_device_request_t), - .flags = USBD_USE_DMA, + .flags = { }, .callback = &atausb_t_bbb_reset2_callback, .timeout = 5000, /* 5 seconds */ + .interval = 50, /* 50 milliseconds */ }, [ATAUSB_T_BBB_RESET3] = { @@ -195,9 +194,10 @@ .endpoint = 0x00, /* Control pipe */ .direction = UE_DIR_ANY, .bufsize = sizeof(usb_device_request_t), - .flags = USBD_USE_DMA, + .flags = { }, .callback = &atausb_t_bbb_reset3_callback, .timeout = 5000, /* 5 seconds */ + .interval = 50, /* 50 milliseconds */ }, [ATAUSB_T_BBB_COMMAND] = { @@ -205,7 +205,7 @@ .endpoint = UE_ADDR_ANY, .direction = UE_DIR_OUT, .bufsize = sizeof(struct bbb_cbw), - .flags = USBD_USE_DMA, + .flags = { }, .callback = &atausb_t_bbb_command_callback, .timeout = 5000, /* 5 seconds */ }, @@ -215,7 +215,7 @@ .endpoint = UE_ADDR_ANY, .direction = UE_DIR_IN, .bufsize = ATAUSB_BULK_SIZE, - .flags = (USBD_USE_DMA|USBD_SHORT_XFER_OK), + .flags = { .proxy_buffer = 1, .short_xfer_ok = 1, }, .callback = &atausb_t_bbb_data_read_callback, .timeout = 0, /* overwritten later */ }, @@ -225,7 +225,7 @@ .endpoint = 0x00, /* Control pipe */ .direction = UE_DIR_ANY, .bufsize = sizeof(usb_device_request_t), - .flags = USBD_USE_DMA, + .flags = { }, .callback = &atausb_t_bbb_data_rd_cs_callback, .timeout = 5000, /* 5 seconds */ }, @@ -235,7 +235,7 @@ .endpoint = UE_ADDR_ANY, .direction = UE_DIR_OUT, .bufsize = ATAUSB_BULK_SIZE, - .flags = USBD_USE_DMA, + .flags = { .proxy_buffer = 1, .short_xfer_ok = 1, }, .callback = &atausb_t_bbb_data_write_callback, .timeout = 0, /* overwritten later */ }, @@ -245,7 +245,7 @@ .endpoint = 0x00, /* Control pipe */ .direction = UE_DIR_ANY, .bufsize = sizeof(usb_device_request_t), - .flags = USBD_USE_DMA, + .flags = { }, .callback = &atausb_t_bbb_data_wr_cs_callback, .timeout = 5000, /* 5 seconds */ }, @@ -255,7 +255,7 @@ .endpoint = UE_ADDR_ANY, .direction = UE_DIR_IN, .bufsize = sizeof(struct bbb_csw), - .flags = (USBD_USE_DMA|USBD_SHORT_XFER_OK), + .flags = { .short_xfer_ok = 1, }, .callback = &atausb_t_bbb_status_callback, .timeout = 5000, /* ms */ }, @@ -343,9 +343,6 @@ sc->usb_speed = usbd_get_speed(uaa->device); mtx_init(&(sc->locked_mtx), "ATAUSB lock", NULL, (MTX_DEF|MTX_RECURSE)); - __callout_init_mtx(&(sc->watchdog), - &(sc->locked_mtx), CALLOUT_RETURNUNLOCKED); - id = usbd_get_interface_descriptor(uaa->iface); switch (id->bInterfaceProtocol) { case UIPROTO_MASS_BBB: @@ -409,7 +406,7 @@ USETW(request.wValue, 0); USETW(request.wIndex, sc->iface_no); USETW(request.wLength, sizeof(maxlun)); - err = usbd_do_request(uaa->device, &request, &maxlun); + err = usbd_do_request(uaa->device, &usb_global_lock, &request, &maxlun); if (err) { if (bootverbose) { @@ -433,12 +430,6 @@ } bus_generic_attach(sc->dev); - /* start the watchdog */ - - mtx_lock(&(sc->locked_mtx)); - - atausb_watchdog(sc); - return 0; detach: @@ -453,23 +444,10 @@ device_t *children; int nchildren, i; - mtx_lock(&(sc->locked_mtx)); + /* teardown our statemachine */ - /* stop watchdog */ - __callout_stop(&(sc->watchdog)); + usbd_transfer_unsetup(sc->xfer, ATAUSB_T_MAX); - /* signal that device is going away */ - sc->last_xfer_no = ATAUSB_T_MAX; - - /* stop all transfers, if any */ - for (i = 0; i < ATAUSB_T_MAX; i++) { - if (sc->xfer[i]) { - usbd_transfer_stop(sc->xfer[i]); - } - } - - mtx_unlock(&(sc->locked_mtx)); - /* detach & delete all children, if any */ if (!device_get_children(dev, &children, &nchildren)) { @@ -479,38 +457,23 @@ free(children, M_TEMP); } - usbd_transfer_unsetup(sc->xfer, ATAUSB_T_MAX); - - __callout_drain(&(sc->watchdog)); - mtx_destroy(&sc->locked_mtx); return 0; } static void -atausb_watchdog(void *arg) -{ - struct atausb_softc *sc = arg; - - mtx_assert(&(sc->locked_mtx), MA_OWNED); - -#if 0 - __callout_reset(&(sc->watchdog), - hz, &atausb_watchdog, sc); -#endif - - mtx_unlock(&(sc->locked_mtx)); - return; -} - -static void atausb_transfer_start(struct atausb_softc *sc, u_int8_t xfer_no) { if (atausbdebug) { device_printf(sc->dev, "BBB transfer %d\n", xfer_no); } - sc->last_xfer_no = xfer_no; - usbd_transfer_start(sc->xfer[xfer_no]); + + if (sc->xfer[xfer_no]) { + sc->last_xfer_no = xfer_no; + usbd_transfer_start(sc->xfer[xfer_no]); + } else { + atausb_cancel_request(sc); + } return; } @@ -531,9 +494,6 @@ return; tr_setup: - - sc->reset_count ++; - req.bmRequestType = UT_WRITE_CLASS_INTERFACE; req.bRequest = 0xff; /* bulk-only reset */ USETW(req.wValue, 0); @@ -541,7 +501,10 @@ req.wIndex[1] = 0; USETW(req.wLength, 0); - usbd_copy_in(&(xfer->buf_data), 0, &req, sizeof(req)); + usbd_copy_in(xfer->frbuffers + 0, 0, &req, sizeof(req)); + + xfer->frlengths[0] = sizeof(req); + xfer->frlengths[1] = 0; usbd_start_hardware(xfer); return; @@ -610,7 +573,6 @@ tr_setup: - sc->reset_count = 0; sc->status_try = 0; if (request) { @@ -631,6 +593,7 @@ usbd_copy_in(&(xfer->buf_data), 0, &(sc->cbw), sizeof(sc->cbw)); + xfer->frlengths[0] = sizeof(sc->cbw); usbd_start_hardware(xfer); } return; @@ -640,8 +603,8 @@ atausb_t_bbb_data_read_callback(struct usbd_xfer *xfer) { struct atausb_softc *sc = xfer->priv_sc; - u_int32_t max_bulk = (ATAUSB_BULK_SIZE - - (ATAUSB_BULK_SIZE % xfer->max_packet_size)); + u_int32_t max_bulk = xfer->max_data_length; + USBD_CHECK_STATUS(xfer); tr_error: @@ -661,7 +624,7 @@ sc->ata_data += xfer->actlen; sc->ata_donecount += xfer->actlen; - if (xfer->actlen < xfer->length) { + if (xfer->actlen < xfer->sumlen) { /* short transfer */ sc->ata_bytecount = 0; } @@ -683,7 +646,7 @@ } xfer->timeout = sc->timeout; - xfer->length = max_bulk; + xfer->frlengths[0] = max_bulk; usbd_start_hardware(xfer); return; @@ -701,8 +664,8 @@ atausb_t_bbb_data_write_callback(struct usbd_xfer *xfer) { struct atausb_softc *sc = xfer->priv_sc; - u_int32_t max_bulk = (ATAUSB_BULK_SIZE - - (ATAUSB_BULK_SIZE % xfer->max_packet_size)); + u_int32_t max_bulk = xfer->max_data_length; + USBD_CHECK_STATUS(xfer); tr_error: @@ -736,7 +699,7 @@ } xfer->timeout = sc->timeout; - xfer->length = max_bulk; + xfer->frlengths[0] = max_bulk; usbd_copy_in(&(xfer->buf_data), 0, sc->ata_data, max_bulk); @@ -845,28 +808,46 @@ sc->ata_request = NULL; - if (atausbdebug > 1) { - device_printf(sc->dev, "%s: depreciated unlock!\n", - __FUNCTION__); - } + mtx_unlock(xfer->priv_mtx); - mtx_unlock(xfer->priv_mtx); /* XXX depreciated! */ - ata_interrupt(device_get_softc(request->parent)); mtx_lock(xfer->priv_mtx); return; tr_setup: + xfer->frlengths[0] = xfer->max_data_length; usbd_start_hardware(xfer); return; } static void +atausb_cancel_request(struct atausb_softc *sc) +{ + struct ata_request *request; + + mtx_assert(&(sc->locked_mtx), MA_OWNED); + + request = sc->ata_request; + sc->ata_request = NULL; + sc->last_xfer_no = ATAUSB_T_BBB_RESET1; + + if (request) { + request->error = ATA_E_ATAPI_SENSE_MASK; + + mtx_unlock(&(sc->locked_mtx)); + + ata_interrupt(device_get_softc(request->parent)); + + mtx_lock(&(sc->locked_mtx)); + } + return; +} + +static void atausb_tr_error(struct usbd_xfer *xfer) { struct atausb_softc *sc = xfer->priv_sc; - struct ata_request *request = sc->ata_request; if (xfer->error != USBD_CANCELLED) { @@ -875,38 +856,10 @@ "-> BULK reset\n", usbd_errstr(xfer->error), sc->last_xfer_no); } - - if (sc->reset_count < 16) { - - /* start reset before any callback */ - - atausb_transfer_start(sc, ATAUSB_T_BBB_RESET1); - } else { - - /* suspend reset until next command */ - - sc->last_xfer_no = ATAUSB_T_BBB_RESET1; - sc->reset_count = 0; - - device_printf(sc->dev, "timeout: giving up reset!\n"); - } } - if (request) { - request->result = (xfer->error == USBD_CANCELLED) ? ENXIO : EIO; - sc->ata_request = NULL; - - if (atausbdebug > 1) { - device_printf(sc->dev, "%s: depreciated unlock!\n", - __FUNCTION__); - } + atausb_cancel_request(sc); - mtx_unlock(xfer->priv_mtx); /* XXX depreciated! */ - - ata_interrupt(device_get_softc(request->parent)); - - mtx_lock(xfer->priv_mtx); - } return; } @@ -971,9 +924,9 @@ request->bytecount = 255; /* sizeof(struct atapi_inquiry); */ } - if (sc->last_xfer_no < ATAUSB_T_MAX) { + if (sc->xfer[sc->last_xfer_no]) { - sc->ata_request = request; + sc->ata_request = request; sc->ata_bytecount = request->bytecount; sc->ata_data = request->data; sc->ata_donecount = 0; ==== //depot/projects/usb/src/sys/dev/usb/umass.c#21 (text+ko) ==== @@ -908,7 +908,6 @@ u_int8_t sc_iface_no; /* interface number */ u_int8_t sc_maxlun; /* maximum LUN number, inclusive */ u_int8_t sc_last_xfer_index; - u_int8_t sc_reset_count; u_int8_t sc_status_try; }; @@ -946,6 +945,8 @@ static usbd_callback_t umass_t_cbi_data_wr_cs_callback; static usbd_callback_t umass_t_cbi_status_callback; +static void umass_cancel_ccb(struct umass_softc *sc); + static void umass_init_shuttle(struct umass_softc *sc); @@ -1041,9 +1042,10 @@ .endpoint = 0x00, /* Control pipe */ .direction = UE_DIR_ANY, .bufsize = sizeof(usb_device_request_t), - .flags = USBD_USE_DMA, + .flags = { }, .callback = &umass_t_bbb_reset1_callback, .timeout = 5000, /* 5 seconds */ + .interval = 500, /* 500 milliseconds */ }, [UMASS_T_BBB_RESET2] = { @@ -1051,9 +1053,10 @@ .endpoint = 0x00, /* Control pipe */ .direction = UE_DIR_ANY, .bufsize = sizeof(usb_device_request_t), - .flags = USBD_USE_DMA, + .flags = { }, .callback = &umass_t_bbb_reset2_callback, .timeout = 5000, /* 5 seconds */ + .interval = 50, /* 50 milliseconds */ }, [UMASS_T_BBB_RESET3] = { @@ -1061,9 +1064,10 @@ .endpoint = 0x00, /* Control pipe */ .direction = UE_DIR_ANY, .bufsize = sizeof(usb_device_request_t), - .flags = USBD_USE_DMA, + .flags = { }, .callback = &umass_t_bbb_reset3_callback, .timeout = 5000, /* 5 seconds */ + .interval = 50, /* 50 milliseconds */ }, [UMASS_T_BBB_COMMAND] = { @@ -1071,7 +1075,7 @@ .endpoint = UE_ADDR_ANY, .direction = UE_DIR_OUT, .bufsize = sizeof(umass_bbb_cbw_t), - .flags = USBD_USE_DMA, + .flags = { }, .callback = &umass_t_bbb_command_callback, .timeout = 5000, /* 5 seconds */ }, @@ -1081,7 +1085,7 @@ .endpoint = UE_ADDR_ANY, .direction = UE_DIR_IN, .bufsize = UMASS_BULK_SIZE, - .flags = (USBD_USE_DMA|USBD_SHORT_XFER_OK), + .flags = { .proxy_buffer = 1, .short_xfer_ok = 1, }, .callback = &umass_t_bbb_data_read_callback, .timeout = 0, /* overwritten later */ }, @@ -1091,7 +1095,7 @@ .endpoint = 0x00, /* Control pipe */ .direction = UE_DIR_ANY, .bufsize = sizeof(usb_device_request_t), - .flags = USBD_USE_DMA, + .flags = { }, .callback = &umass_t_bbb_data_rd_cs_callback, .timeout = 5000, /* 5 seconds */ }, @@ -1101,7 +1105,7 @@ .endpoint = UE_ADDR_ANY, .direction = UE_DIR_OUT, .bufsize = UMASS_BULK_SIZE, - .flags = (USBD_USE_DMA|USBD_SHORT_XFER_OK), + .flags = { .proxy_buffer = 1, .short_xfer_ok = 1, }, .callback = &umass_t_bbb_data_write_callback, .timeout = 0, /* overwritten later */ }, @@ -1111,7 +1115,7 @@ .endpoint = 0x00, /* Control pipe */ .direction = UE_DIR_ANY, .bufsize = sizeof(usb_device_request_t), - .flags = USBD_USE_DMA, + .flags = { }, .callback = &umass_t_bbb_data_wr_cs_callback, .timeout = 5000, /* 5 seconds */ }, @@ -1121,7 +1125,7 @@ .endpoint = UE_ADDR_ANY, .direction = UE_DIR_IN, .bufsize = sizeof(umass_bbb_csw_t), - .flags = (USBD_USE_DMA|USBD_SHORT_XFER_OK), + .flags = { .short_xfer_ok = 1, }, .callback = &umass_t_bbb_status_callback, .timeout = 5000, /* ms */ }, @@ -1135,9 +1139,10 @@ .direction = UE_DIR_ANY, .bufsize = (sizeof(usb_device_request_t) + UMASS_CBI_DIAGNOSTIC_CMDLEN), - .flags = USBD_USE_DMA, + .flags = { }, .callback = &umass_t_cbi_reset1_callback, .timeout = 5000, /* 5 seconds */ + .interval = 500, /* 500 milliseconds */ }, [UMASS_T_CBI_RESET2] = { @@ -1145,9 +1150,10 @@ .endpoint = 0x00, /* Control pipe */ .direction = UE_DIR_ANY, .bufsize = sizeof(usb_device_request_t), - .flags = USBD_USE_DMA, + .flags = { }, .callback = &umass_t_cbi_reset2_callback, .timeout = 5000, /* 5 seconds */ + .interval = 50, /* 50 milliseconds */ }, [UMASS_T_CBI_RESET3] = { @@ -1155,9 +1161,10 @@ .endpoint = 0x00, /* Control pipe */ .direction = UE_DIR_ANY, .bufsize = sizeof(usb_device_request_t), - .flags = USBD_USE_DMA, + .flags = { }, .callback = &umass_t_cbi_reset3_callback, .timeout = 5000, /* 5 seconds */ + .interval = 50, /* 50 milliseconds */ }, [UMASS_T_CBI_COMMAND] = { @@ -1166,7 +1173,7 @@ .direction = UE_DIR_ANY, .bufsize = (sizeof(usb_device_request_t) + UMASS_MAX_CMDLEN), - .flags = USBD_USE_DMA, + .flags = { }, .callback = &umass_t_cbi_command_callback, .timeout = 5000, /* 5 seconds */ }, @@ -1176,7 +1183,7 @@ .endpoint = UE_ADDR_ANY, .direction = UE_DIR_IN, .bufsize = UMASS_BULK_SIZE, - .flags = (USBD_USE_DMA|USBD_SHORT_XFER_OK), + .flags = { .proxy_buffer = 1, .short_xfer_ok = 1, }, .callback = &umass_t_cbi_data_read_callback, .timeout = 0, /* overwritten later */ }, @@ -1186,7 +1193,7 @@ .endpoint = 0x00, /* Control pipe */ .direction = UE_DIR_ANY, .bufsize = sizeof(usb_device_request_t), - .flags = USBD_USE_DMA, + .flags = { }, .callback = &umass_t_cbi_data_rd_cs_callback, .timeout = 5000, /* 5 seconds */ }, @@ -1196,7 +1203,7 @@ .endpoint = UE_ADDR_ANY, .direction = UE_DIR_OUT, .bufsize = UMASS_BULK_SIZE, - .flags = (USBD_USE_DMA|USBD_SHORT_XFER_OK), + .flags = { .proxy_buffer = 1, .short_xfer_ok = 1, }, .callback = &umass_t_cbi_data_write_callback, .timeout = 0, /* overwritten later */ }, @@ -1206,7 +1213,7 @@ .endpoint = 0x00, /* Control pipe */ .direction = UE_DIR_ANY, .bufsize = sizeof(usb_device_request_t), - .flags = USBD_USE_DMA, + .flags = { }, .callback = &umass_t_cbi_data_wr_cs_callback, .timeout = 5000, /* 5 seconds */ }, @@ -1215,7 +1222,7 @@ .type = UE_INTERRUPT, .endpoint = UE_ADDR_ANY, .direction = UE_DIR_IN, - .flags = (USBD_USE_DMA|USBD_SHORT_XFER_OK), + .flags = { .short_xfer_ok = 1, }, .bufsize = sizeof(umass_cbi_sbl_t), .callback = &umass_t_cbi_status_callback, .timeout = 5000, /* ms */ @@ -1226,7 +1233,7 @@ .endpoint = 0x00, /* Control pipe */ .direction = UE_DIR_ANY, .bufsize = sizeof(usb_device_request_t), - .flags = USBD_USE_DMA, + .flags = { }, .callback = &umass_t_cbi_reset4_callback, .timeout = 5000, /* ms */ }, @@ -1489,8 +1496,9 @@ #endif if (sc->sc_quirks & ALT_IFACE_1) { - err = usbreq_set_interface(uaa->device, - uaa->iface_index, 1); + err = usbd_set_alt_interface_index + (uaa->device, uaa->iface_index, 1); + if (err) { DPRINTF(sc, UDMASS_USB, "could not switch to " "Alt Interface 1\n"); @@ -1585,21 +1593,15 @@ umass_detach(device_t dev) { struct umass_softc *sc = device_get_softc(dev); - u_int8_t i; DPRINTF(sc, UDMASS_USB, "\n"); - mtx_lock(&(sc->sc_mtx)); + /* teardown our statemachine */ - /* signal that the device is going away */ - sc->sc_last_xfer_index = UMASS_T_MAX; + usbd_transfer_unsetup(sc->sc_xfer, UMASS_T_MAX); - for (i = 0; i < UMASS_T_MAX; i++) { - usbd_transfer_stop(sc->sc_xfer[i]); - } - -#if (__FreeBSD_version < 700037) - mtx_unlock(&(sc->sc_mtx)); +#if (__FreeBSD_version >= 700037) + mtx_lock(&(sc->sc_mtx)); #endif umass_cam_detach_sim(sc); @@ -1607,8 +1609,6 @@ mtx_unlock(&(sc->sc_mtx)); #endif - usbd_transfer_unsetup(sc->sc_xfer, UMASS_T_MAX); - mtx_destroy(&(sc->sc_mtx)); return 0; /* success */ @@ -1618,6 +1618,7 @@ umass_init_shuttle(struct umass_softc *sc) { usb_device_request_t req; + usbd_status err; u_int8_t status[2] = { 0, 0 }; /* The Linux driver does this, but no one can tell us what the @@ -1629,7 +1630,7 @@ req.wIndex[0] = sc->sc_iface_no; req.wIndex[1] = 0; USETW(req.wLength, sizeof(status)); - (void) usbd_do_request(sc->sc_udev, &req, &status); + err = usbd_do_request(sc->sc_udev, &Giant, &req, &status); DPRINTF(sc, UDMASS_GEN, "Shuttle init returned 0x%02x%02x\n", status[0], status[1]); @@ -1645,8 +1646,13 @@ { DPRINTF(sc, UDMASS_GEN, "transfer index = " "%d\n", xfer_index); - sc->sc_last_xfer_index = xfer_index; - usbd_transfer_start(sc->sc_xfer[xfer_index]); + + if (sc->sc_xfer[xfer_index]) { + sc->sc_last_xfer_index = xfer_index; + usbd_transfer_start(sc->sc_xfer[xfer_index]); + } else { + umass_cancel_ccb(sc); + } return; } @@ -1658,10 +1664,26 @@ /* stop the last transfer, * if not already stopped: */ - if (sc->sc_last_xfer_index < UMASS_T_MAX) { - usbd_transfer_stop(sc->sc_xfer[sc->sc_last_xfer_index]); - sc->sc_reset_count = 0; - umass_transfer_start(sc, 0); + usbd_transfer_stop(sc->sc_xfer[sc->sc_last_xfer_index]); + umass_transfer_start(sc, 0); + return; +} + +static void +umass_cancel_ccb(struct umass_softc *sc) +{ + union ccb *ccb; + + mtx_assert(&(sc->sc_mtx), MA_OWNED); + + ccb = sc->sc_transfer.ccb; + sc->sc_transfer.ccb = NULL; + sc->sc_last_xfer_index = 0; + + if (ccb) { + (sc->sc_transfer.callback) + (sc, ccb, (sc->sc_transfer.data_len - + sc->sc_transfer.actlen), STATUS_WIRE_FAILED); } return; } @@ -1670,38 +1692,14 @@ umass_tr_error(struct usbd_xfer *xfer) { struct umass_softc *sc = xfer->priv_sc; - union ccb *ccb = sc->sc_transfer.ccb; if (xfer->error != USBD_CANCELLED) { DPRINTF(sc, UDMASS_GEN, "transfer error, %s -> " "reset\n", usbd_errstr(xfer->error)); - - if (sc->sc_reset_count < 16) { - - /* start reset before any callback */ - - umass_transfer_start(sc, 0); - } else { - - /* suspend reset until next command */ - - sc->sc_last_xfer_index = 0; - sc->sc_reset_count = 0; - - printf("%s: timeout: giving up " - "reset!\n", sc->sc_name); - } } - if (ccb) { - - sc->sc_transfer.ccb = NULL; - - (sc->sc_transfer.callback) - (sc, ccb, (sc->sc_transfer.data_len - - sc->sc_transfer.actlen), STATUS_WIRE_FAILED); - } + umass_cancel_ccb(sc); return; } @@ -1742,8 +1740,6 @@ DPRINTF(sc, UDMASS_BBB, "BBB reset!\n"); - sc->sc_reset_count ++; - req.bmRequestType = UT_WRITE_CLASS_INTERFACE; req.bRequest = UR_BBB_RESET; /* bulk only reset */ USETW(req.wValue, 0); @@ -1751,8 +1747,10 @@ req.wIndex[1] = 0; USETW(req.wLength, 0); - usbd_copy_in(&(xfer->buf_data), 0, &req, sizeof(req)); + usbd_copy_in(xfer->frbuffers + 0, 0, &req, sizeof(req)); + xfer->frlengths[0] = sizeof(req); + xfer->frlengths[1] = 0; usbd_start_hardware(xfer); return; } @@ -1819,7 +1817,6 @@ tr_setup: - sc->sc_reset_count = 0; sc->sc_status_try = 0; if (ccb) { @@ -1874,6 +1871,7 @@ usbd_copy_in(&(xfer->buf_data), 0, &(sc->cbw), sizeof(sc->cbw)); + xfer->frlengths[0] = sizeof(sc->cbw); usbd_start_hardware(xfer); } return; @@ -1883,8 +1881,8 @@ umass_t_bbb_data_read_callback(struct usbd_xfer *xfer) { struct umass_softc *sc = xfer->priv_sc; - u_int32_t max_bulk = (UMASS_BULK_SIZE - - (UMASS_BULK_SIZE % xfer->max_packet_size)); + u_int32_t max_bulk = xfer->max_data_length; + USBD_CHECK_STATUS(xfer); tr_error: @@ -1903,7 +1901,7 @@ sc->sc_transfer.data_ptr += xfer->actlen; sc->sc_transfer.actlen += xfer->actlen; - if (xfer->actlen < xfer->length) { + if (xfer->actlen < xfer->sumlen) { /* short transfer */ sc->sc_transfer.data_rem = 0; } @@ -1922,7 +1920,7 @@ } xfer->timeout = sc->sc_transfer.data_timeout; - xfer->length = max_bulk; + xfer->frlengths[0] = max_bulk; usbd_start_hardware(xfer); return; @@ -1940,8 +1938,8 @@ umass_t_bbb_data_write_callback(struct usbd_xfer *xfer) { struct umass_softc *sc = xfer->priv_sc; - u_int32_t max_bulk = (UMASS_BULK_SIZE - - (UMASS_BULK_SIZE % xfer->max_packet_size)); + u_int32_t max_bulk = xfer->max_data_length; + USBD_CHECK_STATUS(xfer); tr_error: @@ -1957,7 +1955,7 @@ sc->sc_transfer.data_ptr += xfer->actlen; sc->sc_transfer.actlen += xfer->actlen; - if (xfer->actlen < xfer->length) { + if (xfer->actlen < xfer->sumlen) { /* short transfer */ sc->sc_transfer.data_rem = 0; } @@ -1976,7 +1974,7 @@ } xfer->timeout = sc->sc_transfer.data_timeout; - xfer->length = max_bulk; + xfer->frlengths[0] = max_bulk; usbd_copy_in(&(xfer->buf_data), 0, sc->sc_transfer.data_ptr, max_bulk); @@ -2108,6 +2106,7 @@ return; tr_setup: + xfer->frlengths[0] = xfer->max_data_length; usbd_start_hardware(xfer); return; } @@ -2136,7 +2135,7 @@ sc->sc_transfer.callback = callback; sc->sc_transfer.ccb = ccb; - if (sc->sc_last_xfer_index < UMASS_T_MAX) { + if (sc->sc_xfer[sc->sc_last_xfer_index]) { usbd_transfer_start(sc->sc_xfer[sc->sc_last_xfer_index]); } else { ccb->ccb_h.status = CAM_TID_INVALID; @@ -2160,7 +2159,7 @@ req.wIndex[1] = 0; USETW(req.wLength, 1); - err = usbd_do_request(sc->sc_udev, &req, &buf); + err = usbd_do_request(sc->sc_udev, &Giant, &req, &buf); if (err) { buf = 0; @@ -2198,10 +2197,8 @@ umass_t_cbi_reset1_callback(struct usbd_xfer *xfer) { struct umass_softc *sc = xfer->priv_sc; - struct { - usb_device_request_t req; - u_int8_t buf[UMASS_CBI_DIAGNOSTIC_CMDLEN]; - } UPACKED rst; + usb_device_request_t req; + uint8_t buf[UMASS_CBI_DIAGNOSTIC_CMDLEN]; u_int8_t i; @@ -2231,28 +2228,30 @@ DPRINTF(sc, UDMASS_CBI, "CBI reset!\n"); - sc->sc_reset_count ++; - - rst.req.bmRequestType = UT_WRITE_CLASS_INTERFACE; - rst.req.bRequest = UR_CBI_ADSC; - USETW(rst.req.wValue, 0); - rst.req.wIndex[0] = sc->sc_iface_no; - rst.req.wIndex[1] = 0; - USETW(rst.req.wLength, UMASS_CBI_DIAGNOSTIC_CMDLEN); + req.bmRequestType = UT_WRITE_CLASS_INTERFACE; + req.bRequest = UR_CBI_ADSC; + USETW(req.wValue, 0); + req.wIndex[0] = sc->sc_iface_no; + req.wIndex[1] = 0; + USETW(req.wLength, UMASS_CBI_DIAGNOSTIC_CMDLEN); /* The 0x1d code is the SEND DIAGNOSTIC command. * To distinguish between the two, the last 10 bytes * of the CBL is filled with 0xff (section 2.2 of * the CBI specification) */ - rst.req.bData[0] = 0x1d; /* Command Block Reset */ - rst.req.bData[1] = 0x04; + buf[0] = 0x1d; /* Command Block Reset */ + buf[1] = 0x04; for (i = 2; i < UMASS_CBI_DIAGNOSTIC_CMDLEN; i++) { - rst.req.bData[i] = 0xff; + buf[i] = 0xff; } - usbd_copy_in(&(xfer->buf_data), 0, &rst, sizeof(rst)); + usbd_copy_in(xfer->frbuffers + 0, 0, &req, sizeof(req)); + usbd_copy_in(xfer->frbuffers + 1, 0, buf, sizeof(buf)); + + xfer->frlengths[0] = sizeof(req); >>> TRUNCATED FOR MAIL (1000 lines) <<<
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200709221057.l8MAvWVM079107>