[patch] patch: usb stack size

Mike Makonnen mike_makonnen at yahoo.com
Wed Dec 8 10:29:33 PST 2004


Hi,

I noticed Julian's email about kernel stack size in the usb subsystem,
so I went through some of the usb code and tried to lower stack usage
where it seemed obvious to do so. I've included my patches below. Let me
know what you think. If they are way off base or need modifications
please let me know. Should I post them on freebsd-current so they can
get more extensive testing?

I touched the following routines:
	ugen.c: USB_ATTACH, ugen_do_read, ugen_do_write
	ums.c: USB_ATTACH, ums_read
	usb_subr.c: usbd_probe_and_attach
	ukbd.c: USB_ATTACH
	ulpt.c: USB_ATTACH
	uhid.c: USB_ATTACH
	uscanner.c: USB_ATTACH
	umodem.c: USB_ATTACH
	urio.c: USB_ATTACH, urioread, uriowrite
	umass.c: USB_ATTACH

In ums_read() I removed a local variable (buf) that was apparently
redundant. You might want to take a closer look at the change.

I wasn't sure when to use M_WAITOK or M_NOWAIT with malloc, so I looked
at what the rest of the code in the file used. Let me know if you have
further guidance on this.

cheers,
mike makonnen

Index: sys/dev/usb/ugen.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/usb/ugen.c,v
retrieving revision 1.56
diff -u -r1.56 ugen.c
--- sys/dev/usb/ugen.c	2 Jan 2002 23:31:08 -0000	1.56
+++ sys/dev/usb/ugen.c	25 Jan 2002 06:36:56 -0000
@@ -192,13 +192,20 @@
 {
 	USB_ATTACH_START(ugen, sc, uaa);
 	usbd_device_handle udev;
-	char devinfo[1024];
+	char *devinfo;
 	usbd_status err;
 	int conf;
-	
+
+	devinfo = (char*)malloc(1024, M_TEMP, M_NOWAIT);
+	if (devinfo == NULL) {
+		printf("USB_ATTACH(ugen): no memory\n");
+		USB_ATTACH_ERROR_RETURN;
+	}
 	usbd_devinfo(uaa->device, 0, devinfo);
 	USB_ATTACH_SETUP;
 	printf("%s: %s\n", USBDEVNAME(sc->sc_dev), devinfo);
+	/* devinfo no longer used */
+	free(devinfo, M_TEMP);
 
 	sc->sc_udev = udev = uaa->device;
 
@@ -559,12 +566,12 @@
 {
 	struct ugen_endpoint *sce = &sc->sc_endpoints[endpt][IN];
 	u_int32_t n, tn;
-	char buf[UGEN_BBSIZE];
+	char *buf;
 	usbd_xfer_handle xfer;
 	usbd_status err;
 	int s;
 	int error = 0;
-	u_char buffer[UGEN_CHUNK];
+	u_char *buffer;
 
 	DPRINTFN(5, ("%s: ugenread: %d\n", USBDEVNAME(sc->sc_dev), endpt));
 
@@ -586,6 +593,16 @@
 		return (EIO);
 	}
 
+	buf = (char*)malloc(UGEN_BBSIZE, M_USBDEV, M_WAITOK);
+	if (buf == NULL)
+		return (ENOMEM);
+
+	buffer = (u_char*)malloc(UGEN_CHUNK, M_USBDEV, M_WAITOK);
+	if (buffer == NULL) {
+		free(buf, M_USBDEV);
+		return (ENOMEM);
+	}
+
 	switch (sce->edesc->bmAttributes & UE_XFERTYPE) {
 	case UE_INTERRUPT:
 		/* Block until activity occurred. */
@@ -593,7 +610,8 @@
 		while (sce->q.c_cc == 0) {
 			if (flag & IO_NDELAY) {
 				splx(s);
-				return (EWOULDBLOCK);
+				error = EWOULDBLOCK;
+				goto cleanup;
 			}
 			sce->state |= UGEN_ASLP;
 			DPRINTFN(5, ("ugenread: sleep on %p\n", sce));
@@ -611,8 +629,7 @@
 		/* Transfer as many chunks as possible. */
 		while (sce->q.c_cc > 0 && uio->uio_resid > 0 && !error) {
 			n = min(sce->q.c_cc, uio->uio_resid);
-			if (n > sizeof(buffer))
-				n = sizeof(buffer);
+			n =  n > UGEN_CHUNK ? UGEN_CHUNK : n;
 
 			/* Remove a small chunk from the input queue. */
 			q_to_b(&sce->q, buffer, n);
@@ -626,8 +643,10 @@
 		break;
 	case UE_BULK:
 		xfer = usbd_alloc_xfer(sc->sc_udev);
-		if (xfer == 0)
-			return (ENOMEM);
+		if (xfer == 0) {
+			error = ENOMEM;
+			goto cleanup;
+		}
 		while ((n = min(UGEN_BBSIZE, uio->uio_resid)) != 0) {
 			DPRINTFN(1, ("ugenread: start transfer %d bytes\n",n));
 			tn = n;
@@ -657,7 +676,8 @@
 		while (sce->cur == sce->fill) {
 			if (flag & IO_NDELAY) {
 				splx(s);
-				return (EWOULDBLOCK);
+				error = EWOULDBLOCK;
+				goto cleanup;
 			}
 			sce->state |= UGEN_ASLP;
 			DPRINTFN(5, ("ugenread: sleep on %p\n", sce));
@@ -692,8 +712,13 @@
 
 		
 	default:
-		return (ENXIO);
+		error = ENXIO;
+		goto cleanup;
 	}
+
+cleanup:
+	free(buf, M_USBDEV);
+	free(buffer, M_USBDEV);
 	return (error);
 }
 
@@ -719,7 +744,7 @@
 	struct ugen_endpoint *sce = &sc->sc_endpoints[endpt][OUT];
 	u_int32_t n;
 	int error = 0;
-	char buf[UGEN_BBSIZE];
+	char *buf;
 	usbd_xfer_handle xfer;
 	usbd_status err;
 
@@ -743,11 +768,17 @@
 		return (EIO);
 	}
 
+	buf = (char*)malloc(UGEN_BBSIZE, M_USBDEV, M_WAITOK);
+	if (buf == NULL)
+		return (ENOMEM);
+
 	switch (sce->edesc->bmAttributes & UE_XFERTYPE) {
 	case UE_BULK:
 		xfer = usbd_alloc_xfer(sc->sc_udev);
-		if (xfer == 0)
-			return (EIO);
+		if (xfer == 0) {
+			error = EIO;
+			goto cleanup;
+		}
 		while ((n = min(UGEN_BBSIZE, uio->uio_resid)) != 0) {
 			error = uiomove(buf, n, uio);
 			if (error)
@@ -768,8 +799,12 @@
 		usbd_free_xfer(xfer);
 		break;
 	default:
-		return (ENXIO);
+		error = ENXIO;
+		goto cleanup;
 	}
+
+cleanup:
+	free(buf, M_USBDEV);
 	return (error);
 }
 
Index: sys/dev/usb/uhid.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/usb/uhid.c,v
retrieving revision 1.41
diff -u -r1.41 uhid.c
--- sys/dev/usb/uhid.c	2 Jan 2002 18:28:45 -0000	1.41
+++ sys/dev/usb/uhid.c	25 Jan 2002 05:46:24 -0000
@@ -189,8 +189,14 @@
 	int size;
 	void *desc;
 	usbd_status err;
-	char devinfo[1024];
-	
+	char *devinfo;
+
+	devinfo = (char*)malloc(1024, M_TEMP, M_NOWAIT);
+	if (devinfo == NULL) {
+		printf("USB_ATTACH(uhid): no memory\n");
+		USB_ATTACH_ERROR_RETURN;
+	}
+
 	sc->sc_udev = uaa->device;
 	sc->sc_iface = iface;
 	id = usbd_get_interface_descriptor(iface);
@@ -198,6 +204,8 @@
 	USB_ATTACH_SETUP;
 	printf("%s: %s, iclass %d/%d\n", USBDEVNAME(sc->sc_dev),
 	       devinfo, id->bInterfaceClass, id->bInterfaceSubClass);
+	/* devinfo no longer used */
+	free(devinfo, M_TEMP);
 
 	ed = usbd_interface2endpoint_descriptor(iface, 0);
 	if (ed == NULL) {
Index: sys/dev/usb/ukbd.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/usb/ukbd.c,v
retrieving revision 1.35
diff -u -r1.35 ukbd.c
--- sys/dev/usb/ukbd.c	2 Jan 2002 18:28:45 -0000	1.35
+++ sys/dev/usb/ukbd.c	25 Jan 2002 05:20:56 -0000
@@ -145,7 +145,7 @@
 	USB_ATTACH_START(ukbd, sc, uaa);
 	usbd_interface_handle iface = uaa->iface;
 	usb_interface_descriptor_t *id;
-	char devinfo[1024];
+	char *devinfo;
 
 	keyboard_switch_t *sw;
 	keyboard_t *kbd;
@@ -156,12 +156,21 @@
 	if (sw == NULL)
 		USB_ATTACH_ERROR_RETURN;
 
+	devinfo = (char*)malloc(1024, M_TEMP, M_NOWAIT);
+	if (devinfo == NULL) {
+		printf("USB_ATTACH(ukbd): no memory\n");
+		USB_ATTACH_ERROR_RETURN;
+	}
+
 	id = usbd_get_interface_descriptor(iface);
 	usbd_devinfo(uaa->device, 0, devinfo);
 	USB_ATTACH_SETUP;
 	printf("%s: %s, iclass %d/%d\n", USBDEVNAME(sc->sc_dev),
 	       devinfo, id->bInterfaceClass, id->bInterfaceSubClass);
 
+	/* free devinfo as it is no longer used */
+	free(devinfo, M_TEMP);
+	
 	arg[0] = (void *)uaa;
 	arg[1] = (void *)ukbd_intr;
 	kbd = NULL;
Index: sys/dev/usb/ulpt.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/usb/ulpt.c,v
retrieving revision 1.39
diff -u -r1.39 ulpt.c
--- sys/dev/usb/ulpt.c	2 Jan 2002 18:28:45 -0000	1.39
+++ sys/dev/usb/ulpt.c	25 Jan 2002 05:40:09 -0000
@@ -190,11 +190,17 @@
 	usb_interface_descriptor_t *id, *iend;
 	usb_config_descriptor_t *cdesc;
 	usbd_status err;
-	char devinfo[1024];
+	char *devinfo;
 	usb_endpoint_descriptor_t *ed;
 	u_int8_t epcount;
 	int i, altno;
-	
+ 
+	devinfo = (char*)malloc(1024, M_TEMP, M_NOWAIT);
+	if (devinfo == NULL) {
+		printf("USB_ATTACH(ulpt): no memory\n");
+		USB_ATTACH_ERROR_RETURN;
+	}
+
 	DPRINTFN(10,("ulpt_attach: sc=%p\n", sc));
 	usbd_devinfo(dev, 0, devinfo);
 	USB_ATTACH_SETUP;
@@ -208,7 +214,7 @@
 	if (cdesc == NULL) {
 		printf("%s: failed to get configuration descriptor\n",
 		       USBDEVNAME(sc->sc_dev));
-		USB_ATTACH_ERROR_RETURN;
+		goto error_return;
 	}
 	iend = (usb_interface_descriptor_t *)
 		   ((char *)cdesc + UGETW(cdesc->wTotalLength));
@@ -240,7 +246,7 @@
 			printf("%s: setting alternate interface failed\n",
 			       USBDEVNAME(sc->sc_dev));
 			sc->sc_dying = 1;
-			USB_ATTACH_ERROR_RETURN;
+			goto error_return;
 		}
 	}
 
@@ -254,7 +260,7 @@
 		if (ed == NULL) {
 			printf("%s: couldn't get ep %d\n",
 			    USBDEVNAME(sc->sc_dev), i);
-			USB_ATTACH_ERROR_RETURN;
+			goto error_return;
 		}
 		if (UE_GET_DIR(ed->bEndpointAddress) == UE_DIR_IN &&
 		    UE_GET_XFERTYPE(ed->bmAttributes) == UE_BULK) {
@@ -268,7 +274,7 @@
 		printf("%s: could not find bulk endpoint\n",
 		    USBDEVNAME(sc->sc_dev));
 		sc->sc_dying = 1;
-		USB_ATTACH_ERROR_RETURN;
+		goto error_return;
 	}
 	printf("%s: using %s-directional mode\n", USBDEVNAME(sc->sc_dev),
 	       sc->sc_in >= 0 ? "bi" : "uni");
@@ -328,8 +334,12 @@
 		UID_ROOT, GID_OPERATOR, 0644, "unlpt%d", device_get_unit(self));
 #endif
 
-
+	free(devinfo, M_TEMP);
 	USB_ATTACH_SUCCESS_RETURN;
+
+error_return:
+	free(devinfo, M_TEMP);
+	USB_ATTACH_ERROR_RETURN;
 }
 
 #if defined(__NetBSD__) || defined(__OpenBSD__)
