]> git.ipfire.org Git - people/ms/u-boot.git/commitdiff
dm: scsi: fix divide-by-0 error in scsi_scan()
authorJean-Jacques Hiblot <jjhiblot@ti.com>
Fri, 7 Apr 2017 11:42:08 +0000 (13:42 +0200)
committerSimon Glass <sjg@chromium.org>
Sat, 15 Apr 2017 01:38:57 +0000 (19:38 -0600)
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>
common/scsi.c

index 972ef338be639712caf642fa65786e377b23f88b..d37222cc6b802ceb119b1e60aa78138ff05e451e 100644 (file)
@@ -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) {