diff options
author | Jean-Jacques Hiblot <jjhiblot@ti.com> | 2017-04-07 13:42:08 +0200 |
---|---|---|
committer | Simon Glass <sjg@chromium.org> | 2017-04-14 19:38:57 -0600 |
commit | 4e27b9a5845e9c061b315b7ca301eff982d6898f (patch) | |
tree | 787b5d8751c4b3ec557672177760383e6bb11646 | |
parent | 1330a726ff0c8164cf6035ab4a6d1e31805f69d1 (diff) |
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>
-rw-r--r-- | common/scsi.c | 35 |
1 files changed, 26 insertions, 9 deletions
diff --git a/common/scsi.c b/common/scsi.c index 972ef338be..d37222cc6b 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) { |