Index: sys/dev/usb/umass.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/usb/umass.c,v
retrieving revision 1.52
diff -u -r1.52 umass.c
--- sys/dev/usb/umass.c	24 Jan 2002 15:10:53 -0000	1.52
+++ sys/dev/usb/umass.c	25 Jan 2002 06:41:01 -0000
@@ -774,7 +774,7 @@
 	USB_ATTACH_START(umass, sc, uaa);
 	usb_interface_descriptor_t *id;
 	usb_endpoint_descriptor_t *ed;
-	char devinfo[1024];
+	char *devinfo;
 	int i;
 	int err;
 
@@ -783,6 +783,11 @@
 	 * call umass_detach without specifically initialising the struct.
 	 */
 
+	devinfo = (char*)malloc(1024, M_TEMP, M_NOWAIT);
+	if (devinfo == NULL) {
+		printf("USB_ATTACH(umass): no memory\n");
+		USB_ATTACH_ERROR_RETURN;
+	}
 	usbd_devinfo(uaa->device, 0, devinfo);
 	USB_ATTACH_SETUP;
 
@@ -794,6 +799,10 @@
 
 	id = usbd_get_interface_descriptor(sc->iface);
 	printf("%s: %s", USBDEVNAME(sc->sc_dev), devinfo);
+
+	/* devinfo no longer used */
+	free(devinfo, M_TEMP);
+
 #ifdef UMASS_DEBUG
 	printf(", ");
 	switch (sc->proto&PROTO_COMMAND) {
Index: sys/dev/usb/umodem.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/usb/umodem.c,v
retrieving revision 1.33
diff -u -r1.33 umodem.c
--- sys/dev/usb/umodem.c	2 Jan 2002 18:28:45 -0000	1.33
+++ sys/dev/usb/umodem.c	25 Jan 2002 05:57:56 -0000
@@ -232,12 +232,17 @@
 	usb_interface_descriptor_t *id;
 	usb_endpoint_descriptor_t *ed;
 	usb_cdc_cm_descriptor_t *cmd;
-	char devinfo[1024];
+	char *devinfo;
 	usbd_status err;
 	int data_ifaceno;
 	int i;
 	struct tty *tp;
 
+	devinfo = (char*)malloc(1024, M_TEMP, M_NOWAIT);
+	if (devinfo == NULL) {
+		printf("USB_ATTACH(umodem): no memory\n");
+		USB_ATTACH_ERROR_RETURN;
+	}
 	usbd_devinfo(uaa->device, 0, devinfo);
 	USB_ATTACH_SETUP;
 
@@ -248,6 +253,9 @@
 	printf("%s: %s, iclass %d/%d\n", USBDEVNAME(sc->sc_dev),
 	       devinfo, id->bInterfaceClass, id->bInterfaceSubClass);
 	sc->sc_ctl_iface_no = id->bInterfaceNumber;
+
+	/* devinfo no longer used */
+	free(devinfo, M_TEMP);
 
 	umodem_get_caps(dev, &sc->sc_cm_cap, &sc->sc_acm_cap);
 
Index: sys/dev/usb/ums.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/usb/ums.c,v
retrieving revision 1.47
diff -u -r1.47 ums.c
--- sys/dev/usb/ums.c	2 Jan 2002 18:28:45 -0000	1.47
+++ sys/dev/usb/ums.c	25 Jan 2002 05:15:59 -0000
@@ -199,11 +199,17 @@
 	int size;
 	void *desc;
 	usbd_status err;
-	char devinfo[1024];
+	char *devinfo;
 	u_int32_t flags;
 	int i;
 	struct hid_location loc_btn;
-	
+
+	devinfo = (char*)malloc(1024, M_TEMP, M_NOWAIT);
+	if (devinfo == NULL) {
+		printf("USB_ATTACH(ums): no memory\n");
+		USB_ATTACH_ERROR_RETURN;
+	}
+
 	sc->sc_disconnected = 1;
 	sc->sc_iface = iface;
 	id = usbd_get_interface_descriptor(iface);
@@ -211,6 +217,8 @@
 	USB_ATTACH_SETUP;
 	printf("%s: %s, iclass %d/%d\n", USBDEVNAME(sc->sc_dev),
 	       devinfo, id->bInterfaceClass, id->bInterfaceSubClass);
+	/* devinfo no longer used */
+	free(devinfo, M_TEMP);
 	ed = usbd_interface2endpoint_descriptor(iface, 0);
 	if (!ed) {
 		printf("%s: could not read endpoint descriptor\n",
@@ -616,7 +624,6 @@
 {
 	struct ums_softc *sc;
 	int s;
-	char buf[sizeof(sc->qbuf)];
 	int l = 0;
 	int error;
 
@@ -660,10 +667,7 @@
 
 	while ((sc->qcount > 0) && (uio->uio_resid > 0)) {
 		l = (sc->qcount < uio->uio_resid? sc->qcount:uio->uio_resid);
-		if (l > sizeof(buf))
-			l = sizeof(buf);
-		if (l > sizeof(sc->qbuf) - sc->qtail)		/* transfer till end of buf */
-			l = sizeof(sc->qbuf) - sc->qtail;
+		l = l > sizeof(sc->qbuf) - sc->qtail ? sizeof(sc->qbuf) - sc->qtail :
l;
 
 		splx(s);
 		uiomove(&sc->qbuf[sc->qtail], l, uio);
Index: sys/dev/usb/urio.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/usb/urio.c,v
retrieving revision 1.13
diff -u -r1.13 urio.c
--- sys/dev/usb/urio.c	2 Jan 2002 23:31:08 -0000	1.13
+++ sys/dev/usb/urio.c	25 Jan 2002 06:31:25 -0000
@@ -194,7 +194,7 @@
 USB_ATTACH(urio)
 {
 	USB_ATTACH_START(urio, sc, uaa);
-	char devinfo[1024];
+	char *devinfo;
 	usbd_device_handle udev;
 	usbd_interface_handle iface;
 	u_int8_t epcount;
@@ -205,10 +205,17 @@
 	char * ermsg = "<none>";
 	int i;
 
+	devinfo = (char*)malloc(1024, M_TEMP, M_NOWAIT);
+	if (devinfo == NULL) {
+		printf("USB_ATTACH(urio): no memory\n");
+		USB_ATTACH_ERROR_RETURN;
+	}
 	DPRINTFN(10,("urio_attach: sc=%p\n", sc));	
 	usbd_devinfo(uaa->device, 0, devinfo);
 	USB_ATTACH_SETUP;
 	printf("%s: %s\n", USBDEVNAME(sc->sc_dev), devinfo);
+	/* devinfo no longer used */
+	free(devinfo, M_TEMP);
 
 	sc->sc_udev = udev = uaa->device;
 
@@ -379,7 +386,7 @@
 #endif
 	int unit = URIOUNIT(dev);
 	usbd_status r;
-	char buf[URIO_BBSIZE];
+	char *buf;
 	u_int32_t n, tn;
 	int error = 0;
 
@@ -397,6 +404,11 @@
 #endif
 	if (reqh == 0)
 		return ENOMEM;
+
+	buf = (char*)malloc(URIO_BBSIZE, M_USBDEV, M_WAITOK);
+	if (buf == NULL)
+		return (ENOMEM);
+
 	while ((n = min(URIO_BBSIZE, uio->uio_resid)) != 0) {
 		DPRINTFN(1, ("urioread: start transfer %d bytes\n", n));
 		tn = n;
@@ -436,6 +448,7 @@
 	usbd_free_request(reqh);
 #endif
 
+	free(buf, M_USBDEV);
 	return error;
 }
 
@@ -453,7 +466,7 @@
 #endif
 	int unit = URIOUNIT(dev);
 	usbd_status r;
-	char buf[URIO_BBSIZE];
+	char *buf;
 	u_int32_t n;
 	int error = 0;
 
@@ -471,6 +484,11 @@
 #endif
 	if (reqh == 0)
 		return EIO;
+
+	buf = (char*)malloc(URIO_BBSIZE, M_USBDEV, M_WAITOK);
+	if (buf == NULL)
+		return (ENOMEM);
+
 	while ((n = min(URIO_BBSIZE, uio->uio_resid)) != 0) {
 		error = uiomove(buf, n, uio);
 		if (error)
@@ -505,6 +523,7 @@
 	usbd_free_request(reqh);
 #endif
 
+	free(buf, M_USBDEV);
 	return error;
 }
 
Index: sys/dev/usb/usb_subr.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/usb/usb_subr.c,v
retrieving revision 1.31
diff -u -r1.31 usb_subr.c
--- sys/dev/usb/usb_subr.c	2 Jan 2002 20:16:53 -0000	1.31
+++ sys/dev/usb/usb_subr.c	25 Jan 2002 05:09:28 -0000
@@ -739,12 +739,13 @@
 usbd_probe_and_attach(device_ptr_t parent, usbd_device_handle dev,
 		      int port, int addr)
 {
+#define USBD_MAX_IFACES		256	/* 256 is the absolute max */
 	struct usb_attach_arg uaa;
 	usb_device_descriptor_t *dd = &dev->ddesc;
 	int found, i, confi, nifaces;
 	usbd_status err;
 	device_ptr_t dv;
-	usbd_interface_handle ifaces[256]; /* 256 is the absolute max */
+	usbd_interface_handle *ifaces;
 
 #if defined(__FreeBSD__)
 	/* 
@@ -785,6 +786,10 @@
 		return (USBD_NORMAL_COMPLETION);
 	}
 
+	ifaces = (usbd_interface_handle*)malloc(USBD_MAX_IFACES, M_USB,
M_NOWAIT);
+	if (ifaces == NULL)
+		return (USBD_NOMEM);
+
 	DPRINTF(("usbd_probe_and_attach: no device specific driver found\n"));
 
 	DPRINTF(("usbd_probe_and_attach: looping over %d configurations\n",
@@ -807,6 +812,7 @@
 			device_delete_child(parent, bdev);
 #endif
 
+			free(ifaces, M_USB);
  			return (err);
 		}
 		nifaces = dev->cdesc->bNumInterface;
@@ -820,6 +826,7 @@
 #if defined(__FreeBSD__)
 			device_delete_child(parent, bdev);
 #endif
+			free(ifaces, M_USB);
 			return (USBD_NOMEM);
 		}
 
@@ -854,11 +861,13 @@
 			/* remove the last created child again; it is unused */
 			device_delete_child(parent, bdev);
 #endif
+			free(ifaces, M_USB);
 			return (USBD_NORMAL_COMPLETION);
 		}
 		free(dev->subdevs, M_USB);
 		dev->subdevs = 0;
 	}
+	free(ifaces, M_USB);
 	/* No interfaces were attached in any of the configurations. */
 
 	if (dd->bNumConfigurations > 1) /* don't change if only 1 config */
Index: sys/dev/usb/uscanner.c
===================================================================
RCS file: /home/ncvs/src/sys/dev/usb/uscanner.c,v
retrieving revision 1.19
diff -u -r1.19 uscanner.c
--- sys/dev/usb/uscanner.c	2 Jan 2002 16:33:53 -0000	1.19
+++ sys/dev/usb/uscanner.c	25 Jan 2002 05:53:05 -0000
@@ -258,13 +258,20 @@
 	USB_ATTACH_START(uscanner, sc, uaa);
 	usb_interface_descriptor_t *id = 0;
 	usb_endpoint_descriptor_t *ed, *ed_bulkin = NULL, *ed_bulkout = NULL;
-	char devinfo[1024];
+	char *devinfo;
 	int i;
 	usbd_status err;
 
+	devinfo = (char*)malloc(1024, M_TEMP, M_NOWAIT);
+	if (devinfo == NULL) {
+		printf("USB_ATTACH(uscanner): no memory\n");
+		USB_ATTACH_ERROR_RETURN;
+	}
 	usbd_devinfo(uaa->device, 0, devinfo);
 	USB_ATTACH_SETUP;
 	printf("%s: %s\n", USBDEVNAME(sc->sc_dev), devinfo);
+	/* devinfo no longer used */
+	free(devinfo, M_TEMP);
 
 	sc->sc_udev = uaa->device;
 


More information about the freebsd-bugs mailing list