PERFORCE change 126719 for review

Hans Petter Selasky hselasky at FreeBSD.org
Sun Sep 23 04:59:48 PDT 2007


http://perforce.freebsd.org/chv.cgi?CH=126719

Change 126719 by hselasky at hselasky_laptop001 on 2007/09/23 11:59:42

	
	FYI; The comments follow the P4 diff from top to bottom.
	
	- change return type of "ugen_allocate_blocks()"
	
	- "ugen_allocate_blocks()" is now called unlocked
	
	- rename "__usbd_transfer_setup()" to "ugen_transfer_setup()"
	
	- "ugen_transfer_setup()" now also allocate buffer memory by
	  calling "ugen_allocate_blocks()".
	
	- new function "ugen_usb_uiomove()" that transfers memory directly
	  between an USB transfer and UIO
	
	- rename "__uiomove()" into "ugen_uiomove()".
	
	- updated several "flags |= XXX" to "flags.xxx = 1".
	
	- the maximum frame size must be read from the USB transfer
	
	- all USB BULK/ISOC/INTR IN-transfers must setup
	  "xfer->frlengths[]" before calling "usbd_start_hardware()".
	  Else the actual length of the previous transfer will be 
	  used for transfer length of the next USB transfer.
	
	- updated several "flags & XXX" to "flags_int.xxx".
	
	- USB callbacks should return in case of "xfer->error == USBD_CANCELLED".
	
	- "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.
	
	- passing a mutex to "usbd_do_request_flags()" and all
	  "usbreq_xxx()" functions is now mandatory.

Affected files ...

.. //depot/projects/usb/src/sys/dev/usb/ugen.c#21 edit

Differences ...

==== //depot/projects/usb/src/sys/dev/usb/ugen.c#21 (text+ko) ====

@@ -66,8 +66,6 @@
 
 #define UGEN_HW_FRAMES	50 /* number of milliseconds per transfer */
 
-#define ADD_BYTES(ptr,size) ((void *)(((u_int8_t *)(ptr)) + (size)))
-
 struct ugen_frame_ring {
   u_int16_t input_index;
   u_int16_t output_index;
@@ -295,7 +293,7 @@
 	}
 	else
 	{
-		*ptr = ADD_BYTES
+		*ptr = USBD_ADD_BYTES
 		  (ufr->buf, 
 		   ufr->frame_size*ufr->input_index);
 
@@ -318,7 +316,7 @@
 	}
 	else
 	{
-		*ptr = ADD_BYTES
+		*ptr = USBD_ADD_BYTES
 		  (ufr->buf,
 		   ufr->frame_size*ufr->output_index);
 
@@ -327,21 +325,22 @@
 	return;
 }
 
-static int
+static usbd_status
 ugen_allocate_blocks(struct ugen_softc *sc,
 		     struct ugen_endpoint *sce,
-		     u_int16_t context_bit,
 		     struct ugen_frame_ring *ufr, 
 		     u_int16_t frames, 
 		     u_int16_t frame_size)
 {
 	void *ptr;
 
+	mtx_lock(&(sc->sc_mtx));
 	bzero(ufr, sizeof(*ufr));
+	mtx_unlock(&(sc->sc_mtx));
 
 	if(frames == 0) 
 	{
-		return 0;
+		return USBD_INVAL;
 	}
 
 	/* one frame will always be unused
@@ -350,37 +349,21 @@
 	 */
 	frames++;
 
-	sce->state |= context_bit;
-
-	mtx_unlock(&sc->sc_mtx);
-
 	ptr = malloc(frames*(frame_size + sizeof(u_int16_t)), 
 		     M_USBDEV, M_WAITOK);
 
-	mtx_lock(&sc->sc_mtx);
-
-	sce->state &= ~context_bit;
-
-	if(sce->state & UGEN_CLOSING)
-	{
-		wakeup(sce);
-		if(ptr)
-		{
-			free(ptr, M_USBDEV);
-			ptr = NULL;
-		}
-	}
-
 	if(ptr == NULL)
 	{
-		return 0;
+		return USBD_NOMEM;
 	}
 
+	mtx_lock(&(sc->sc_mtx));
 	ufr->end_index = frames;
 	ufr->frame_size = frame_size;
-	ufr->frlengths = ADD_BYTES(ptr, frames*frame_size);
-	ufr->buf = ADD_BYTES(ptr, 0);
-	return 1;
+	ufr->frlengths = USBD_ADD_BYTES(ptr, frames*frame_size);
+	ufr->buf = USBD_ADD_BYTES(ptr, 0);
+	mtx_unlock(&(sc->sc_mtx));
+	return 0;
 }
 
 static void
