Better handling of devices, which don't support MODE SENSE control mode page
authorvlnb <vlnb@d57e44dd-8a1f-0410-8b47-8ef2f437770f>
Fri, 18 Dec 2009 17:21:27 +0000 (17:21 +0000)
committervlnb <vlnb@d57e44dd-8a1f-0410-8b47-8ef2f437770f>
Fri, 18 Dec 2009 17:21:27 +0000 (17:21 +0000)
Tested-By: Dietmar Maurer <dietmar@proxmox.com>
git-svn-id: https://scst.svn.sourceforge.net/svnroot/scst/trunk@1408 d57e44dd-8a1f-0410-8b47-8ef2f437770f

scst/src/scst_lib.c

index 3e9527e..e2f6c14 100644 (file)
@@ -3983,7 +3983,7 @@ EXPORT_SYMBOL(scst_to_tgt_dma_dir);
 
 int scst_obtain_device_parameters(struct scst_device *dev)
 {
 
 int scst_obtain_device_parameters(struct scst_device *dev)
 {
-       int res = 0, i;
+       int rc, i;
        uint8_t cmd[16];
        uint8_t buffer[4+0x0A];
        uint8_t sense_buffer[SCSI_SENSE_BUFFERSIZE];
        uint8_t cmd[16];
        uint8_t buffer[4+0x0A];
        uint8_t sense_buffer[SCSI_SENSE_BUFFERSIZE];
@@ -4011,16 +4011,16 @@ int scst_obtain_device_parameters(struct scst_device *dev)
                memset(sense_buffer, 0, sizeof(sense_buffer));
 
                TRACE(TRACE_SCSI, "%s", "Doing internal MODE_SENSE");
                memset(sense_buffer, 0, sizeof(sense_buffer));
 
                TRACE(TRACE_SCSI, "%s", "Doing internal MODE_SENSE");
-               res = scsi_execute(dev->scsi_dev, cmd, SCST_DATA_READ, buffer,
+               rc = scsi_execute(dev->scsi_dev, cmd, SCST_DATA_READ, buffer,
                                sizeof(buffer), sense_buffer, 15, 0, 0
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)
                                , NULL
 #endif
                                );
 
                                sizeof(buffer), sense_buffer, 15, 0, 0
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,29)
                                , NULL
 #endif
                                );
 
