PERFORCE change 126689 for review
Hans Petter Selasky
hselasky at FreeBSD.org
Sat Sep 22 03:57:33 PDT 2007
http://perforce.freebsd.org/chv.cgi?CH=126689
Change 126689 by hselasky at 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) <<<
More information about the p4-projects
mailing list