@@ -402,12 +385,19 @@
 		      u_int8_t iface_index,
 		      struct usbd_xfer **pxfer,
 		      const struct usbd_config *setup,
-		      u_int8_t n_setup)
+		      u_int8_t n_setup,
+		      uint16_t n_in_frames,
+		      uint16_t n_out_frames)
 {
 	struct usbd_xfer * temp[n_setup];
 
 	usbd_status error;
 
+	if ((n_out_frames > 0) && (n_in_frames > 0)) {
+	    /* should not happen */
+	    return USBD_INVAL;
+	}
+
 	sce->state |= context_bit;
 
 	mtx_unlock(&sc->sc_mtx);
@@ -419,7 +409,22 @@
 	error = usbd_transfer_setup(udev, iface_index, &temp[0], 
 				    setup, n_setup, 
 				    sce, &(sc->sc_mtx));
+	if (error == 0) {
+	  if (n_in_frames > 0) {
+	      error = ugen_allocate_blocks
+		(sc, sce, &(sce->in_queue), n_in_frames,
+		 temp[0]->max_frame_size);
+	  } else if (n_out_frames > 0) {
+	      error = ugen_allocate_blocks
+		(sc, sce, &(sce->out_queue), n_out_frames,
+		 temp[0]->max_frame_size);
+	  }
 
+	  if (error) {
+	      usbd_transfer_unsetup(temp, n_setup);
+	  }
+	}
+
 	mtx_lock(&sc->sc_mtx);
 
 	if(sce->state & UGEN_CLOSING)
@@ -445,7 +450,7 @@
 }
 
 static int
