This is the initial version of USB port+hub+hostcontroller drivers from a special version of Linux USB Stack. More info will be placed at ROS-Wiki.
Added: trunk/reactos/drivers/usb/cromwell/
Added: trunk/reactos/drivers/usb/cromwell/Makefile
Added: trunk/reactos/drivers/usb/cromwell/core/
Added: trunk/reactos/drivers/usb/cromwell/core/buffer_simple.c
Added: trunk/reactos/drivers/usb/cromwell/core/config.c
Added: trunk/reactos/drivers/usb/cromwell/core/hcd-pci.c
Added: trunk/reactos/drivers/usb/cromwell/core/hcd.c
Added: trunk/reactos/drivers/usb/cromwell/core/hcd.h
Added: trunk/reactos/drivers/usb/cromwell/core/hub.c
Added: trunk/reactos/drivers/usb/cromwell/core/hub.h
Added: trunk/reactos/drivers/usb/cromwell/core/makefile
Added: trunk/reactos/drivers/usb/cromwell/core/makefile.crom
Added: trunk/reactos/drivers/usb/cromwell/core/message.c
Added: trunk/reactos/drivers/usb/cromwell/core/urb.c
Added: trunk/reactos/drivers/usb/cromwell/core/usb-debug.c
Added: trunk/reactos/drivers/usb/cromwell/core/usb.c
Added: trunk/reactos/drivers/usb/cromwell/core/usb.h
Added: trunk/reactos/drivers/usb/cromwell/core/usbcore.a
Added: trunk/reactos/drivers/usb/cromwell/core/usbcore.c
Added: trunk/reactos/drivers/usb/cromwell/core/usbcore.coff
Added: trunk/reactos/drivers/usb/cromwell/core/usbcore.def
Added: trunk/reactos/drivers/usb/cromwell/core/usbcore.map
Added: trunk/reactos/drivers/usb/cromwell/core/usbcore.nostrip.sys
Added: trunk/reactos/drivers/usb/cromwell/core/usbcore.rc
Added: trunk/reactos/drivers/usb/cromwell/core/usbcore.sym
Added: trunk/reactos/drivers/usb/cromwell/core/usbcore.sys
Added: trunk/reactos/drivers/usb/cromwell/host/
Added: trunk/reactos/drivers/usb/cromwell/host/makefile
Added: trunk/reactos/drivers/usb/cromwell/host/makefile.crom
Added: trunk/reactos/drivers/usb/cromwell/host/ohci-dbg.c
Added: trunk/reactos/drivers/usb/cromwell/host/ohci-hcd.c
Added: trunk/reactos/drivers/usb/cromwell/host/ohci-hub.c
Added: trunk/reactos/drivers/usb/cromwell/host/ohci-mem.c
Added: trunk/reactos/drivers/usb/cromwell/host/ohci-pci.c
Added: trunk/reactos/drivers/usb/cromwell/host/ohci-q.c
Added: trunk/reactos/drivers/usb/cromwell/host/ohci.a
Added: trunk/reactos/drivers/usb/cromwell/host/ohci.coff
Added: trunk/reactos/drivers/usb/cromwell/host/ohci.def
Added: trunk/reactos/drivers/usb/cromwell/host/ohci.h
Added: trunk/reactos/drivers/usb/cromwell/host/ohci.map
Added: trunk/reactos/drivers/usb/cromwell/host/ohci.nostrip.sys
Added: trunk/reactos/drivers/usb/cromwell/host/ohci.rc
Added: trunk/reactos/drivers/usb/cromwell/host/ohci.sym
Added: trunk/reactos/drivers/usb/cromwell/host/ohci.sys
Added: trunk/reactos/drivers/usb/cromwell/host/ohci_config.h
Added: trunk/reactos/drivers/usb/cromwell/host/ohci_main.c
Added: trunk/reactos/drivers/usb/cromwell/linux/
Added: trunk/reactos/drivers/usb/cromwell/linux/asm/
Added: trunk/reactos/drivers/usb/cromwell/linux/asm/bitops.h
Added: trunk/reactos/drivers/usb/cromwell/linux/bitops.h
Added: trunk/reactos/drivers/usb/cromwell/linux/boot.h
Added: trunk/reactos/drivers/usb/cromwell/linux/consts.h
Added: trunk/reactos/drivers/usb/cromwell/linux/cromwell_types.h
Added: trunk/reactos/drivers/usb/cromwell/linux/errno.h
Added: trunk/reactos/drivers/usb/cromwell/linux/linux_wrapper.h
Added: trunk/reactos/drivers/usb/cromwell/linux/list.h
Added: trunk/reactos/drivers/usb/cromwell/linux/pci_ids.h
Added: trunk/reactos/drivers/usb/cromwell/linux/usb.h
Added: trunk/reactos/drivers/usb/cromwell/linux/usb_ch9.h
Added: trunk/reactos/drivers/usb/cromwell/sys/
Added: trunk/reactos/drivers/usb/cromwell/sys/BootUSB.c
Added: trunk/reactos/drivers/usb/cromwell/sys/Makefile
Added: trunk/reactos/drivers/usb/cromwell/sys/linuxwrapper.c
Added: trunk/reactos/drivers/usb/cromwell/sys/risefall.c
Added: trunk/reactos/drivers/usb/cromwell/sys/ros_wrapper.c
Added: trunk/reactos/drivers/usb/cromwell/sys/usbkey.c
Added: trunk/reactos/drivers/usb/cromwell/sys/usbwrapper.c
Added: trunk/reactos/drivers/usb/cromwell/sys/xpad.c
Added: trunk/reactos/drivers/usb/cromwell/sys/xremote.c
Added: trunk/reactos/drivers/usb/cromwell/usb_wrapper.h

Added: trunk/reactos/drivers/usb/cromwell/Makefile
--- trunk/reactos/drivers/usb/cromwell/Makefile	2005-01-26 22:05:12 UTC (rev 13323)
+++ trunk/reactos/drivers/usb/cromwell/Makefile	2005-01-26 22:34:39 UTC (rev 13324)
@@ -0,0 +1,50 @@
+#
+# ReactOS USB-Cromwell Drivers
+#
+
+PATH_TO_TOP = ../../..
+
+include $(PATH_TO_TOP)/rules.mak
+
+DRIVERS = core host
+
+all: $(DRIVERS)
+
+depends: 
+
+implib: $(DRIVERS:%=%_implib)
+
+clean: 	$(DRIVERS:%=%_clean)
+
+install: $(DRIVERS:%=%_install)
+
+bootcd: $(DRIVERS:%=%_bootcd)
+
+.PHONY: all depends implib clean install bootcd
+
+
+#
+# USB DRIVERS
+#
+$(DRIVERS): %:
+	$(MAKE) -C $*
+
+$(DRIVERS:%=%_implib): %_implib:
+	$(MAKE) -C $* implib
+
+$(DRIVERS:%=%_clean): %_clean:
+	$(MAKE) -C $* clean
+
+$(DRIVERS:%=%_install): %_install:
+	$(MAKE) -C $* install
+
+$(DRIVERS:%=%_bootcd): %_bootcd:
+	$(MAKE) -C $* bootcd
+
+.PHONY: $(DRIVERS) $(DRIVERS:%=%_implib) $(DRIVERS:%=%_clean) $(DRIVERS:%=%_install) $(DRIVERS:%=%_bootcd)
+
+
+etags:
+	find . -name "*.[ch]" -print | etags --language=c -
+
+# EOF

Added: trunk/reactos/drivers/usb/cromwell/core/buffer_simple.c
--- trunk/reactos/drivers/usb/cromwell/core/buffer_simple.c	2005-01-26 22:05:12 UTC (rev 13323)
+++ trunk/reactos/drivers/usb/cromwell/core/buffer_simple.c	2005-01-26 22:34:39 UTC (rev 13324)
@@ -0,0 +1,42 @@
+/* 
+ * buffer_simple.c -- replacement for usb/core/buffer.c
+ *
+ * (c) Georg Acher, georg@acher.org
+ *
+ */
+
+#include "../usb_wrapper.h"
+#define __KERNEL__
+#define CONFIG_PCI
+#include "hcd.h"
+
+/*------------------------------------------------------------------------*/ 
+int hcd_buffer_create (struct usb_hcd *hcd)
+{
+	return 0;
+}
+/*------------------------------------------------------------------------*/ 
+void hcd_buffer_destroy (struct usb_hcd *hcd)
+{
+}
+/*------------------------------------------------------------------------*/ 
+void *hcd_buffer_alloc (
+        struct usb_bus          *bus,
+        size_t                  size,
+        int                     mem_flags,
+        dma_addr_t              *dma
+)
+{
+	return kmalloc(size,0);
+}
+/*------------------------------------------------------------------------*/ 
+void hcd_buffer_free (
+        struct usb_bus          *bus,
+        size_t                  size,
+        void                    *addr,
+        dma_addr_t              dma
+)
+{
+	kfree(addr);
+}
+