-               TRACE_DBG("MODE_SENSE done: %x", res);
+               TRACE_DBG("MODE_SENSE done: %x", rc);
 
 
-               if (scsi_status_is_good(res)) {
+               if (scsi_status_is_good(rc)) {
                        int q;
 
                        PRINT_BUFF_FLAG(TRACE_SCSI,
                        int q;
 
                        PRINT_BUFF_FLAG(TRACE_SCSI,
@@ -4041,22 +4041,23 @@ int scst_obtain_device_parameters(struct scst_device *dev)
                        /*
                         * Unfortunately, SCSI ML doesn't provide a way to
                         * specify commands task attribute, so we can rely on
                        /*
                         * Unfortunately, SCSI ML doesn't provide a way to
                         * specify commands task attribute, so we can rely on
-                        * device's restricted reordering only.
+                        * device's restricted reordering only. Linux I/O
+                        * subsystem doesn't reorder pass-through (PC) requests.
                         */
                        dev->has_own_order_mgmt = !dev->queue_alg;
 
                         */
                        dev->has_own_order_mgmt = !dev->queue_alg;
 
-                       TRACE(TRACE_SCSI|TRACE_MGMT_MINOR,
-                               "Device %s: TST %x, "
-                               "QUEUE ALG %x, SWP %x, TAS %x, D_SENSE %d"
-                               "has_own_order_mgmt %d",
+                       PRINT_INFO("Device %s: TST %x, QUEUE ALG %x, SWP %x, "
+                               "TAS %x, D_SENSE %d, has_own_order_mgmt %d",
                                dev->virt_name, dev->tst, dev->queue_alg,
                                dev->swp, dev->tas, dev->d_sense,
                                dev->has_own_order_mgmt);
 
                        goto out;
                } else {
                                dev->virt_name, dev->tst, dev->queue_alg,
                                dev->swp, dev->tas, dev->d_sense,
                                dev->has_own_order_mgmt);
 
                        goto out;
                } else {
+                       scst_check_internal_sense(dev, rc, sense_buffer,
+                               sizeof(sense_buffer));
 #if 0
 #if 0
-                       if ((status_byte(res) == CHECK_CONDITION) &&
+                       if ((status_byte(rc) == CHECK_CONDITION) &&
                            SCST_SENSE_VALID(sense_buffer)) {
 #else
                        /*
                            SCST_SENSE_VALID(sense_buffer)) {
 #else
                        /*
@@ -4065,51 +4066,58 @@ int scst_obtain_device_parameters(struct scst_device *dev)
                         */
                        if (SCST_SENSE_VALID(sense_buffer)) {
 #endif
                         */
                        if (SCST_SENSE_VALID(sense_buffer)) {
 #endif
+                               PRINT_BUFF_FLAG(TRACE_SCSI,
+                                       "Returned sense data",
+                                       sense_buffer, sizeof(sense_buffer));
                                if (scst_analyze_sense(sense_buffer,
                                                sizeof(sense_buffer),
                                                SCST_SENSE_KEY_VALID,
                                                ILLEGAL_REQUEST, 0, 0)) {
                                if (scst_analyze_sense(sense_buffer,
                                                sizeof(sense_buffer),
                                                SCST_SENSE_KEY_VALID,
                                                ILLEGAL_REQUEST, 0, 0)) {
-                                       TRACE(TRACE_SCSI|TRACE_MGMT_MINOR,
-                                               "Device %s doesn't "
-                                               "support control mode page, "
-                                               "using defaults: TST %x, "
-                                               "QUEUE ALG %x, SWP %x, "
-                                               "TAS %x, D_SENSE %d, "
-                                               "has_own_order_mgmt %d ",
-                                               dev->virt_name,
-                                               dev->tst, dev->queue_alg,
-                                               dev->swp, dev->tas,
-                                               dev->d_sense,
-                                               dev->has_own_order_mgmt);
-                                       res = 0;
-                                       goto out;
+                                       PRINT_INFO("Device %s doesn't support "
+                                               "MODE SENSE", dev->virt_name);
+                                       break;
                                } else if (scst_analyze_sense(sense_buffer,
                                                sizeof(sense_buffer),
                                                SCST_SENSE_KEY_VALID,
                                                NOT_READY, 0, 0)) {
                                } else if (scst_analyze_sense(sense_buffer,
                                                sizeof(sense_buffer),
                                                SCST_SENSE_KEY_VALID,
                                                NOT_READY, 0, 0)) {
-                                       TRACE(TRACE_SCSI, "Device %s not ready",
+                                       PRINT_ERROR("Device %s not ready",
                                                dev->virt_name);
                                                dev->virt_name);
-                                       res = 0;
-                                       goto out;
+                                       break;
                                }
                        } else {
                                }
                        } else {
-                               TRACE(TRACE_SCSI|TRACE_MGMT_MINOR,
-                                       "Internal MODE SENSE to "
+                               PRINT_INFO("Internal MODE SENSE to "
                                        "device %s failed: %x",
                                        "device %s failed: %x",
-                                       dev->virt_name, res);
-                               PRINT_BUFF_FLAG(TRACE_SCSI|TRACE_MGMT_MINOR,
-                                       "MODE SENSE sense",
+                                       dev->virt_name, rc);
+                               PRINT_BUFF_FLAG(TRACE_SCSI, "MODE SENSE sense",
                                        sense_buffer, sizeof(sense_buffer));
                                        sense_buffer, sizeof(sense_buffer));
+                               switch (host_byte(rc)) {
+                               case DID_RESET:
+                               case DID_ABORT:
+                               case DID_SOFT_ERROR:
+                                       break;
+                               default:
+                                       goto brk;
+                               }
+                               switch (driver_byte(rc)) {
+                               case DRIVER_BUSY:
+                               case DRIVER_SOFT:
+                                       break;
+                               default:
+                                       goto brk;
+                               }
                        }
                        }
-                       scst_check_internal_sense(dev, res, sense_buffer,
-                                       sizeof(sense_buffer));
                }
        }
                }
        }
-       res = -ENODEV;
+brk:
+       PRINT_WARNING("Unable to get device's %s control mode page, using "
+               "existing values/defaults: TST %x, QUEUE ALG %x, SWP %x, "
+               "TAS %x, D_SENSE %d, has_own_order_mgmt %d", dev->virt_name,
+               dev->tst, dev->queue_alg, dev->swp, dev->tas, dev->d_sense,
+               dev->has_own_order_mgmt);
 
 out:
 
 out:
-       TRACE_EXIT_RES(res);
-       return res;
+       TRACE_EXIT();
+       return 0;
 }
 EXPORT_SYMBOL(scst_obtain_device_parameters);
 
 }
 EXPORT_SYMBOL(scst_obtain_device_parameters);