summaryrefslogtreecommitdiff
path: root/common
diff options
context:
space:
mode:
authorJean-Jacques Hiblot <jjhiblot@ti.com>2017-04-07 11:42:08 (GMT)
committerSimon Glass <sjg@chromium.org>2017-04-15 01:38:57 (GMT)
commit4e27b9a5845e9c061b315b7ca301eff982d6898f (patch)
tree787b5d8751c4b3ec557672177760383e6bb11646 /common
parent1330a726ff0c8164cf6035ab4a6d1e31805f69d1 (diff)
downloadu-boot-4e27b9a5845e9c061b315b7ca301eff982d6898f.tar.xz
dm: scsi: fix divide-by-0 error in scsi_scan()
With DM_SCSI enabled, blk_create_devicef() is called with blkz = 0, leading to a divide-by-0 exception. scsi_detect_dev() can be used to get the required parameters (block size and number of blocks) from the drive before calling blk_create_devicef(). Signed-off-by: Jean-Jacques Hiblot <jjhiblot@ti.com> Reviewed-by: Tom Rini <trini@konsulko.com> Reviewed-by: Simon Glass <sjg@chromium.org>
Diffstat (limited to 'common')
-rw-r--r--common/scsi.c35
1 files changed, 26 insertions, 9 deletions
diff --git a/common/scsi.c b/common/scsi.c
index 972ef338..d37222c 100644
--- a/common/scsi.c
+++ b/common/scsi.c
@@ -580,9 +580,19 @@ int scsi_scan(int mode)
for (lun = 0; lun < plat->max_lun; lun++) {
struct udevice *bdev; /* block device */
/* block device description */
+ struct blk_desc _bd;
struct blk_desc *bdesc;
char str[10];
+ scsi_init_dev_desc_priv(&_bd);
+ ret = scsi_detect_dev(i, lun, &_bd);
+ if (ret)
+ /*
+ * no device detected?
+ * check the next lun.
+ */
+ continue;
+
/*
* Create only one block device and do detection
* to make sure that there won't be a lot of
@@ -590,20 +600,27 @@ int scsi_scan(int mode)
*/
snprintf(str, sizeof(str), "id%dlun%d", i, lun);
ret = blk_create_devicef(dev, "scsi_blk",
- str, IF_TYPE_SCSI,
- -1, 0, 0, &bdev);
+ str, IF_TYPE_SCSI,
+ -1,
+ _bd.blksz,
+ _bd.blksz * _bd.lba,
+ &bdev);
if (ret) {
debug("Can't create device\n");
return ret;
}
- bdesc = dev_get_uclass_platdata(bdev);
- scsi_init_dev_desc_priv(bdesc);
- ret = scsi_detect_dev(i, lun, bdesc);
- if (ret) {
- device_unbind(bdev);
- continue;
- }
+ bdesc = dev_get_uclass_platdata(bdev);
+ bdesc->target = i;
+ bdesc->lun = lun;
+ bdesc->removable = _bd.removable;
+ bdesc->type = _bd.type;
+ memcpy(&bdesc->vendor, &_bd.vendor,
+ sizeof(_bd.vendor));
+ memcpy(&bdesc->product, &_bd.product,
+ sizeof(_bd.product));
+ memcpy(&bdesc->revision, &_bd.revision,
+ sizeof(_bd.revision));
part_init(bdesc);
if (mode == 1) {