All of lore.kernel.org
 help / color / mirror / Atom feed
From: Simon Glass <sjg@chromium.org>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH 25/30] dm: usb: Convert USB storage to use driver-model for block devs
Date: Sun, 14 Feb 2016 19:16:54 -0700	[thread overview]
Message-ID: <1455502619-16093-26-git-send-email-sjg@chromium.org> (raw)
In-Reply-To: <1455502619-16093-1-git-send-email-sjg@chromium.org>

Update this code to support CONFIG_BLK. Each USB storage device can have
one or more block devices as children, each one representing a LUN
(logical unit) of the USB device.

Signed-off-by: Simon Glass <sjg@chromium.org>
---

 common/usb_storage.c | 141 ++++++++++++++++++++++++++++++++++++++++++++++++---
 1 file changed, 135 insertions(+), 6 deletions(-)

diff --git a/common/usb_storage.c b/common/usb_storage.c
index 0475123..1472824 100644
--- a/common/usb_storage.c
+++ b/common/usb_storage.c
@@ -43,6 +43,7 @@
 #include <asm/byteorder.h>
 #include <asm/processor.h>
 #include <dm/device-internal.h>
+#include <dm/lists.h>
 
 #include <part.h>
 #include <usb.h>
@@ -67,7 +68,9 @@ static __u32 CBWTag;
 
 static int usb_max_devs; /* number of highest available usb device */
 
+#ifndef CONFIG_BLK
 static struct blk_desc usb_dev_desc[USB_MAX_STOR_DEV];
+#endif
 
 struct us_data;
 typedef int (*trans_cmnd)(ccb *cb, struct us_data *data);