Added: trunk/reactos/drivers/usb/cromwell/core/config.c
--- trunk/reactos/drivers/usb/cromwell/core/config.c	2005-01-26 22:05:12 UTC (rev 13323)
+++ trunk/reactos/drivers/usb/cromwell/core/config.c	2005-01-26 22:34:39 UTC (rev 13324)
@@ -0,0 +1,508 @@
+#if 0
+#include <linux/usb.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <asm/byteorder.h>
+#else
+#include "../usb_wrapper.h"
+#endif
+
+#define USB_MAXALTSETTING		128	/* Hard limit */
+#define USB_MAXENDPOINTS		30	/* Hard limit */
+
+/* these maximums are arbitrary */
+#define USB_MAXCONFIG			8
+#define USB_ALTSETTINGALLOC		4
+#define USB_MAXINTERFACES		32
+
+static int usb_parse_endpoint(struct usb_host_endpoint *endpoint, unsigned char *buffer, int size)
+{
+	struct usb_descriptor_header *header;
+	unsigned char *begin;
+	int parsed = 0, len, numskipped;
+
+	header = (struct usb_descriptor_header *)buffer;
+
+	/* Everything should be fine being passed into here, but we sanity */
+	/*  check JIC */
+	if (header->bLength > size) {
+		err("ran out of descriptors parsing");
+		return -1;
+	}
+		
+	if (header->bDescriptorType != USB_DT_ENDPOINT) {
+		warn("unexpected descriptor 0x%X, expecting endpoint, 0x%X",
+			header->bDescriptorType, USB_DT_ENDPOINT);
+		return parsed;
+	}
+
+	if (header->bLength == USB_DT_ENDPOINT_AUDIO_SIZE)
+		memcpy(&endpoint->desc, buffer, USB_DT_ENDPOINT_AUDIO_SIZE);
+	else
+		memcpy(&endpoint->desc, buffer, USB_DT_ENDPOINT_SIZE);
+	
+	le16_to_cpus(&endpoint->desc.wMaxPacketSize);
+
+	buffer += header->bLength;
+	size -= header->bLength;
+	parsed += header->bLength;
+
+	/* Skip over the rest of the Class Specific or Vendor Specific */
+	/*  descriptors */
+	begin = buffer;
+	numskipped = 0;
+	while (size >= sizeof(struct usb_descriptor_header)) {
+		header = (struct usb_descriptor_header *)buffer;
+
+		if (header->bLength < 2) {
+			err("invalid descriptor length of %d", header->bLength);
+			return -1;
+		}
+
+		/* If we find another "proper" descriptor then we're done  */
+		if ((header->bDescriptorType == USB_DT_ENDPOINT) ||
+		    (header->bDescriptorType == USB_DT_INTERFACE) ||
+		    (header->bDescriptorType == USB_DT_CONFIG) ||
+		    (header->bDescriptorType == USB_DT_DEVICE))
+			break;
+
+		dbg("skipping descriptor 0x%X",
+			header->bDescriptorType);
+		numskipped++;
+
+		buffer += header->bLength;
+		size -= header->bLength;
+		parsed += header->bLength;
+	}
+	if (numskipped)
+		dbg("skipped %d class/vendor specific endpoint descriptors", numskipped);
+
+	/* Copy any unknown descriptors into a storage area for drivers */
+	/*  to later parse */
+	len = (int)(buffer - begin);
+	if (!len) {
+		endpoint->extra = NULL;
+		endpoint->extralen = 0;
+		return parsed;
+	}
+
+	endpoint->extra = kmalloc(len, GFP_KERNEL);
+
+	if (!endpoint->extra) {
+		err("couldn't allocate memory for endpoint extra descriptors");
+		endpoint->extralen = 0;
+		return parsed;
+	}
+
+	memcpy(endpoint->extra, begin, len);
+	endpoint->extralen = len;
+
+	return parsed;
+}
+
+static int usb_parse_interface(struct usb_interface *interface, unsigned char *buffer, int size)
+{
+	int i, len, numskipped, retval, parsed = 0;
+	struct usb_descriptor_header *header;
+	struct usb_host_interface *ifp;
+	unsigned char *begin;
+
+	interface->act_altsetting = 0;
+	interface->num_altsetting = 0;
+	interface->max_altsetting = USB_ALTSETTINGALLOC;
+	device_initialize(&interface->dev);
+
+	interface->altsetting = kmalloc(sizeof(*interface->altsetting) * interface->max_altsetting,
+					GFP_KERNEL);
+	
+	if (!interface->altsetting) {
+		err("couldn't kmalloc interface->altsetting");
+		return -1;
+	}
+
+	while (size > 0) {
+		struct usb_interface_descriptor	*d;
+	
+		if (interface->num_altsetting >= interface->max_altsetting) {
+			struct usb_host_interface *ptr;
+			int oldmas;
+
+			oldmas = interface->max_altsetting;
+			interface->max_altsetting += USB_ALTSETTINGALLOC;
+			if (interface->max_altsetting > USB_MAXALTSETTING) {
+				warn("too many alternate settings (incr %d max %d)\n",
+					USB_ALTSETTINGALLOC, USB_MAXALTSETTING);
+				return -1;
+			}
+
+			ptr = kmalloc(sizeof(*ptr) * interface->max_altsetting, GFP_KERNEL);
+			if (ptr == NULL) {
+				err("couldn't kmalloc interface->altsetting");
+				return -1;
+			}
+			memcpy(ptr, interface->altsetting, sizeof(*interface->altsetting) * oldmas);
+			kfree(interface->altsetting);
+			interface->altsetting = ptr;
+		}
+
+		ifp = interface->altsetting + interface->num_altsetting;
+		ifp->endpoint = NULL;
+		ifp->extra = NULL;
+		ifp->extralen = 0;
+		interface->num_altsetting++;
+
+		memcpy(ifp, buffer, USB_DT_INTERFACE_SIZE);
+
+		/* Skip over the interface */
+		buffer += ifp->desc.bLength;
+		parsed += ifp->desc.bLength;
+		size -= ifp->desc.bLength;
+
+		begin = buffer;
+		numskipped = 0;
+
+		/* Skip over any interface, class or vendor descriptors */
+		while (size >= sizeof(struct usb_descriptor_header)) {
+			header = (struct usb_descriptor_header *)buffer;
+
+			if (header->bLength < 2) {
+				err("invalid descriptor length of %d", header->bLength);
+				return -1;
+			}
+
+			/* If we find another "proper" descriptor then we're done  */
+			if ((header->bDescriptorType == USB_DT_INTERFACE) ||
+			    (header->bDescriptorType == USB_DT_ENDPOINT) ||
+			    (header->bDescriptorType == USB_DT_CONFIG) ||
+			    (header->bDescriptorType == USB_DT_DEVICE))
+				break;
+
+			numskipped++;
+
+			buffer += header->bLength;
+			parsed += header->bLength;
+			size -= header->bLength;
+		}
+
+		if (numskipped)
+			dbg("skipped %d class/vendor specific interface descriptors", numskipped);
+
+		/* Copy any unknown descriptors into a storage area for */
+		/*  drivers to later parse */
+		len = (int)(buffer - begin);
+		if (len) {
+			ifp->extra = kmalloc(len, GFP_KERNEL);
+
+			if (!ifp->extra) {
+				err("couldn't allocate memory for interface extra descriptors");
+				ifp->extralen = 0;
+				return -1;
+			}
+			memcpy(ifp->extra, begin, len);
+			ifp->extralen = len;
+		}
+
+		/* Did we hit an unexpected descriptor? */
+		header = (struct usb_descriptor_header *)buffer;
+		if ((size >= sizeof(struct usb_descriptor_header)) &&
+		    ((header->bDescriptorType == USB_DT_CONFIG) ||
+		     (header->bDescriptorType == USB_DT_DEVICE)))
+			return parsed;
+
+		if (ifp->desc.bNumEndpoints > USB_MAXENDPOINTS) {
+			warn("too many endpoints");
+			return -1;
+		}
+
+		ifp->endpoint = (struct usb_host_endpoint *)
+			kmalloc(ifp->desc.bNumEndpoints *
+			sizeof(struct usb_host_endpoint), GFP_KERNEL);
+		if (!ifp->endpoint) {
+			err("out of memory");
+			return -1;	
+		}
+
+		memset(ifp->endpoint, 0, ifp->desc.bNumEndpoints *
+			sizeof(struct usb_host_endpoint));
+	
+		for (i = 0; i < ifp->desc.bNumEndpoints; i++) {
+			header = (struct usb_descriptor_header *)buffer;
+
+			if (header->bLength > size) {
+				err("ran out of descriptors parsing");
+				return -1;
+			}
+		
+			retval = usb_parse_endpoint(ifp->endpoint + i, buffer, size);
+			if (retval < 0)
+				return retval;
+
+			buffer += retval;
+			parsed += retval;
+			size -= retval;
+		}
+
+		/* We check to see if it's an alternate to this one */
+		d = (struct usb_interface_descriptor *)buffer;
+		if (size < USB_DT_INTERFACE_SIZE
+				|| d->bDescriptorType != USB_DT_INTERFACE
+				|| !d->bAlternateSetting)
+			return parsed;
+	}
+
+	return parsed;
+}
+
+int usb_parse_configuration(struct usb_host_config *config, char *buffer)
+{
+	int i, retval, size;
+	struct usb_descriptor_header *header;
+
+	memcpy(&config->desc, buffer, USB_DT_CONFIG_SIZE);
+	le16_to_cpus(&config->desc.wTotalLength);
+	size = config->desc.wTotalLength;
+
+	if (config->desc.bNumInterfaces > USB_MAXINTERFACES) {
+		warn("too many interfaces");
+		return -1;
+	}
+
+	config->interface = (struct usb_interface *)
+		kmalloc(config->desc.bNumInterfaces *
+		sizeof(struct usb_interface), GFP_KERNEL);
+	dbg("kmalloc IF %p, numif %i", config->interface, config->desc.bNumInterfaces);
+	if (!config->interface) {
+		err("out of memory");
+		return -1;	
+	}
+
+	memset(config->interface, 0,
+	       config->desc.bNumInterfaces * sizeof(struct usb_interface));
+
+	buffer += config->desc.bLength;
+	size -= config->desc.bLength;
+	
+	config->extra = NULL;
+	config->extralen = 0;
+
+	for (i = 0; i < config->desc.bNumInterfaces; i++) {
+		int numskipped, len;
+		char *begin;
+
+		/* Skip over the rest of the Class Specific or Vendor */
+		/*  Specific descriptors */
+		begin = buffer;
+		numskipped = 0;
+		while (size >= sizeof(struct usb_descriptor_header)) {
+			header = (struct usb_descriptor_header *)buffer;
+
+			if ((header->bLength > size) || (header->bLength < 2)) {
+				err("invalid descriptor length of %d", header->bLength);
+				return -1;
+			}
+
+			/* If we find another "proper" descriptor then we're done  */
+			if ((header->bDescriptorType == USB_DT_ENDPOINT) ||
+			    (header->bDescriptorType == USB_DT_INTERFACE) ||
+			    (header->bDescriptorType == USB_DT_CONFIG) ||
+			    (header->bDescriptorType == USB_DT_DEVICE))
+				break;
+
+			dbg("skipping descriptor 0x%X", header->bDescriptorType);
+			numskipped++;
+
+			buffer += header->bLength;
+			size -= header->bLength;
+		}
+		if (numskipped)
+			dbg("skipped %d class/vendor specific endpoint descriptors", numskipped);
+
+		/* Copy any unknown descriptors into a storage area for */
+		/*  drivers to later parse */
+		len = (int)(buffer - begin);
+		if (len) {
+			if (config->extralen) {
+				warn("extra config descriptor");
+			} else {
+				config->extra = kmalloc(len, GFP_KERNEL);
+				if (!config->extra) {
+					err("couldn't allocate memory for config extra descriptors");
+					config->extralen = 0;
+					return -1;
+				}
+
+				memcpy(config->extra, begin, len);
+				config->extralen = len;
+			}
+		}
+
+		retval = usb_parse_interface(config->interface + i, buffer, size);
+		if (retval < 0)
+			return retval;
+
+		buffer += retval;
+		size -= retval;
+	}
+
+	return size;
+}
+
+// hub-only!! ... and only exported for reset/reinit path.
+// otherwise used internally on disconnect/destroy path
+void usb_destroy_configuration(struct usb_device *dev)
+{
+	int c, i, j, k;
+	
+	if (!dev->config)
+		return;
+
+	if (dev->rawdescriptors) {
+		for (i = 0; i < dev->descriptor.bNumConfigurations; i++)
+			kfree(dev->rawdescriptors[i]);
+
+		kfree(dev->rawdescriptors);
+	}
+
+	for (c = 0; c < dev->descriptor.bNumConfigurations; c++) {
+		struct usb_host_config *cf = &dev->config[c];
+
+		if (!cf->interface)
+			break;
+
+		for (i = 0; i < cf->desc.bNumInterfaces; i++) {
+			struct usb_interface *ifp =
+				&cf->interface[i];
+				
+			if (!ifp->altsetting)
+				break;
+
+			for (j = 0; j < ifp->num_altsetting; j++) {
+				struct usb_host_interface *as =
+					&ifp->altsetting[j];
+					
+				if(as->extra) {
+					kfree(as->extra);
+				}
+
+				if (!as->endpoint)
+					break;
+					
+				for(k = 0; k < as->desc.bNumEndpoints; k++) {
+					if(as->endpoint[k].extra) {
+						kfree(as->endpoint[k].extra);
+					}
+				}	
+				kfree(as->endpoint);
+			}
+
+			kfree(ifp->altsetting);
+		}
+		kfree(cf->interface);
+	}
+	kfree(dev->config);
+}
+
+
+// hub-only!! ... and only in reset path, or usb_new_device()
+// (used by real hubs and virtual root hubs)
+int usb_get_configuration(struct usb_device *dev)
+{
+	int result;
+	unsigned int cfgno, length;
+	unsigned char *buffer;
+	unsigned char *bigbuffer;
+ 	struct usb_config_descriptor *desc;
+
+	if (dev->descriptor.bNumConfigurations > USB_MAXCONFIG) {
+		warn("too many configurations");
+		return -EINVAL;
+	}
+
+	if (dev->descriptor.bNumConfigurations < 1) {
+		warn("not enough configurations");
+		return -EINVAL;
+	}
+
+	dev->config = (struct usb_host_config *)
+		kmalloc(dev->descriptor.bNumConfigurations *
+		sizeof(struct usb_host_config), GFP_KERNEL);
+	if (!dev->config) {
+		err("out of memory");
+		return -ENOMEM;	
+	}
+	memset(dev->config, 0, dev->descriptor.bNumConfigurations *
+		sizeof(struct usb_host_config));
+
+	dev->rawdescriptors = (char **)kmalloc(sizeof(char *) *
+		dev->descriptor.bNumConfigurations, GFP_KERNEL);
+	if (!dev->rawdescriptors) {
+		err("out of memory");
+		return -ENOMEM;
+	}
+
+	buffer = kmalloc(8, GFP_KERNEL);
+	if (!buffer) {
+		err("unable to allocate memory for configuration descriptors");
+		return -ENOMEM;
+	}
+	desc = (struct usb_config_descriptor *)buffer;
+
+	for (cfgno = 0; cfgno < dev->descriptor.bNumConfigurations; cfgno++) {
+		/* We grab the first 8 bytes so we know how long the whole */
+		/*  configuration is */
+		result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, buffer, 8);
+		if (result < 8) {
+			if (result < 0)
+				err("unable to get descriptor");
+			else {
+				err("config descriptor too short (expected %i, got %i)", 8, result);
+				result = -EINVAL;
+			}
+			goto err;
+		}
+
+  	  	/* Get the full buffer */
+		length = le16_to_cpu(desc->wTotalLength);
+
+		bigbuffer = kmalloc(length, GFP_KERNEL);
+		if (!bigbuffer) {
+			err("unable to allocate memory for configuration descriptors");
+			result = -ENOMEM;
+			goto err;
+		}
+
+		/* Now that we know the length, get the whole thing */
+		result = usb_get_descriptor(dev, USB_DT_CONFIG, cfgno, bigbuffer, length);
+		if (result < 0) {
+			err("couldn't get all of config descriptors");
+			kfree(bigbuffer);
+			goto err;
+		}	
+	
+		if (result < length) {
+			err("config descriptor too short (expected %i, got %i)", length, result);
+			result = -EINVAL;
+			kfree(bigbuffer);
+			goto err;
+		}
+
+		dev->rawdescriptors[cfgno] = bigbuffer;
+
+		result = usb_parse_configuration(&dev->config[cfgno], bigbuffer);
+		if (result > 0)
+			dbg("descriptor data left");
+		else if (result < 0) {
+			result = -EINVAL;
+			goto err;
+		}
+	}
+
+	kfree(buffer);
+	return 0;
+err:
+	kfree(buffer);
+	dev->descriptor.bNumConfigurations = cfgno;
+	return result;
+}
+

