
On Sat, Jan 31, 2015 at 12:34 AM, Simon Glass sjg@chromium.org wrote:
While we currently don't have driver model support for block devices and Ethernet, we can still allow this to work when driver model is used for USB.
Signed-off-by: Simon Glass sjg@chromium.org
common/cmd_usb.c | 74 ++++++++++++++++------ common/usb.c | 28 +++++---- common/usb_hub.c | 13 +++- common/usb_storage.c | 148 ++++++++++++++++++++++++++++---------------- drivers/usb/eth/usb_ether.c | 46 +++++++++++--- include/usb.h | 76 +++++++++++++++++++++-- 6 files changed, 286 insertions(+), 99 deletions(-)
diff --git a/common/cmd_usb.c b/common/cmd_usb.c index 27813f0..b824634 100644 --- a/common/cmd_usb.c +++ b/common/cmd_usb.c @@ -10,6 +10,7 @@
#include <common.h> #include <command.h> +#include <dm.h> #include <asm/byteorder.h> #include <asm/unaligned.h> #include <part.h> @@ -254,16 +255,24 @@ static void usb_display_config(struct usb_device *dev)
static struct usb_device *usb_find_device(int devnum) {
struct usb_device *dev;
+#ifdef CONFIG_DM_USB
struct udevice *dev;
if (uclass_get_device_by_seq(UCLASS_USB, devnum, &dev))
return NULL;
return dev_get_uclass_priv(dev);
+#else
struct usb_device *udev; int d; for (d = 0; d < USB_MAX_DEVICE; d++) {
dev = usb_get_dev_index(d);
if (dev == NULL)
udev = usb_get_dev_index(d);
if (udev == NULL) return NULL;
if (dev->devnum == devnum)
return dev;
if (udev->devnum == devnum)
return udev; }
+#endif
return NULL;
} @@ -466,9 +475,8 @@ static void do_usb_start(void) */ static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) {
struct usb_device *udev = NULL; int i;
struct usb_device *dev = NULL; extern char usb_started;
#ifdef CONFIG_USB_STORAGE block_dev_desc_t *stor_dev; @@ -508,36 +516,64 @@ static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) } if (strncmp(argv[1], "tree", 4) == 0) { puts("USB device tree:\n"); +#ifdef CONFIG_DM_USB
struct udevice *dev;
for (uclass_first_device(UCLASS_USB, &dev);
dev;
uclass_next_device(&dev)) {
struct usb_device *udev = dev_get_uclass_priv(dev);
usb_show_tree(udev);
}
+#else for (i = 0; i < USB_MAX_DEVICE; i++) {
struct usb_device *dev;
dev = usb_get_dev_index(i); if (dev == NULL) break; if (dev->parent == NULL) usb_show_tree(dev); }
+#endif return 0; } if (strncmp(argv[1], "inf", 3) == 0) {
int d; if (argc == 2) {
+#ifdef CONFIG_DM_USB
struct udevice *dev;
for (uclass_first_device(UCLASS_USB, &dev);
dev;
uclass_next_device(&dev)) {
struct usb_device *udev;
udev = dev_get_uclass_priv(dev);
usb_display_desc(udev);
usb_display_config(udev);
}
+#else
int d; for (d = 0; d < USB_MAX_DEVICE; d++) {
dev = usb_get_dev_index(d);
if (dev == NULL)
udev = usb_get_dev_index(d);
if (udev == NULL) break;
usb_display_desc(dev);
usb_display_config(dev);
usb_display_desc(udev);
usb_display_config(udev); }
+#endif return 0; } else { i = simple_strtoul(argv[2], NULL, 10); printf("config for device %d\n", i);
dev = usb_find_device(i);
if (dev == NULL) {
udev = usb_find_device(i);
if (udev == NULL) { printf("*** No device available ***\n"); return 0; } else {
usb_display_desc(dev);
usb_display_config(dev);
usb_display_desc(udev);
usb_display_config(udev); } } return 0;
@@ -546,13 +582,13 @@ static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) if (argc < 5) return CMD_RET_USAGE; i = simple_strtoul(argv[2], NULL, 10);
dev = usb_find_device(i);
if (dev == NULL) {
udev = usb_find_device(i);
if (udev == NULL) { printf("Device %d does not exist.\n", i); return 1; } i = simple_strtoul(argv[3], NULL, 10);
return usb_test(dev, i, argv[4]);
return usb_test(udev, i, argv[4]); }
#ifdef CONFIG_USB_STORAGE if (strncmp(argv[1], "stor", 4) == 0) diff --git a/common/usb.c b/common/usb.c index 32e15cd..3ccf8a7 100644 --- a/common/usb.c +++ b/common/usb.c @@ -41,12 +41,13 @@
#define USB_BUFSIZ 512
-static struct usb_device usb_dev[USB_MAX_DEVICE]; -static int dev_index; static int asynch_allowed;
char usb_started; /* flag for the started/stopped USB status */
+#ifndef CONFIG_DM_USB +static struct usb_device usb_dev[USB_MAX_DEVICE]; +static int dev_index;
#ifndef CONFIG_USB_MAX_CONTROLLER_COUNT #define CONFIG_USB_MAX_CONTROLLER_COUNT 1 #endif @@ -94,12 +95,12 @@ int usb_init(void) controllers_initialized++; start_index = dev_index; printf("scanning bus %d for devices... ", i);
dev = usb_alloc_new_device(ctrl);
ret = usb_alloc_new_device(ctrl, &dev); /* * device 0 is always present * (root hub, so let it analyze) */
if (dev)
if (!ret) usb_new_device(dev); if (start_index == dev_index)
@@ -152,6 +153,7 @@ int usb_disable_asynch(int disable) asynch_allowed = !disable; return old_value; } +#endif /* !CONFIG_DM_USB */
/*------------------------------------------------------------------- @@ -815,6 +817,7 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
- the USB device are static allocated [USB_MAX_DEVICE].
*/
+#ifndef CONFIG_DM_USB
/* returns a pointer to the device with the index [index].
- if the device is not assigned (dev->devnum==-1) returns NULL
@@ -827,16 +830,13 @@ struct usb_device *usb_get_dev_index(int index) return &usb_dev[index]; }
-/* returns a pointer of a new device structure or NULL, if
- no device struct is available
- */
-struct usb_device *usb_alloc_new_device(void *controller) +int usb_alloc_new_device(void *controller, struct usb_device **devp) { int i; debug("New Device %d\n", dev_index); if (dev_index == USB_MAX_DEVICE) { printf("ERROR, too many USB Devices, max=%d\n", USB_MAX_DEVICE);
return NULL;
return -ENOSPC; } /* default Address is 0, real addresses start with 1 */ usb_dev[dev_index].devnum = dev_index + 1;
@@ -846,7 +846,9 @@ struct usb_device *usb_alloc_new_device(void *controller) usb_dev[dev_index].parent = NULL; usb_dev[dev_index].controller = controller; dev_index++;
return &usb_dev[dev_index - 1];
*devp = &usb_dev[dev_index - 1];
return 0;
}
/* @@ -854,7 +856,7 @@ struct usb_device *usb_alloc_new_device(void *controller)
- Called in error cases where configuring a newly attached
- device fails for some reason.
*/ -void usb_free_device(void) +void usb_free_device(void *controller) { dev_index--; debug("Freeing device node: %d\n", dev_index); @@ -872,6 +874,8 @@ __weak int usb_alloc_device(struct usb_device *udev) { return 0; } +#endif /* !CONFIG_DM_USB */
/*
- By the time we get here, the device has gotten a new device ID
- and is in the default state. We need to identify the thing and
diff --git a/common/usb_hub.c b/common/usb_hub.c index 66b4a72..ccdf755 100644 --- a/common/usb_hub.c +++ b/common/usb_hub.c @@ -211,6 +211,7 @@ void usb_hub_port_connect_change(struct usb_device *dev, int port) struct usb_device *usb; ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1); unsigned short portstatus;
int ret; /* Check status */ if (usb_get_port_status(dev, port + 1, portsts) < 0) {
@@ -246,7 +247,15 @@ void usb_hub_port_connect_change(struct usb_device *dev, int port) mdelay(200);
/* Allocate a new device struct for it */
usb = usb_alloc_new_device(dev->controller);
+#ifdef CONFIG_DM_USB
ret = usb_alloc_new_device(dev->controller_dev, &usb);
+#else
ret = usb_alloc_new_device(dev->controller, &usb);
+#endif
if (ret) {
printf("cannot create new device: reg=%d", ret);
return;
} switch (portstatus & USB_PORT_STAT_SPEED_MASK) { case USB_PORT_STAT_SUPER_SPEED:
@@ -269,7 +278,7 @@ void usb_hub_port_connect_change(struct usb_device *dev, int port) /* Run it through the hoops (find a driver, etc) */ if (usb_new_device(usb)) { /* Woops, disable the port */
usb_free_device();
usb_free_device(dev->controller); dev->children[port] = NULL; debug("hub: disabling port %d\n", port + 1); usb_clear_port_feature(dev, port + 1, USB_PORT_FEAT_ENABLE);
diff --git a/common/usb_storage.c b/common/usb_storage.c index 1411737..8fb2c18 100644 --- a/common/usb_storage.c +++ b/common/usb_storage.c @@ -33,9 +33,12 @@
#include <common.h> #include <command.h> +#include <dm.h> +#include <errno.h> #include <inttypes.h> #include <asm/byteorder.h> #include <asm/processor.h> +#include <dm/device-internal.h>
#include <part.h> #include <usb.h> @@ -158,7 +161,6 @@ unsigned long usb_stor_read(int device, lbaint_t blknr, lbaint_t blkcnt, void *buffer); unsigned long usb_stor_write(int device, lbaint_t blknr, lbaint_t blkcnt, const void *buffer); -struct usb_device * usb_get_dev_index(int index); void uhci_show_temp_int_td(void);
#ifdef CONFIG_PARTITIONS @@ -208,6 +210,44 @@ static unsigned int usb_get_max_lun(struct us_data *us) return (len > 0) ? *result : 0; }
+static int usb_stor_probe_device(struct usb_device *dev) +{
if (dev == NULL)
return -ENOENT; /* no more devices available */
if (usb_storage_probe(dev, 0, &usb_stor[usb_max_devs])) {
/* OK, it's a storage device. Iterate over its LUNs
* and populate `usb_dev_desc'.
*/
int lun, max_lun, start = usb_max_devs;
max_lun = usb_get_max_lun(&usb_stor[usb_max_devs]);
for (lun = 0;
lun <= max_lun && usb_max_devs < USB_MAX_STOR_DEV;
lun++) {
struct block_dev_desc *blkdev;
blkdev = &usb_dev_desc[usb_max_devs];
if (usb_stor_get_info(dev, &usb_stor[start],
&usb_dev_desc[usb_max_devs]) ==
1) {
blkdev->lun = lun;
blkdev->priv = dev;
usb_max_devs++;
}
}
}
/* if storage device */
if (usb_max_devs == USB_MAX_STOR_DEV) {
printf("max USB Storage Device reached: %d stopping\n",
usb_max_devs);
return -ENOSPC;
}
return 0;
+} /*******************************************************************************
- scan the usb and reports device info
- to the user if mode = 1
@@ -215,8 +255,8 @@ static unsigned int usb_get_max_lun(struct us_data *us) */ int usb_stor_scan(int mode) {
struct block_dev_desc *blkdev; unsigned char i;
struct usb_device *dev; if (mode == 1) printf(" scanning usb for storage devices... ");
@@ -224,47 +264,55 @@ int usb_stor_scan(int mode) usb_disable_asynch(1); /* asynch transfer not allowed */
for (i = 0; i < USB_MAX_STOR_DEV; i++) {
memset(&usb_dev_desc[i], 0, sizeof(block_dev_desc_t));
usb_dev_desc[i].if_type = IF_TYPE_USB;
usb_dev_desc[i].dev = i;
usb_dev_desc[i].part_type = PART_TYPE_UNKNOWN;
usb_dev_desc[i].target = 0xff;
usb_dev_desc[i].type = DEV_TYPE_UNKNOWN;
usb_dev_desc[i].block_read = usb_stor_read;
usb_dev_desc[i].block_write = usb_stor_write;
blkdev = &usb_dev_desc[i];
memset(&blkdev, 0, sizeof(block_dev_desc_t));
blkdev->if_type = IF_TYPE_USB;
blkdev->dev = i;
blkdev->part_type = PART_TYPE_UNKNOWN;
blkdev->target = 0xff;
blkdev->type = DEV_TYPE_UNKNOWN;
blkdev->block_read = usb_stor_read;
blkdev->block_write = usb_stor_write; } usb_max_devs = 0;
+#ifdef CONFIG_DM_USB
struct udevice *bus;
struct uclass *uc;
int ret;
ret = uclass_get(UCLASS_USB, &uc);
if (ret)
return ret;
uclass_foreach_dev(bus, uc) {
struct udevice *dev;
for (device_find_first_child(bus, &dev);
dev;
device_find_next_child(&dev)) {
ret = device_probe(dev);
if (!ret) {
struct usb_device *udev;
udev = dev_get_parentdata(dev);
ret = usb_stor_probe_device(udev);
}
if (ret) {
printf("Device '%s' probe failed: %d\n",
dev->name, ret);
}
}
}
+#else for (i = 0; i < USB_MAX_DEVICE; i++) {
struct usb_device *dev;
dev = usb_get_dev_index(i); /* get device */ debug("i=%d\n", i);
if (dev == NULL)
break; /* no more devices available */
if (usb_storage_probe(dev, 0, &usb_stor[usb_max_devs])) {
/* OK, it's a storage device. Iterate over its LUNs
* and populate `usb_dev_desc'.
*/
int lun, max_lun, start = usb_max_devs;
max_lun = usb_get_max_lun(&usb_stor[usb_max_devs]);
for (lun = 0;
lun <= max_lun && usb_max_devs < USB_MAX_STOR_DEV;
lun++) {
usb_dev_desc[usb_max_devs].lun = lun;
if (usb_stor_get_info(dev, &usb_stor[start],
&usb_dev_desc[usb_max_devs]) == 1) {
usb_max_devs++;
}
}
}
/* if storage device */
if (usb_max_devs == USB_MAX_STOR_DEV) {
printf("max USB Storage Device reached: %d stopping\n",
usb_max_devs);
if (usb_stor_probe_device(dev)) break;
} } /* for */
+#endif
usb_disable_asynch(0); /* asynch transfer allowed */ printf("%d Storage Device(s) found\n", usb_max_devs);
@@ -1046,7 +1094,7 @@ unsigned long usb_stor_read(int device, lbaint_t blknr, unsigned short smallblks; struct usb_device *dev; struct us_data *ss;
int retry, i;
int retry; ccb *srb = &usb_ccb; if (blkcnt == 0)
@@ -1054,15 +1102,10 @@ unsigned long usb_stor_read(int device, lbaint_t blknr,
device &= 0xff; /* Setup device */
debug("\nusb_read: dev %d \n", device);
dev = NULL;
for (i = 0; i < USB_MAX_DEVICE; i++) {
dev = usb_get_dev_index(i);
if (dev == NULL)
return 0;
if (dev->devnum == usb_dev_desc[device].target)
break;
}
debug("\nusb_read: dev %d\n", device);
dev = usb_dev_desc[device].priv;
if (!dev)
return 0; ss = (struct us_data *)dev->privptr; usb_disable_asynch(1); /* asynch transfer not allowed */
@@ -1119,7 +1162,7 @@ unsigned long usb_stor_write(int device, lbaint_t blknr, unsigned short smallblks; struct usb_device *dev; struct us_data *ss;
int retry, i;
int retry; ccb *srb = &usb_ccb; if (blkcnt == 0)
@@ -1127,15 +1170,10 @@ unsigned long usb_stor_write(int device, lbaint_t blknr,
device &= 0xff; /* Setup device */
debug("\nusb_write: dev %d \n", device);
dev = NULL;
for (i = 0; i < USB_MAX_DEVICE; i++) {
dev = usb_get_dev_index(i);
if (dev == NULL)
return 0;
if (dev->devnum == usb_dev_desc[device].target)
break;
}
debug("\nusb_write: dev %d\n", device);
dev = usb_dev_desc[device].priv;
if (!dev)
return 0; ss = (struct us_data *)dev->privptr; usb_disable_asynch(1); /* asynch transfer not allowed */
diff --git a/drivers/usb/eth/usb_ether.c b/drivers/usb/eth/usb_ether.c index 7cb96e3..4334d16 100644 --- a/drivers/usb/eth/usb_ether.c +++ b/drivers/usb/eth/usb_ether.c @@ -5,7 +5,9 @@ */
#include <common.h> +#include <dm.h> #include <usb.h> +#include <dm/device-internal.h>
#include "usb_ether.h"
@@ -118,8 +120,6 @@ static void probe_valid_drivers(struct usb_device *dev) int usb_host_eth_scan(int mode) { int i, old_async;
struct usb_device *dev;
if (mode == 1) printf(" scanning usb for ethernet devices... ");
@@ -138,7 +138,38 @@ int usb_host_eth_scan(int mode) }
usb_max_eth_dev = 0;
+#ifdef CONFIG_DM_USB
struct udevice *bus;
struct uclass *uc;
int ret;
ret = uclass_get(UCLASS_USB, &uc);
if (ret)
return ret;
uclass_foreach_dev(bus, uc) {
for (i = 0; i < USB_MAX_DEVICE; i++) {
struct usb_device *dev;
dev = usb_get_dev_index(bus, i); /* get device */
debug("i=%d\n", i);
if (dev == NULL)
break; /* no more devices available */
/*
* find valid usb_ether driver for this device,
* if any
*/
probe_valid_drivers(dev);
/* check limit */
if (usb_max_eth_dev == USB_MAX_ETH_DEV)
break;
} /* for */
}
+#else for (i = 0; i < USB_MAX_DEVICE; i++) {
struct usb_device *dev;
dev = usb_get_dev_index(i); /* get device */ debug("i=%d\n", i); if (dev == NULL)
@@ -148,13 +179,14 @@ int usb_host_eth_scan(int mode) probe_valid_drivers(dev);
/* check limit */
if (usb_max_eth_dev == USB_MAX_ETH_DEV) {
printf("max USB Ethernet Device reached: %d stopping\n",
usb_max_eth_dev);
if (usb_max_eth_dev == USB_MAX_ETH_DEV) break;
} } /* for */
+#endif
if (usb_max_eth_dev == USB_MAX_ETH_DEV) {
printf("max USB Ethernet Device reached: %d stopping\n",
usb_max_eth_dev);
} usb_disable_asynch(old_async); /* restore asynch value */ printf("%d Ethernet Device(s) found\n", usb_max_eth_dev); if (usb_max_eth_dev > 0)
diff --git a/include/usb.h b/include/usb.h index a8fee0b..ba80eb8 100644 --- a/include/usb.h +++ b/include/usb.h @@ -9,6 +9,7 @@ #ifndef _USB_H_ #define _USB_H_
+#include <fdtdec.h> #include <usb_defs.h> #include <linux/usb/ch9.h> #include <asm/cache.h> @@ -130,6 +131,10 @@ struct usb_device { void *controller; /* hardware controller private data */ /* slot_id - for xHCI enabled devices */ unsigned int slot_id; +#ifdef CONFIG_DM_USB
char **strings;
struct udevice *controller_dev;
+#endif };
struct int_queue; @@ -245,7 +250,6 @@ int usb_stop(void); /* stop the USB Controller */ int usb_set_protocol(struct usb_device *dev, int ifnum, int protocol); int usb_set_idle(struct usb_device *dev, int ifnum, int duration, int report_id); -struct usb_device *usb_get_dev_index(int index); int usb_control_msg(struct usb_device *dev, unsigned int pipe, unsigned char request, unsigned char requesttype, unsigned short value, unsigned short index, @@ -423,15 +427,79 @@ struct usb_hub_device { struct usb_hub_descriptor desc; };
+#ifdef CONFIG_DM_USB
+/* This is attached to each controller */ +struct dm_usb_info {
struct usb_device usb_dev[USB_MAX_DEVICE];
int dev_index;
struct udevice *dev;
void *controller; /* struct xhci_ctrl, etc. */
+};
+struct dm_usb_ops {
int (*hcd_init)(struct udevice *dev, fdt_addr_t *hccrp,
fdt_addr_t *hcorp);
int (*control)(struct udevice *dev, struct usb_device *udev,
unsigned long pipe, void *buffer, int length,
struct devrequest *setup);
int (*bulk)(struct udevice *dev, struct usb_device *udev,
unsigned long pipe, void *buffer, int length);
int (*interrupt)(struct udevice *dev, struct usb_device *udev,
unsigned long pipe, void *buffer, int length,
interval);
data type required for "interval". It gives build error.
int (*alloc_device)(struct udevice *dev, struct usb_device *udev);
+};
+#define usb_get_ops(dev) ((struct dm_usb_ops *)(dev)->driver->ops) +#define usb_get_emul_ops(dev) ((struct dm_usb_ops *)(dev)->driver->ops)
+int submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
int length, int interval);
+int submit_control_msg(struct usb_device *dev, unsigned long pipe,
void *buffer, int length, struct devrequest *setup);
+int submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
int length);
+#ifdef CONFIG_MUSB_HOST +int usb_reset_root_port(void); +#endif
+void usb_free_device(struct udevice *controller); +/**
- usb_alloc_new_device() - Allocate a new device
- @devp: returns a pointer of a new device structure
- @return 0 if OK, -ENOSPC if we have found out of room for new devices
- */
+int usb_alloc_new_device(struct udevice *controller, struct usb_device **devp);
+struct usb_device *usb_get_dev_index(struct udevice *controller, int index);
+#else
+void usb_free_device(void *controller); +/**
- usb_alloc_new_device() - Allocate a new device
- @devp: returns a pointer of a new device structure
- @return 0 if OK, -ENOSPC if we have found out of room for new devices
- */
+int usb_alloc_new_device(void *controller, struct usb_device **devp);
+struct usb_device *usb_get_dev_index(int index);
+#endif
int usb_hub_probe(struct usb_device *dev, int ifnum); void usb_hub_reset(void); int hub_port_reset(struct usb_device *dev, int port, unsigned short *portstat);
-struct usb_device *usb_alloc_new_device(void *controller);
int usb_new_device(struct usb_device *dev); -void usb_free_device(void);
int usb_alloc_device(struct usb_device *dev);
#endif /*_USB_H_ */
2.2.0.rc0.207.ga3a616c
U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot