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