Added: trunk/reactos/drivers/usb/cromwell/core/hcd-pci.c
--- trunk/reactos/drivers/usb/cromwell/core/hcd-pci.c	2005-01-26 22:05:12 UTC (rev 13323)
+++ trunk/reactos/drivers/usb/cromwell/core/hcd-pci.c	2005-01-26 22:34:39 UTC (rev 13324)
@@ -0,0 +1,365 @@
+/*
+ * (C) Copyright David Brownell 2000-2002
+ * 
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#if 0
+#include <linux/config.h>
+
+#ifdef CONFIG_USB_DEBUG
+	#define DEBUG
+#else
+	#undef DEBUG
+#endif
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/pci.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <linux/usb.h>
+#include "hcd.h"
+#else
+#define DEBUG
+#include "../usb_wrapper.h"
+#include "hcd.h"
+#endif
+
+
+/* PCI-based HCs are normal, but custom bus glue should be ok */
+
+
+/*-------------------------------------------------------------------------*/
+
+/* configure so an HC device and id are always provided */
+/* always called with process context; sleeping is OK */
+
+/**
+ * usb_hcd_pci_probe - initialize PCI-based HCDs
+ * @dev: USB Host Controller being probed
+ * @id: pci hotplug id connecting controller to HCD framework
+ * Context: !in_interrupt()
+ *
+ * Allocates basic PCI resources for this USB host controller, and
+ * then invokes the start() method for the HCD associated with it
+ * through the hotplug entry's driver_data.
+ *
+ * Store this function in the HCD's struct pci_driver as probe().
+ */
+int STDCALL usb_hcd_pci_probe (struct pci_dev *dev, const struct pci_device_id *id)
+{
+	struct hc_driver	*driver;
+	unsigned long		resource, len;
+	void			*base;
+	struct usb_hcd		*hcd;
+	int			retval, region;
+	char			buf [8];
+	//char			*bufp = buf;
+
+	if (usb_disabled())
+		return -ENODEV;
+
+	if (!id || !(driver = (struct hc_driver *) id->driver_data))
+		return -EINVAL;
+
+	if (pci_enable_device (dev) < 0)
+		return -ENODEV;
+
+        if (!dev->irq) {
+        	err ("Found HC with no IRQ.  Check BIOS/PCI %s setup!",
+			dev->slot_name);
+   	        return -ENODEV;
+        }
+
+	if (driver->flags & HCD_MEMORY) {	// EHCI, OHCI
+		region = 0;
+		resource = pci_resource_start (dev, 0);
+		len = pci_resource_len (dev, 0);
+		if (!request_mem_region (resource, len, driver->description)) {
+			dbg ("controller already in use");
+			return -EBUSY;
+		}
+		base = ioremap_nocache (resource, len);
+		if (base == NULL) {
+			dbg ("error mapping memory");
+			retval = -EFAULT;
+clean_1:
+			release_mem_region (resource, len);
+			err ("init %s fail, %d", dev->slot_name, retval);
+			return retval;
+		}
+
+	} else { 				// UHCI
+		resource = len = 0;
+		for (region = 0; region < PCI_ROM_RESOURCE; region++) {
+			if (!(pci_resource_flags (dev, region) & IORESOURCE_IO))
+				continue;
+
+			resource = pci_resource_start (dev, region);
+			len = pci_resource_len (dev, region);
+			if (request_region (resource, len,
+					driver->description))
+				break;
+		}
+		if (region == PCI_ROM_RESOURCE) {
+			dbg ("no i/o regions available");
+			return -EBUSY;
+		}
+		base = (void *) resource;
+	}
+
+	// driver->start(), later on, will transfer device from
+	// control by SMM/BIOS to control by Linux (if needed)
+
+	pci_set_master (dev);
+
+	hcd = driver->hcd_alloc ();
+	if (hcd == NULL){
+		dbg ("hcd alloc fail");
+		retval = -ENOMEM;
+clean_2:
+		if (driver->flags & HCD_MEMORY) {
+			iounmap (base);
+			goto clean_1;
+		} else {
+			release_region (resource, len);
+			err ("init %s fail, %d", dev->slot_name, retval);
+			return retval;
+		}
+	}
+	pci_set_drvdata (dev, hcd);
+	hcd->driver = driver;
+	hcd->description = driver->description;
+	hcd->pdev = dev;
+	hcd->self.bus_name = dev->slot_name;
+	hcd->product_desc = dev->dev.name;
+	hcd->self.controller = &dev->dev;
+	hcd->controller = hcd->self.controller;
+
+	if ((retval = hcd_buffer_create (hcd)) != 0) {
+clean_3:
+		driver->hcd_free (hcd);
+		goto clean_2;
+	}
+
+	dev_info (hcd->controller, "%s\n", hcd->product_desc);
+
+#ifndef __sparc__
+	sprintf (buf, "%d", dev->irq);
+#else
+	bufp = __irq_itoa(dev->irq);
+#endif
+	if (request_irq (dev->irq, usb_hcd_irq, SA_SHIRQ, hcd->description, hcd)
+			!= 0) {
+		dev_err (hcd->controller,
+				"request interrupt %s failed\n", bufp);
+		retval = -EBUSY;
+		goto clean_3;
+	}
+	hcd->irq = dev->irq;
+
+	hcd->regs = base;
+	hcd->region = region;
+	dev_info (hcd->controller, "irq %s, %s %p\n", bufp,
+		(driver->flags & HCD_MEMORY) ? "pci mem" : "io base",
+		base);
+
+	usb_bus_init (&hcd->self);
+	hcd->self.op = &usb_hcd_operations;
+	hcd->self.hcpriv = (void *) hcd;
+
+	INIT_LIST_HEAD (&hcd->dev_list);
+
+	usb_register_bus (&hcd->self);
+
+	if ((retval = driver->start (hcd)) < 0)
+		usb_hcd_pci_remove (dev);
+
+	return retval;
+} 
+EXPORT_SYMBOL (usb_hcd_pci_probe);
+
+
+/* may be called without controller electrically present */
+/* may be called with controller, bus, and devices active */
+
+/**
+ * usb_hcd_pci_remove - shutdown processing for PCI-based HCDs
+ * @dev: USB Host Controller being removed
+ * Context: !in_interrupt()
+ *
+ * Reverses the effect of usb_hcd_pci_probe(), first invoking
+ * the HCD's stop() method.  It is always called from a thread
+ * context, normally "rmmod", "apmd", or something similar.
+ *
+ * Store this function in the HCD's struct pci_driver as remove().
+ */
+void STDCALL usb_hcd_pci_remove (struct pci_dev *dev)
+{
+	struct usb_hcd		*hcd;
+	struct usb_device	*hub;
+
+	hcd = pci_get_drvdata(dev);
+	if (!hcd)
+		return;
+	dev_info (hcd->controller, "remove, state %x\n", hcd->state);
+
+	if (in_interrupt ())
+		BUG ();
+
+	hub = hcd->self.root_hub;
+	hcd->state = USB_STATE_QUIESCING;
+
+	dev_dbg (hcd->controller, "roothub graceful disconnect\n");
+	usb_disconnect (&hub);
+
+	hcd->driver->stop (hcd);
+	hcd_buffer_destroy (hcd);
+	hcd->state = USB_STATE_HALT;
+	pci_set_drvdata (dev, 0);
+
+	free_irq (hcd->irq, hcd);
+	if (hcd->driver->flags & HCD_MEMORY) {
+		iounmap (hcd->regs);
+		release_mem_region (pci_resource_start (dev, 0),
+			pci_resource_len (dev, 0));
+	} else {
+		release_region (pci_resource_start (dev, hcd->region),
+			pci_resource_len (dev, hcd->region));
+	}
+
+	usb_deregister_bus (&hcd->self);
+	if (atomic_read (&hcd->self.refcnt) != 1) {
+		dev_warn (hcd->controller,
+			"dangling refs (%d) to bus %d!\n",
+			atomic_read (&hcd->self.refcnt) - 1,
+			hcd->self.busnum);
+	}
+	hcd->driver->hcd_free (hcd);
+}
+EXPORT_SYMBOL (usb_hcd_pci_remove);
+
+
+#ifdef	CONFIG_PM
+
+/*
+ * Some "sleep" power levels imply updating struct usb_driver
+ * to include a callback asking hcds to do their bit by checking
+ * if all the drivers can suspend.  Gets involved with remote wakeup.
+ *
+ * If there are pending urbs, then HCs will need to access memory,
+ * causing extra power drain.  New sleep()/wakeup() PM calls might
+ * be needed, beyond PCI suspend()/resume().  The root hub timer
+ * still be accessing memory though ...
+ *
+ * FIXME:  USB should have some power budgeting support working with
+ * all kinds of hubs.
+ *
+ * FIXME:  This assumes only D0->D3 suspend and D3->D0 resume.
+ * D1 and D2 states should do something, yes?
+ *
+ * FIXME:  Should provide generic enable_wake(), calling pci_enable_wake()
+ * for all supported states, so that USB remote wakeup can work for any
+ * devices that support it (and are connected via powered hubs).
+ *
+ * FIXME:  resume doesn't seem to work right any more...
+ */
+
+
+// 2.4 kernels have issued concurrent resumes (w/APM)
+// we defend against that error; PCI doesn't yet.
+
+/**
+ * usb_hcd_pci_suspend - power management suspend of a PCI-based HCD
+ * @dev: USB Host Controller being suspended
+ *
+ * Store this function in the HCD's struct pci_driver as suspend().
+ */
+int usb_hcd_pci_suspend (struct pci_dev *dev, u32 state)
+{
+	struct usb_hcd		*hcd;
+	int			retval;
+
+	hcd = pci_get_drvdata(dev);
+	dev_info (hcd->controller, "suspend to state %d\n", state);
+
+	pci_save_state (dev, hcd->pci_state);
+
+	// FIXME for all connected devices, leaf-to-root:
+	// driver->suspend()
+	// proposed "new 2.5 driver model" will automate that
+
+	/* driver may want to disable DMA etc */
+	retval = hcd->driver->suspend (hcd, state);
+	hcd->state = USB_STATE_SUSPENDED;
+
+ 	pci_set_power_state (dev, state);
+	return retval;
+}
+EXPORT_SYMBOL (usb_hcd_pci_suspend);
+
+/**
+ * usb_hcd_pci_resume - power management resume of a PCI-based HCD
+ * @dev: USB Host Controller being resumed
+ *
+ * Store this function in the HCD's struct pci_driver as resume().
+ */
+int usb_hcd_pci_resume (struct pci_dev *dev)
+{
+	struct usb_hcd		*hcd;
+	int			retval;
+
+	hcd = pci_get_drvdata(dev);
+	dev_info (hcd->controller, "resume\n");
+
+	/* guard against multiple resumes (APM bug?) */
+	atomic_inc (&hcd->resume_count);
+	if (atomic_read (&hcd->resume_count) != 1) {
+		dev_err (hcd->controller, "concurrent PCI resumes\n");
+		retval = 0;
+		goto done;
+	}
+
+	retval = -EBUSY;
+	if (hcd->state != USB_STATE_SUSPENDED) {
+		dev_dbg (hcd->controller, "can't resume, not suspended!\n");
+		goto done;
+	}
+	hcd->state = USB_STATE_RESUMING;
+
+	pci_set_power_state (dev, 0);
+	pci_restore_state (dev, hcd->pci_state);
+
+	retval = hcd->driver->resume (hcd);
+	if (!HCD_IS_RUNNING (hcd->state)) {
+		dev_dbg (hcd->controller, "resume fail, retval %d\n", retval);
+		usb_hc_died (hcd);
+// FIXME:  recover, reset etc.
+	} else {
+		// FIXME for all connected devices, root-to-leaf:
+		// driver->resume ();
+		// proposed "new 2.5 driver model" will automate that
+	}
+
+done:
+	atomic_dec (&hcd->resume_count);
+	return retval;
+}
+EXPORT_SYMBOL (usb_hcd_pci_resume);
+
+#endif	/* CONFIG_PM */
+
+

Added: trunk/reactos/drivers/usb/cromwell/core/hcd.c
--- trunk/reactos/drivers/usb/cromwell/core/hcd.c	2005-01-26 22:05:12 UTC (rev 13323)
+++ trunk/reactos/drivers/usb/cromwell/core/hcd.c	2005-01-26 22:34:39 UTC (rev 13324)
@@ -0,0 +1,1499 @@
+/*
+ * (C) Copyright Linus Torvalds 1999
+ * (C) Copyright Johannes Erdfelt 1999-2001
+ * (C) Copyright Andreas Gal 1999
+ * (C) Copyright Gregory P. Smith 1999
+ * (C) Copyright Deti Fliegl 1999
+ * (C) Copyright Randy Dunlap 2000
+ * (C) Copyright David Brownell 2000-2002
+ * 
+ * This program is free software; you can redistribute it and/or modify it
[truncated at 1000 lines; 31273 more skipped]