|
@@ -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++;
|