scsi: Extract device detection algorithm
authorMichal Simek <michal.simek@xilinx.com>
Fri, 18 Nov 2016 14:42:13 +0000 (15:42 +0100)
committerMichal Simek <michal.simek@xilinx.com>
Fri, 2 Dec 2016 13:37:16 +0000 (14:37 +0100)
The patch enables running detection algorithm on block device
description structure.

Signed-off-by: Michal Simek <michal.simek@xilinx.com>
Reviewed-by: Simon Glass <sjg@chromium.org>
common/scsi.c

index 0bce91d..89926e7 100644 (file)
@@ -480,15 +480,88 @@ static void scsi_init_dev_desc(struct blk_desc *dev_desc, int devnum)
 #endif
 }
 
+/**
+ * scsi_detect_dev - Detect scsi device
+ *
+ * @pccb: pointer to temporary SCSI command block
+ * @dev_desc: block device description
+ * @lun: Logical unit number
+ *
+ * The scsi_detect_dev detects and fills a dev_desc structure when the device is
+ * detected.
+ *
+ * Return: 0 on success, error value otherwise
+ */
+static int scsi_detect_dev(ccb *pccb, struct blk_desc *dev_desc, int lun)
+{
+       unsigned char perq, modi;
+       lbaint_t capacity;
+       unsigned long blksz;
+
+       pccb->lun = lun;
+       pccb->pdata = (unsigned char *)&tempbuff;
+       pccb->datalen = 512;
+       scsi_setup_inquiry(pccb);
+       if (scsi_exec(pccb) != true) {
+               if (pccb->contr_stat == SCSI_SEL_TIME_OUT) {
+                       /*
+                         * selection timeout => assuming no
+                         * device present
+                         */
+                       debug("Selection timeout ID %d\n",
+                             pccb->target);
+                       return -ETIMEDOUT;
+               }
+               scsi_print_error(pccb);
+               return -ENODEV;
+       }
+       perq = tempbuff[0];
+       modi = tempbuff[1];
+       if ((perq & 0x1f) == 0x1f)
+               return -ENODEV; /* skip unknown devices */
+       if ((modi & 0x80) == 0x80) /* drive is removable */
+               dev_desc->removable = true;
+       /* get info for this device */
+       scsi_ident_cpy((unsigned char *)dev_desc->vendor,
+                      &tempbuff[8], 8);
+       scsi_ident_cpy((unsigned char *)dev_desc->product,
+                      &tempbuff[16], 16);
+       scsi_ident_cpy((unsigned char *)dev_desc->revision,
+                      &tempbuff[32], 4);
+       dev_desc->target = pccb->target;
+       dev_desc->lun = pccb->lun;
+
+       pccb->datalen = 0;
+       scsi_setup_test_unit_ready(pccb);
+       if (scsi_exec(pccb) != true) {
+               if (dev_desc->removable) {
+                       dev_desc->type = perq;
+                       goto removable;
+               }
+               scsi_print_error(pccb);
+               return -EINVAL;
+       }
+       if (scsi_read_capacity(pccb, &capacity, &blksz)) {
+               scsi_print_error(pccb);
+               return -EINVAL;
+       }
+       dev_desc->lba = capacity;
+       dev_desc->blksz = blksz;
+       dev_desc->log2blksz = LOG2(dev_desc->blksz);
+       dev_desc->type = perq;
+       part_init(&dev_desc[0]);
+removable:
+       return 0;
+}
+
 /*
  * (re)-scan the scsi bus and reports scsi device info
  * to the user if mode = 1
  */
 void scsi_scan(int mode)
 {
-       unsigned char i, perq, modi, lun;
-       lbaint_t capacity;
-       unsigned long blksz;
+       unsigned char i, lun;
+       int ret;
        ccb *pccb = (ccb *)&tempccb;
 
        if (mode == 1)
@@ -500,66 +573,14 @@ void scsi_scan(int mode)
        for (i = 0; i < CONFIG_SYS_SCSI_MAX_SCSI_ID; i++) {
                pccb->target = i;
                for (lun = 0; lun < CONFIG_SYS_SCSI_MAX_LUN; lun++) {
-                       pccb->lun = lun;
-                       pccb->pdata = (unsigned char *)&tempbuff;
-                       pccb->datalen = 512;
-                       scsi_setup_inquiry(pccb);
-                       if (scsi_exec(pccb) != true) {
-                               if (pccb->contr_stat == SCSI_SEL_TIME_OUT) {
-                                       /*
-                                        * selection timeout => assuming no
-                                        * device present
-                                        */
-                                       debug("Selection timeout ID %d\n",
-                                             pccb->target);
-                                       continue;
-                               }
-                               scsi_print_error(pccb);
-                               continue;
-                       }
-                       perq = tempbuff[0];
-                       modi = tempbuff[1];
-                       if ((perq & 0x1f) == 0x1f)
-                               continue; /* skip unknown devices */
-                       if ((modi & 0x80) == 0x80) /* drive is removable */
-                               scsi_dev_desc[scsi_max_devs].removable = true;
-                       /* get info for this device */
-                       scsi_ident_cpy((unsigned char *)&scsi_dev_desc
-                                               [scsi_max_devs].vendor[0],
-                                      &tempbuff[8], 8);
-                       scsi_ident_cpy((unsigned char *)&scsi_dev_desc
-                                               [scsi_max_devs].product[0],
-                                      &tempbuff[16], 16);
-                       scsi_ident_cpy((unsigned char *)&scsi_dev_desc
-                                               [scsi_max_devs].revision[0],
-                                      &tempbuff[32], 4);
-                       scsi_dev_desc[scsi_max_devs].target = pccb->target;
-                       scsi_dev_desc[scsi_max_devs].lun = pccb->lun;
-
-                       pccb->datalen = 0;
-                       scsi_setup_test_unit_ready(pccb);
-                       if (scsi_exec(pccb) != true) {
-                               if (scsi_dev_desc[scsi_max_devs].removable) {
-                                       scsi_dev_desc[scsi_max_devs].type =
-                                                       perq;
-                                       goto removable;
-                               }
-                               scsi_print_error(pccb);
-                               continue;
-                       }
-                       if (scsi_read_capacity(pccb, &capacity, &blksz)) {
-                               scsi_print_error(pccb);
+                       ret = scsi_detect_dev(pccb,
+                                             &scsi_dev_desc[scsi_max_devs],
+                                             lun);
+                       if (ret)
                                continue;
-                       }
-                       scsi_dev_desc[scsi_max_devs].lba = capacity;
-                       scsi_dev_desc[scsi_max_devs].blksz = blksz;
-                       scsi_dev_desc[scsi_max_devs].log2blksz =
-                               LOG2(scsi_dev_desc[scsi_max_devs].blksz);
-                       scsi_dev_desc[scsi_max_devs].type = perq;
-                       part_init(&scsi_dev_desc[scsi_max_devs]);
-removable:
+
                        if (mode == 1) {
-                               printf("  Device %d: ", scsi_max_devs);
+                               printf("  Device %d: ", 0);
                                dev_print(&scsi_dev_desc[scsi_max_devs]);
                        } /* if mode */
                        scsi_max_devs++;