@@ -345,6 +345,37 @@ store_shost_eh_deadline(struct device *dev, struct device_attribute *attr,
static DEVICE_ATTR(eh_deadline, S_IRUGO | S_IWUSR, show_shost_eh_deadline, store_shost_eh_deadline);
+static ssize_t
+store_shost_blocked(struct device *dev, struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ int err;
+ bool blocked;
+ struct Scsi_Host *shost = class_to_shost(dev);
+
+ err = kstrtobool(buf, &blocked);
+ if (err)
+ return err;
+
+ if (shost->host_blockio != blocked) {
+ shost->host_blockio = blocked;
+ if (!blocked)
+ scsi_run_host_queues(shost);
+ }
+
+ return count;
+}
+
+static ssize_t
+show_shost_blocked(struct device *dev, struct device_attribute *attr, char *buf)
+{
+ struct Scsi_Host *shost = class_to_shost(dev);
+
+ return snprintf(buf, 20, "%d\n", shost->host_blockio);
+}
+static DEVICE_ATTR(blocked, S_IRUGO | S_IWUSR,
+ show_shost_blocked, store_shost_blocked);
+
shost_rd_attr(unique_id, "%u\n");
shost_rd_attr(cmd_per_lun, "%hd\n");
shost_rd_attr(can_queue, "%d\n");
@@ -397,6 +428,7 @@ static struct attribute *scsi_sysfs_shost_attrs[] = {
&dev_attr_host_reset.attr,
&dev_attr_eh_deadline.attr,
&dev_attr_nr_hw_queues.attr,
+ &dev_attr_blocked.attr,
NULL
};
@@ -659,6 +659,9 @@ struct Scsi_Host {
/* The transport requires the LUN bits NOT to be stored in CDB[1] */
unsigned no_scsi2_lun_in_cdb:1;
+ /* True host will blocking IO */
+ unsigned host_blockio:1;
+
/*
* Optional work queue to be utilized by the transport
*/