@@ -108,7 +111,9 @@ struct us_data {
 #define USB_MAX_XFER_BLK	20
 #endif
 
+#ifndef CONFIG_BLK
 static struct us_data usb_stor[USB_MAX_STOR_DEV];
+#endif
 
 #define USB_STOR_TRANSPORT_GOOD	   0
 #define USB_STOR_TRANSPORT_FAILED -1
@@ -118,16 +123,33 @@ int usb_stor_get_info(struct usb_device *dev, struct us_data *us,
 		      struct blk_desc *dev_desc);
 int usb_storage_probe(struct usb_device *dev, unsigned int ifnum,
 		      struct us_data *ss);
+#ifdef CONFIG_BLK
+static unsigned long usb_stor_read(struct udevice *dev, lbaint_t blknr,
+				   lbaint_t blkcnt, void *buffer);
+static unsigned long usb_stor_write(struct udevice *dev, lbaint_t blknr,
+				    lbaint_t blkcnt, const void *buffer);
+#else
 static unsigned long usb_stor_read(struct blk_desc *block_dev, lbaint_t blknr,
 				   lbaint_t blkcnt, void *buffer);
 static unsigned long usb_stor_write(struct blk_desc *block_dev, lbaint_t blknr,
 				    lbaint_t blkcnt, const void *buffer);
+#endif
 void uhci_show_temp_int_td(void);
 
 #ifdef CONFIG_PARTITIONS
 struct blk_desc *usb_stor_get_dev(int index)
 {
+#ifdef CONFIG_BLK
+	struct udevice *dev;
+	int ret;
+
+	ret = blk_get_device(IF_TYPE_USB, index, &dev);
+	if (ret)
+		return NULL;
+	return dev_get_uclass_platdata(dev);
+#else
 	return (index < usb_max_devs) ? &usb_dev_desc[index] : NULL;
+#endif
 }
 #endif
 
@@ -143,6 +165,19 @@ static void usb_show_progress(void)
 int usb_stor_info(void)
 {
 	int count = 0;
+#ifdef CONFIG_BLK
+	struct udevice *dev;
+
+	for (blk_first_device(IF_TYPE_USB, &dev);
+	     dev;
+	     blk_next_device(&dev)) {
+		struct blk_desc *desc = dev_get_uclass_platdata(dev);
+
+		printf("  Device %d: ", desc->devnum);
+		dev_print(desc);
+		count++;
+	}
+#else
 	int i;
 
 	if (usb_max_devs > 0) {
@@ -152,7 +187,7 @@ int usb_stor_info(void)
 		}
 		return 0;
 	}
-
+#endif
 	if (!count) {
 		printf("No storage devices, perhaps not 'usb start'ed..?\n");
 		return 1;
@@ -179,11 +214,63 @@ static unsigned int usb_get_max_lun(struct us_data *us)
 static int usb_stor_probe_device(struct usb_device *udev)
 {
 	int lun, max_lun;
+
+#ifdef CONFIG_BLK
+	struct us_data *data;
+	char dev_name[30], *str;
+	int ret;
+#else
 	int start;
 
 	if (udev == NULL)
 		return -ENOENT; /* no more devices available */
+#endif
+
+	debug("\n\nProbing for storage\n");
+#ifdef CONFIG_BLK
+	/*
+	 * We store the us_data in the mass storage device's platdata. It
+	 * is shared by all LUNs (block devices) attached to this mass storage
+	 * device.
+	 */
+	data = dev_get_platdata(udev->dev);
+	if (!usb_storage_probe(udev, 0, data))
+		return 0;
+	max_lun = usb_get_max_lun(data);
+	for (lun = 0; lun <= max_lun; lun++) {
+		struct blk_desc *blkdev;
+		struct udevice *dev;
+
+		snprintf(dev_name, sizeof(dev_name), "%s.lun%d",
+			 udev->dev->name, lun);
+		str = strdup(dev_name);
+		if (!str)
+			return -ENOMEM;
+		ret = blk_create_device(udev->dev, "usb_storage_blk", str,
+				IF_TYPE_USB, usb_max_devs, 512, 0, &dev);
+		if (ret) {
+			debug("Cannot bind driver\n");
+			return ret;
+		}
+
+		blkdev = dev_get_uclass_platdata(dev);
+		blkdev->target = 0xff;
+		blkdev->lun = lun;
 
+		ret = usb_stor_get_info(udev, data, blkdev);
+		if (ret == 1)
+			ret = blk_prepare_device(dev);
+		if (!ret) {
+			usb_max_devs++;
+			debug("%s: Found device %p\n", __func__, udev);
+		} else {
+			debug("usb_stor_get_info: Invalid device\n");
+			ret = device_unbind(dev);
+			if (ret)
+				return ret;
+		}
+	}
+#else
 	/* We don't have space to even probe if we hit the maximum */
 	if (usb_max_devs == USB_MAX_STOR_DEV) {
 		printf("max USB Storage Device reached: %d stopping\n",
@@ -191,7 +278,6 @@ static int usb_stor_probe_device(struct usb_device *udev)
 		return -ENOSPC;
 	}
 
-	debug("\n\nProbing for storage\n");
 	if (!usb_storage_probe(udev, 0, &usb_stor[usb_max_devs]))
 		return 0;
 
@@ -220,10 +306,14 @@ static int usb_stor_probe_device(struct usb_device *udev)
 
 		if (usb_stor_get_info(udev, &usb_stor[start],
 				      &usb_dev_desc[usb_max_devs]) == 1) {
+			debug("partype: %d\n", blkdev->part_type);
+			part_init(blkdev);
+			debug("partype: %d\n", blkdev->part_type);
 			usb_max_devs++;
 			debug("%s: Found device %p\n", __func__, udev);
 		}
 	}
+#endif
 
 	return 0;
 }
@@ -1034,8 +1124,13 @@ static void usb_bin_fixup(struct usb_device_descriptor descriptor,
 }
 #endif /* CONFIG_USB_BIN_FIXUP */
 
+#ifdef CONFIG_BLK
+static unsigned long usb_stor_read(struct udevice *dev, lbaint_t blknr,
+				   lbaint_t blkcnt, void *buffer)
+#else
 static unsigned long usb_stor_read(struct blk_desc *block_dev, lbaint_t blknr,
 				   lbaint_t blkcnt, void *buffer)
+#endif
 {
 	lbaint_t start, blks;
 	uintptr_t buf_addr;
@@ -1044,16 +1139,25 @@ static unsigned long usb_stor_read(struct blk_desc *block_dev, lbaint_t blknr,
 	struct us_data *ss;
 	int retry;
 	ccb *srb = &usb_ccb;
+#ifdef CONFIG_BLK
+	struct blk_desc *block_dev;
+#endif
 
 	if (blkcnt == 0)
 		return 0;
 	/* Setup  device */
+#ifdef CONFIG_BLK
+	block_dev = dev_get_uclass_platdata(dev);
+	udev = dev_get_parent_priv(dev_get_parent(dev));
+	debug("\nusb_read: udev %d\n", block_dev->devnum);
+#else
 	debug("\nusb_read: udev %d\n", block_dev->devnum);
 	udev = usb_dev_desc[block_dev->devnum].priv;
 	if (!udev) {
 		debug("%s: No device\n", __func__);
 		return 0;
 	}
+#endif
 	ss = (struct us_data *)udev->privptr;
 
 	usb_disable_asynch(1); /* asynch transfer not allowed */
@@ -1102,8 +1206,13 @@ retry_it:
 	return blkcnt;
 }
 
+#ifdef CONFIG_BLK
+static unsigned long usb_stor_write(struct udevice *dev, lbaint_t blknr,
+				    lbaint_t blkcnt, const void *buffer)
+#else
 static unsigned long usb_stor_write(struct blk_desc *block_dev, lbaint_t blknr,
 				    lbaint_t blkcnt, const void *buffer)
+#endif
 {
 	lbaint_t start, blks;
 	uintptr_t buf_addr;
@@ -1112,17 +1221,26 @@ static unsigned long usb_stor_write(struct blk_desc *block_dev, lbaint_t blknr,
 	struct us_data *ss;
 	int retry;
 	ccb *srb = &usb_ccb;
+#ifdef CONFIG_BLK
+	struct blk_desc *block_dev;
+#endif
 
 	if (blkcnt == 0)
 		return 0;
 
 	/* Setup  device */
+#ifdef CONFIG_BLK
+	block_dev = dev_get_uclass_platdata(dev);
+	udev = dev_get_parent_priv(dev_get_parent(dev));
+	debug("\nusb_read: udev %d\n", block_dev->devnum);
+#else
 	debug("\nusb_read: udev %d\n", block_dev->devnum);
 	udev = usb_dev_desc[block_dev->devnum].priv;
 	if (!udev) {
 		debug("%s: No device\n", __func__);
 		return 0;
 	}
+#endif
 	ss = (struct us_data *)udev->privptr;
 
 	usb_disable_asynch(1); /* asynch transfer not allowed */
@@ -1377,11 +1495,7 @@ int usb_stor_get_info(struct usb_device *dev, struct us_data *ss,
 	dev_desc->log2blksz = LOG2(dev_desc->blksz);
 	dev_desc->type = perq;
 	debug(" address %d\n", dev_desc->target);
-	debug("partype: %d\n", dev_desc->part_type);
-
-	part_init(dev_desc);
 
-	debug("partype: %d\n", dev_desc->part_type);
 	return 1;
 }
 
@@ -1409,6 +1523,9 @@ U_BOOT_DRIVER(usb_mass_storage) = {
 	.id	= UCLASS_MASS_STORAGE,
 	.of_match = usb_mass_storage_ids,
 	.probe = usb_mass_storage_probe,
+#ifdef CONFIG_BLK
+	.platdata_auto_alloc_size	= sizeof(struct us_data),
+#endif
 };
 
 UCLASS_DRIVER(usb_mass_storage) = {
@@ -1425,5 +1542,17 @@ static const struct usb_device_id mass_storage_id_table[] = {
 };
 
 U_BOOT_USB_DEVICE(usb_mass_storage, mass_storage_id_table);
+#endif
 
+#ifdef CONFIG_BLK
+static const struct blk_ops usb_storage_ops = {
+	.read	= usb_stor_read,
+	.write	= usb_stor_write,
+};
+
+U_BOOT_DRIVER(usb_storage_blk) = {
+	.name		= "usb_storage_blk",
+	.id		= UCLASS_BLK,
+	.ops		= &usb_storage_ops,
+};
 #endif
-- 
2.7.0.rc3.207.g0ac5344

  parent reply	other threads:[~2016-02-15  2:16 UTC|newest]

Thread overview: 69+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-02-15  2:16 [U-Boot] [PATCH 00/30] dm: Add driver-model support for block drivers Simon Glass
2016-02-15  2:16 ` [U-Boot] [PATCH 01/30] dm: Drop the block_dev_desc_t typedef Simon Glass
2016-02-16 10:09   ` Bin Meng
2016-02-15  2:16 ` [U-Boot] [PATCH 02/30] dm: pci: Break out the common region display code Simon Glass
2016-02-16 10:09   ` Bin Meng
2016-02-29  4:18     ` Simon Glass
2016-02-17  0:19   ` Stephen Warren
2016-02-15  2:16 ` [U-Boot] [PATCH 03/30] dm: part: Correct a sandbox build warning Simon Glass
2016-02-16 10:09   ` Bin Meng
2016-02-29  4:18     ` Simon Glass
2016-02-15  2:16 ` [U-Boot] [PATCH 04/30] dm: fdtdec: " Simon Glass
2016-02-15  2:16 ` [U-Boot] [PATCH 05/30] dm: part: Drop the common.h header Simon Glass
2016-02-16 10:09   ` Bin Meng
2016-02-15  2:16 ` [U-Boot] [PATCH 06/30] dm: Add a new header for block devices Simon Glass
2016-02-16 10:10   ` Bin Meng
2016-02-15  2:16 ` [U-Boot] [PATCH 07/30] dm: blk: Convert interface type to an enum Simon Glass
2016-02-16 10:10   ` Bin Meng
2016-02-15  2:16 ` [U-Boot] [PATCH 08/30] dm: blk: Add comments to a few functions Simon Glass
2016-02-16 10:10   ` Bin Meng
2016-02-15  2:16 ` [U-Boot] [PATCH 09/30] dm: blk: Rename get_dev() to blk_get_dev() Simon Glass
2016-02-16 10:10   ` Bin Meng
2016-02-15  2:16 ` [U-Boot] [PATCH 10/30] dm: blk: Rename get_device() to blk_get_device_str() Simon Glass
2016-02-16 14:02   ` Bin Meng
2016-02-16 23:14   ` Stephen Warren
2016-02-15  2:16 ` [U-Boot] [PATCH 11/30] dm: blk: Rename get_device_and_partition() Simon Glass
2016-02-16 14:02   ` Bin Meng
2016-02-15  2:16 ` [U-Boot] [PATCH 12/30] dm: part: Add a cast to avoid a compiler warning Simon Glass
2016-02-16 14:02   ` Bin Meng
2016-02-15  2:16 ` [U-Boot] [PATCH 13/30] dm: sandbox: Enable all partition types Simon Glass
2016-02-15 22:37   ` Tom Rini
2016-02-16 14:02   ` Bin Meng
2016-02-15  2:16 ` [U-Boot] [PATCH 14/30] dm: part: Convert partition API use to linker lists Simon Glass
2016-02-15 22:37   ` Tom Rini
2016-02-16 14:25   ` Bin Meng
2016-02-29  4:18     ` Simon Glass
2016-02-17  6:41   ` Stephen Warren
2016-02-29  4:48     ` Simon Glass
2016-02-15  2:16 ` [U-Boot] [PATCH 15/30] dm: part: Rename some partition functions Simon Glass
2016-02-16 14:25   ` Bin Meng
2016-02-29  4:19     ` Simon Glass
2016-02-15  2:16 ` [U-Boot] [PATCH 16/30] dm: cbfs: Fix handling of invalid type Simon Glass
2016-02-16 14:51   ` Bin Meng
2016-02-29  4:19     ` Simon Glass
2016-02-15  2:16 ` [U-Boot] [PATCH 17/30] dm: sandbox: Enable cbfs and cramfs Simon Glass
2016-02-16 14:51   ` Bin Meng
2016-02-15  2:16 ` [U-Boot] [PATCH 18/30] dm: block: Rename device number member dev to devnum Simon Glass
2016-02-16 14:51   ` Bin Meng
2016-02-16 23:23   ` Stephen Warren
2016-02-29  4:19     ` Simon Glass
2016-02-15  2:16 ` [U-Boot] [PATCH 19/30] dm: block: Adjust device calls to go through helpers function Simon Glass
2016-02-16 14:51   ` Bin Meng
2016-02-15  2:16 ` [U-Boot] [PATCH 20/30] dm: usb: Avoid exceeding available array size for storage devices Simon Glass
2016-02-15  2:16 ` [U-Boot] [PATCH 21/30] dm: usb: Tidy up storage code ready for driver model conversion Simon Glass
2016-02-15  2:16 ` [U-Boot] [PATCH 22/30] dm: blk: Add a block-device uclass Simon Glass
2016-02-17  4:49   ` Bin Meng
2016-02-15  2:16 ` [U-Boot] [PATCH 23/30] dm: sandbox: Prepare block driver for driver-model conversion Simon Glass
2016-02-15  2:16 ` [U-Boot] [PATCH 24/30] dm: sandbox: Add driver-model block-device support for sandbox Simon Glass
2016-02-16 23:34   ` Stephen Warren
2016-02-29  4:19     ` Simon Glass
2016-02-15  2:16 ` Simon Glass [this message]
2016-02-15  2:16 ` [U-Boot] [PATCH 26/30] dm: usb: Unbind old block devices when shutting down USB Simon Glass
2016-02-15  2:16 ` [U-Boot] [PATCH 27/30] dm: sandbox: Switch over to use DM for block devices Simon Glass
2016-02-15  2:16 ` [U-Boot] [PATCH 28/30] dm: sandbox: Drop the pre-DM host implementation Simon Glass
2016-02-15  2:16 ` [U-Boot] [PATCH 29/30] dm: usb: Clean up USB after each test Simon Glass
2016-02-15  2:16 ` [U-Boot] [PATCH 30/30] dm: blk: Add tests for block devices Simon Glass
2016-02-15 22:37 ` [U-Boot] [PATCH 00/30] dm: Add driver-model support for block drivers Tom Rini
2016-02-29  4:19   ` Simon Glass
2016-02-16 23:43 ` Stephen Warren
2016-02-29  4:19   ` Simon Glass

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1455502619-16093-26-git-send-email-sjg@chromium.org \
    --to=sjg@chromium.org \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.