-__uiomove(struct ugen_softc *sc, struct ugen_endpoint *sce,
+ugen_uiomove(struct ugen_softc *sc, struct ugen_endpoint *sce,
 	  u_int16_t context_bit, void *cp, int n, 
 	  struct uio *uio)
 {
@@ -474,6 +479,31 @@
 }
 
 static int
+ugen_usb_uiomove(struct ugen_softc *sc, struct ugen_endpoint *sce,
+		 struct usbd_page_cache *pc, struct uio *uio,
+		 uint32_t pc_offset, uint32_t len, uint16_t context_bit)
+{
+	int error;
+
+	sce->state |= context_bit;
+
+	mtx_unlock(&sc->sc_mtx);
+
+	error = usbd_uiomove(pc, uio, pc_offset, len);
+
+	mtx_lock(&sc->sc_mtx);
+
+	sce->state &= ~context_bit;
+
+	if(sce->state & UGEN_CLOSING)
+	{
+		wakeup(sce);
+		error = EINTR;
+	}
+	return error;
+}
+
+static int
 ugenopen(struct cdev *dev, int flag, int mode, struct thread *p)
 {
 	struct ugen_softc *sc = DEV2SC(dev);
@@ -592,7 +622,6 @@
 static int
 ugen_open_pipe_write(struct ugen_softc *sc, struct ugen_endpoint *sce)
 {
-	u_int16_t isize;
 	usbd_status err;
 
 	mtx_assert(&sc->sc_mtx, MA_OWNED);
@@ -612,7 +641,6 @@
 		usbd_config[1].direction = UE_DIR_ANY;
 		usbd_config[1].timeout = 1000; /* 1 second */
 		usbd_config[1].interval = 50; /* 50 milliseconds */
-		usbd_config[1].flags = 0;
 		usbd_config[1].bufsize = sizeof(usb_device_request_t);
 		usbd_config[1].callback = &ugen_write_clear_stall_callback;
 
@@ -622,18 +650,18 @@
 		usbd_config[0].callback = &ugen_default_write_callback;
 		usbd_config[0].interval = USBD_DEFAULT_INTERVAL;
 		usbd_config[0].timeout = sce->in_timeout;
+		usbd_config[0].flags.proxy_buffer = 1;
 
 		switch(ed->bmAttributes & UE_XFERTYPE)
 		{
 		case UE_INTERRUPT:
 		case UE_BULK:
-			usbd_config[0].flags = 0;
 			usbd_config[0].bufsize = UGEN_BULK_BUFFER_SIZE;
 			
 			if(__usbd_transfer_setup
 			   (sc, sce, UGEN_WR_CFG,
 			    sc->sc_udev, sce->pipe_out->iface_index,
-			    &sce->xfer_out[0], &usbd_config[0], 2))
+			    &sce->xfer_out[0], &usbd_config[0], 2, 0, 0))
 			{
 				return (EIO);
 			}
@@ -643,11 +671,6 @@
 			break;
 
 		case UE_ISOCHRONOUS:
-			isize = usbd_get_max_frame_size(ed);
-
-			/* the maximum frame size is validated
-			 * by "usbd_fill_iface_data()" 
-			 */
 
 			if(usbd_get_speed(sc->sc_udev) == USB_SPEED_HIGH)
 			{
@@ -658,15 +681,8 @@
 				sce->out_frames = UGEN_HW_FRAMES;
 			}
 
-			if(ugen_allocate_blocks
-			   (sc, sce, UGEN_WR_CFG, 
-			    &sce->out_queue, sce->out_frames * 10, isize) == 0)
-			{
-				return ENOMEM;
-			}
-
-			usbd_config[0].flags = USBD_SHORT_XFER_OK;
-			usbd_config[0].bufsize = isize * sce->out_frames;
+			usbd_config[0].flags.short_xfer_ok = 1;
+			usbd_config[0].bufsize = 0; /* use default */
 			usbd_config[0].frames = sce->out_frames;
 			usbd_config[0].callback = &ugenisoc_write_callback;
 			usbd_config[0].timeout = 0;
@@ -677,11 +693,11 @@
 			err = __usbd_transfer_setup
 			  (sc, sce, UGEN_WR_CFG,
 			   sc->sc_udev, sce->pipe_out->iface_index,
-			   sce->xfer_out, usbd_config, 2);
+			   sce->xfer_out, usbd_config, 2,
+			   0, 10 * sce->out_frames);
 
 			if(err)
 			{
-				ugen_free_blocks(&sce->out_queue);
 				return (EIO);
 			}
 			break;
@@ -702,7 +718,6 @@
 static int
 ugen_open_pipe_read(struct ugen_softc *sc, struct ugen_endpoint *sce)
 {
-	int isize;
 	usbd_status err;
 
 	mtx_assert(&sc->sc_mtx, MA_OWNED);
@@ -722,7 +737,6 @@
 		usbd_config[1].direction = UE_DIR_ANY;
 		usbd_config[1].timeout = 1000; /* 1 second */
 		usbd_config[1].interval = 50; /* 50 milliseconds */
-		usbd_config[1].flags = 0;
 		usbd_config[1].bufsize = sizeof(usb_device_request_t);
 		usbd_config[1].callback = &ugen_read_clear_stall_callback;
 
@@ -730,30 +744,22 @@
 		usbd_config[0].endpoint = ed->bEndpointAddress & UE_ADDR;
 		usbd_config[0].direction = UE_DIR_IN;
 		usbd_config[0].timeout = sce->in_timeout;
+		usbd_config[0].flags.proxy_buffer = 1;
 
 		switch(ed->bmAttributes & UE_XFERTYPE)
 		{
 		case UE_INTERRUPT:
-		  isize = usbd_get_max_frame_size(ed);
-		  usbd_config[0].flags = USBD_SHORT_XFER_OK;
+		  usbd_config[0].flags.short_xfer_ok = 1;
 		  usbd_config[0].callback = &ugen_interrupt_callback;
-		  usbd_config[0].bufsize = isize;
+		  usbd_config[0].bufsize = 0; /* use "wMaxPacketSize" */
 		  usbd_config[0].interval = USBD_DEFAULT_INTERVAL;
 		  usbd_config[0].timeout = 0;
 
-		  if(ugen_allocate_blocks
-		     (sc, sce, UGEN_RD_CFG,
-		      &sce->in_queue, 1, isize) == 0)
-		  {
-			return ENOMEM;
-		  }
-
 		  if(__usbd_transfer_setup
 		     (sc, sce, UGEN_RD_CFG,
 		      sc->sc_udev, sce->pipe_in->iface_index,
-		      &sce->xfer_in[0], &usbd_config[0], 2))
+		      &sce->xfer_in[0], &usbd_config[0], 2, 1, 0))
 		  {
-			ugen_free_blocks(&sce->in_queue);
 			return (EIO);
 		  }
 
@@ -765,15 +771,16 @@
 		  break;
 
 		case UE_BULK:
-		  usbd_config[0].flags = ((sce->state & UGEN_SHORT_OK) ? 
-					  USBD_SHORT_XFER_OK : 0);
+		  if (sce->state & UGEN_SHORT_OK) {
+		      usbd_config[0].flags.short_xfer_ok = 1;
+		  }
 		  usbd_config[0].callback = &ugen_default_read_callback;
 		  usbd_config[0].bufsize = UGEN_BULK_BUFFER_SIZE;
 
 		  if(__usbd_transfer_setup
 		     (sc, sce, UGEN_RD_CFG,
 		      sc->sc_udev, sce->pipe_in->iface_index,
-		      &sce->xfer_in[0], &usbd_config[0], 2))
+		      &sce->xfer_in[0], &usbd_config[0], 2, 0, 0))
 		  {
 			return (EIO);
 		  }
@@ -784,8 +791,6 @@
 
 		case UE_ISOCHRONOUS:
 
-		  isize = usbd_get_max_frame_size(ed);
-
 		  /* the maximum frame size is validated
 		   * by "usbd_fill_iface_data()" 
 		   */
@@ -799,15 +804,8 @@
 			sce->in_frames = UGEN_HW_FRAMES;
 		  }
 
-		  if(ugen_allocate_blocks
-		     (sc, sce, UGEN_RD_CFG,
-		      &sce->in_queue, sce->in_frames * 10, isize) == 0)
-		  {
-			return ENOMEM;
-		  }
-
-		  usbd_config[0].flags = USBD_SHORT_XFER_OK;
-		  usbd_config[0].bufsize = isize * sce->in_frames;
+		  usbd_config[0].flags.short_xfer_ok = 1;
+		  usbd_config[0].bufsize = 0; /* use default */
 		  usbd_config[0].frames = sce->in_frames;
 		  usbd_config[0].callback = &ugenisoc_read_callback;
 		  usbd_config[0].timeout = 0;
@@ -819,11 +817,11 @@
 		  err = __usbd_transfer_setup
 		    (sc, sce, UGEN_RD_CFG,
 		     sc->sc_udev, sce->pipe_in->iface_index,
-		     sce->xfer_in, usbd_config, 2);
+		     sce->xfer_in, usbd_config, 2, 
+		     sce->in_frames * 10, 0);
 
 		  if(err)
 		  {
-			ugen_free_blocks(&sce->in_queue);
 			return (EIO);
 		  }
 
@@ -891,7 +889,7 @@
 			}
 
 			sce->in_timeout = USBD_NO_TIMEOUT;
