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(a)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]