-			sce->out_frame_size = -1; /* set maximum value */
+			sce->out_frame_size = 0-1; /* set maximum value */
 			sce->io_buffer_size = UGEN_BULK_BUFFER_SIZE; /* set default value */
 
 			if((pipe->edesc->bEndpointAddress & 
@@ -1058,7 +1056,7 @@
 			PRINTFN(10, ("transferring %d bytes\n", len));
 
 			/* copy data to user memory */
-			error = __uiomove(sc, sce, UGEN_RD_UIO, ptr, len, uio);
+			error = ugen_uiomove(sc, sce, UGEN_RD_UIO, ptr, len, uio);
 
 			if(error) break;
 
@@ -1090,13 +1088,13 @@
 			xfer = sce->xfer_in[0];
 
 			/* update length */
-			xfer->length = n;
+			xfer->frlengths[0] = n;
 
 			/* start transfer */
 			usbd_transfer_start(xfer);
 
-			while ((xfer->flags & USBD_DEV_TRANSFERRING) ||
-			       (sce->xfer_in[1]->flags & USBD_DEV_TRANSFERRING)) {
+			while ((xfer->flags_int.transferring) ||
+			       (sce->xfer_in[1]->flags_int.transferring)) {
 
 			    /* wait for data */
 
@@ -1133,9 +1131,10 @@
 			}
 
 			PRINTFN(1, ("got %d of %d bytes\n", xfer->actlen, n));
-			error = __uiomove
-			  (sc, sce, UGEN_RD_UIO, 
-			   xfer->buffer, xfer->actlen, uio);
+
+			error = ugen_usb_uiomove
+			  (sc, sce, xfer->frbuffers + 0, uio, 0,
+			   xfer->actlen, UGEN_RD_UIO);
 
 			if(error || (xfer->actlen < n))
 			{
@@ -1207,8 +1206,10 @@
 #endif
 			xfer = sce->xfer_out[0];
 
-			error = __uiomove
-			  (sc, sce, UGEN_WR_UIO, xfer->buffer, n, uio);
+			error = ugen_usb_uiomove
+			  (sc, sce, xfer->frbuffers + 0, uio,
+			   0, n, UGEN_WR_UIO);
+
 			if(error)
 			{
 				break;
@@ -1217,13 +1218,13 @@
 			PRINTFN(1, ("transferred %d bytes\n", n));
 
 			/* update length */
-			xfer->length = n;
+			xfer->frlengths[0] = n;
 
 			/* start transfer */
 			usbd_transfer_start(xfer);
 
-			while ((xfer->flags & USBD_DEV_TRANSFERRING) ||
-			       (sce->xfer_out[1]->flags & USBD_DEV_TRANSFERRING)) {
+			while ((xfer->flags_int.transferring) ||
+			       (sce->xfer_out[1]->flags_int.transferring)) {
 
 			    /* wait for data */
 
@@ -1316,7 +1317,7 @@
 				*plen = uio->uio_resid;
 			}
 
-			error = __uiomove(sc, sce, UGEN_WR_UIO, ptr, *plen, uio);
+			error = ugen_uiomove(sc, sce, UGEN_WR_UIO, ptr, *plen, uio);
 
 			if(error) break;
 
@@ -1432,7 +1433,7 @@
 	}
 	else
 	{
-		bcopy(xfer->buffer, ptr, xfer->actlen);
+		usbd_copy_out(&(xfer->buf_data), 0, ptr, xfer->actlen);
 
 		if(xfer->actlen > *plen)
 		{
@@ -1469,6 +1470,7 @@
 	if (sce->read_stall) {
 	    usbd_transfer_start(sce->xfer_in[1]);
 	} else {
+	    xfer->frlengths[0] = xfer->max_data_length;
 	    usbd_start_hardware(xfer);
 	}
 	return;
@@ -1506,13 +1508,12 @@
 ugenisoc_read_callback(struct usbd_xfer *xfer)
 {
 	struct ugen_endpoint *sce = xfer->priv_sc;
-	u_int16_t *plen1;
+	u_int32_t *plen1;
 	u_int16_t *plen2;
 
-	void *ptr1;
 	void *ptr2;
 
-	u_int16_t isize;
+	uint32_t offset;
 	u_int16_t n;
 
 	USBD_CHECK_STATUS(xfer);
@@ -1522,10 +1523,9 @@
 	PRINTFN(5,("actlen=%d\n", xfer->actlen));
 
 	plen1 = xfer->frlengths;
-	ptr1 = xfer->buffer;
 
-	isize = usbd_get_max_frame_size(sce->pipe_in->edesc);
 	n = sce->in_frames;
+	offset = 0;
 	while(n--)
 	{
 		if(*plen1 != 0)
@@ -1542,14 +1542,15 @@
 				*plen1 = *plen2;
 			}
 
-			bcopy(ptr1, ptr2, *plen1);
+			usbd_copy_out(xfer->frbuffers + 0, offset,
+				      ptr2, *plen1);
 
 			*plen2 = *plen1;
 
 			ugen_inc_input_index(&sce->in_queue);
 		}
 
-		ptr1 = ADD_BYTES(ptr1, isize);
+		offset += xfer->max_frame_size;
 		plen1++;
 	}
 
@@ -1562,11 +1563,10 @@
 
  tr_setup:
  tr_error:
-	isize = usbd_get_max_frame_size(sce->pipe_in->edesc);
 	for(n = 0; n < sce->in_frames; n++)
 	{
 		/* setup size for next transfer */
-		xfer->frlengths[n] = isize;
+		xfer->frlengths[n] = xfer->max_frame_size;
 	}
 	usbd_start_hardware(xfer);
 	return;
@@ -1576,24 +1576,26 @@
 ugenisoc_write_callback(struct usbd_xfer *xfer)
 {
 	struct ugen_endpoint *sce = xfer->priv_sc;
-	u_int16_t *plen1;
-	u_int16_t len2;
-
-	void *ptr1;
+	uint32_t *plen1;
 	void *ptr2;
 
-	u_int16_t isize;
+	uint32_t offset;
+	uint16_t len2;
 	u_int16_t n;
 
 	USBD_CHECK_STATUS(xfer);
 
+ tr_error:
+	if (xfer->error == USBD_CANCELLED) {
+	    return;
+	}
+
  tr_transferred:
  tr_setup:
 
 	plen1 = xfer->frlengths;
-	ptr1 = xfer->buffer;
 
-	isize = usbd_get_max_frame_size(sce->pipe_out->edesc);
+	offset = 0;
 	n = sce->out_frames;
 	while(n--)
 	{
@@ -1604,18 +1606,17 @@
 		    break;
 		}
 
-		if(len2 > isize)
-		{
-		    len2 = isize;
+		if (len2 > xfer->max_frame_size) {
+		    len2 = xfer->max_frame_size;
 		}
 
-		bcopy(ptr2, ptr1, len2);
+		usbd_copy_in(xfer->frbuffers + 0, offset, ptr2, len2);
 
 		*plen1 = len2;
 
 		ugen_inc_output_index(&sce->out_queue);
 
-		ptr1 = ADD_BYTES(ptr1, len2);
+		offset += len2;
 		plen1++;
 	}
 
@@ -1631,9 +1632,7 @@
 	}
 	selwakeuppri(&sce->selinfo, PZERO);
 
-	if(n)
-	{
- tr_error:
+	if (n > 0) {
 		usbd_start_hardware(xfer);
 	}
 	return;
@@ -1671,7 +1670,7 @@
 	ugen_destroy_devnodes(sc, 1);
 
 	/* change setting */
-	if(usbreq_set_interface(sc->sc_udev, ifaceidx, altno))
+	if(usbd_set_alt_interface_index(sc->sc_udev, ifaceidx, altno))
 	{
 		return EIO;
 	}
@@ -1706,8 +1705,7 @@
 	}
 	else
 	{
-		if(usbreq_get_config_desc(udev, index, &cdescr))
-		{
+		if (usbreq_get_config_desc(udev, NULL, &cdescr, index)) {
 			return (0);
 		}
 		len = UGETW(cdescr.wTotalLength);
@@ -1721,8 +1719,8 @@
 		{
 			return 0;
 		}
-		if(usbreq_get_config_desc_full(udev, index, cdesc, len))
-		{
+
+		if (usbreq_get_config_desc_full(udev, NULL, cdesc, len, index)) {
 			free(cdesc, M_TEMP);
 			return (0);
 		}
@@ -1749,6 +1747,7 @@
 	void *data = 0;
 	int error = 0;
 	int len;
+	uint16_t actlen;
 	u_int8_t conf;
 	u_int8_t alt;
 
@@ -1803,9 +1802,9 @@
 		goto done;
 
 	case USB_GET_FRAME_SIZE:
-		if(sce->pipe_in)
+		if(sce->xfer_in[0])
 		{
-			*(int *)addr = usbd_get_max_frame_size(sce->pipe_in->edesc);
+			*(int *)addr = sce->xfer_in[0]->max_frame_size;
 		}
 		else
 		{
@@ -1871,7 +1870,7 @@
 		break;
 #endif
 	case USB_GET_CONFIG:
-		error = usbreq_get_config(sc->sc_udev, &conf);
+		error = usbreq_get_config(sc->sc_udev, NULL, &conf);
 		if(error)
 		{
 			error = EIO;
@@ -2020,10 +2019,10 @@
 		break;
 	case USB_GET_STRING_DESC:
 #define si ((struct usb_string_desc *)addr)
-		if(usbreq_get_string_desc
-		   (sc->sc_udev, si->usd_string_index,
-		    si->usd_language_id, &si->usd_desc, NULL))
-		{
+		if (usbreq_get_string_desc
+		    (sc->sc_udev, NULL, &si->usd_desc,
+		     sizeof(si->usd_desc), si->usd_language_id,
+		     si->usd_string_index)) {
 			error = EINVAL;
 			break;
 		}
@@ -2080,11 +2079,14 @@
 			}
 		}
 
-		if(usbd_do_request_flags
-		   (sc->sc_udev, &ur->ucr_request, data,
-		    (ur->ucr_flags & USBD_SHORT_XFER_OK), &ur->ucr_actlen, 
-		    USBD_DEFAULT_TIMEOUT))
-		{
+		error = usbd_do_request_flags
+		  (sc->sc_udev, NULL, &ur->ucr_request, data,
+		   (ur->ucr_flags & USBD_SHORT_XFER_OK), &actlen,
+		   USBD_DEFAULT_TIMEOUT);
+
+		ur->ucr_actlen = actlen;
+
+		if (error) {
 			error = EIO;
 			break;
 		}
@@ -2101,8 +2103,7 @@
 		break;
 
 	case USB_GET_DEVICEINFO:
-		usbd_fill_deviceinfo(sc->sc_udev,
-		    (struct usb_device_info *)addr, 1);
+		usbd_fill_deviceinfo(sc->sc_udev, (void *)addr);
 		break;
 	default:
 		error = EINVAL;


More information about the p4-projects mailing list