Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi
Pull first round of SCSI updates from James Bottomley: "This patch consists of the usual driver updates (megaraid_sas, scsi_debug, qla2xxx, qla4xxx, lpfc, bnx2fc, be2iscsi, hpsa, ipr) plus an assortment of minor fixes and the first precursors of SCSI-MQ (the code path simplifications) and the bug fix for the USB oops on remove (which involves an infrastructure change, so is sent via the main tree with a delayed backport after a cycle in which it is shown to introduce no new bugs)" * tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi: (196 commits) [SCSI] sd: Quiesce mode sense error messages [SCSI] add support for per-host cmd pools [SCSI] simplify command allocation and freeing a bit [SCSI] megaraid: simplify internal command handling [SCSI] ses: Use vpd information from scsi_device [SCSI] Add EVPD page 0x83 and 0x80 to sysfs [SCSI] Return VPD page length in scsi_vpd_inquiry() [SCSI] scsi_sysfs: Implement 'is_visible' callback [SCSI] hpsa: update driver version to 3.4.4-1 [SCSI] hpsa: fix bad endif placement in RAID 5 mapper code [SCSI] qla2xxx: Fix build errors related to invalid print fields on some architectures. [SCSI] bfa: Replace large udelay() with mdelay() [SCSI] vmw_pvscsi: Some improvements in pvscsi driver. [SCSI] vmw_pvscsi: Add support for I/O requests coalescing. [SCSI] vmw_pvscsi: Fix pvscsi_abort() function. [SCSI] remove deprecated IRQF_DISABLED from SCSI [SCSI] bfa: Updating Maintainers email ids [SCSI] ipr: Add new CCIN definition for Grand Canyon support [SCSI] ipr: Format HCAM overlay ID 0x21 [SCSI] ipr: Use pci_enable_msi_range() and pci_enable_msix_range() ...
Esse commit está contido em:
@@ -300,7 +300,9 @@ store_shost_eh_deadline(struct device *dev, struct device_attribute *attr,
|
||||
int ret = -EINVAL;
|
||||
unsigned long deadline, flags;
|
||||
|
||||
if (shost->transportt && shost->transportt->eh_strategy_handler)
|
||||
if (shost->transportt &&
|
||||
(shost->transportt->eh_strategy_handler ||
|
||||
!shost->hostt->eh_host_reset_handler))
|
||||
return ret;
|
||||
|
||||
if (!strncmp(buf, "off", strlen("off")))
|
||||
@@ -383,17 +385,14 @@ static void scsi_device_dev_release_usercontext(struct work_struct *work)
|
||||
{
|
||||
struct scsi_device *sdev;
|
||||
struct device *parent;
|
||||
struct scsi_target *starget;
|
||||
struct list_head *this, *tmp;
|
||||
unsigned long flags;
|
||||
|
||||
sdev = container_of(work, struct scsi_device, ew.work);
|
||||
|
||||
parent = sdev->sdev_gendev.parent;
|
||||
starget = to_scsi_target(parent);
|
||||
|
||||
spin_lock_irqsave(sdev->host->host_lock, flags);
|
||||
starget->reap_ref++;
|
||||
list_del(&sdev->siblings);
|
||||
list_del(&sdev->same_target_siblings);
|
||||
list_del(&sdev->starved_entry);
|
||||
@@ -413,8 +412,8 @@ static void scsi_device_dev_release_usercontext(struct work_struct *work)
|
||||
/* NULL queue means the device can't be used */
|
||||
sdev->request_queue = NULL;
|
||||
|
||||
scsi_target_reap(scsi_target(sdev));
|
||||
|
||||
kfree(sdev->vpd_pg83);
|
||||
kfree(sdev->vpd_pg80);
|
||||
kfree(sdev->inquiry);
|
||||
kfree(sdev);
|
||||
|
||||
@@ -579,7 +578,6 @@ static int scsi_sdev_check_buf_bit(const char *buf)
|
||||
* Create the actual show/store functions and data structures.
|
||||
*/
|
||||
sdev_rd_attr (device_blocked, "%d\n");
|
||||
sdev_rd_attr (queue_depth, "%d\n");
|
||||
sdev_rd_attr (device_busy, "%d\n");
|
||||
sdev_rd_attr (type, "%d\n");
|
||||
sdev_rd_attr (scsi_level, "%d\n");
|
||||
@@ -712,10 +710,64 @@ show_queue_type_field(struct device *dev, struct device_attribute *attr,
|
||||
return snprintf(buf, 20, "%s\n", name);
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(queue_type, S_IRUGO, show_queue_type_field, NULL);
|
||||
static ssize_t
|
||||
store_queue_type_field(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
struct scsi_device *sdev = to_scsi_device(dev);
|
||||
struct scsi_host_template *sht = sdev->host->hostt;
|
||||
int tag_type = 0, retval;
|
||||
int prev_tag_type = scsi_get_tag_type(sdev);
|
||||
|
||||
if (!sdev->tagged_supported || !sht->change_queue_type)
|
||||
return -EINVAL;
|
||||
|
||||
if (strncmp(buf, "ordered", 7) == 0)
|
||||
tag_type = MSG_ORDERED_TAG;
|
||||
else if (strncmp(buf, "simple", 6) == 0)
|
||||
tag_type = MSG_SIMPLE_TAG;
|
||||
else if (strncmp(buf, "none", 4) != 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (tag_type == prev_tag_type)
|
||||
return count;
|
||||
|
||||
retval = sht->change_queue_type(sdev, tag_type);
|
||||
if (retval < 0)
|
||||
return retval;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR(queue_type, S_IRUGO | S_IWUSR, show_queue_type_field,
|
||||
store_queue_type_field);
|
||||
|
||||
#define sdev_vpd_pg_attr(_page) \
|
||||
static ssize_t \
|
||||
show_vpd_##_page(struct file *filp, struct kobject *kobj, \
|
||||
struct bin_attribute *bin_attr, \
|
||||
char *buf, loff_t off, size_t count) \
|
||||
{ \
|
||||
struct device *dev = container_of(kobj, struct device, kobj); \
|
||||
struct scsi_device *sdev = to_scsi_device(dev); \
|
||||
if (!sdev->vpd_##_page) \
|
||||
return -EINVAL; \
|
||||
return memory_read_from_buffer(buf, count, &off, \
|
||||
sdev->vpd_##_page, \
|
||||
sdev->vpd_##_page##_len); \
|
||||
} \
|
||||
static struct bin_attribute dev_attr_vpd_##_page = { \
|
||||
.attr = {.name = __stringify(vpd_##_page), .mode = S_IRUGO }, \
|
||||
.size = 0, \
|
||||
.read = show_vpd_##_page, \
|
||||
};
|
||||
|
||||
sdev_vpd_pg_attr(pg83);
|
||||
sdev_vpd_pg_attr(pg80);
|
||||
|
||||
static ssize_t
|
||||
show_iostat_counterbits(struct device *dev, struct device_attribute *attr, char *buf)
|
||||
show_iostat_counterbits(struct device *dev, struct device_attribute *attr,
|
||||
char *buf)
|
||||
{
|
||||
return snprintf(buf, 20, "%d\n", (int)sizeof(atomic_t) * 8);
|
||||
}
|
||||
@@ -786,46 +838,9 @@ DECLARE_EVT(soft_threshold_reached, SOFT_THRESHOLD_REACHED_REPORTED)
|
||||
DECLARE_EVT(mode_parameter_change_reported, MODE_PARAMETER_CHANGE_REPORTED)
|
||||
DECLARE_EVT(lun_change_reported, LUN_CHANGE_REPORTED)
|
||||
|
||||
/* Default template for device attributes. May NOT be modified */
|
||||
static struct attribute *scsi_sdev_attrs[] = {
|
||||
&dev_attr_device_blocked.attr,
|
||||
&dev_attr_type.attr,
|
||||
&dev_attr_scsi_level.attr,
|
||||
&dev_attr_device_busy.attr,
|
||||
&dev_attr_vendor.attr,
|
||||
&dev_attr_model.attr,
|
||||
&dev_attr_rev.attr,
|
||||
&dev_attr_rescan.attr,
|
||||
&dev_attr_delete.attr,
|
||||
&dev_attr_state.attr,
|
||||
&dev_attr_timeout.attr,
|
||||
&dev_attr_eh_timeout.attr,
|
||||
&dev_attr_iocounterbits.attr,
|
||||
&dev_attr_iorequest_cnt.attr,
|
||||
&dev_attr_iodone_cnt.attr,
|
||||
&dev_attr_ioerr_cnt.attr,
|
||||
&dev_attr_modalias.attr,
|
||||
REF_EVT(media_change),
|
||||
REF_EVT(inquiry_change_reported),
|
||||
REF_EVT(capacity_change_reported),
|
||||
REF_EVT(soft_threshold_reached),
|
||||
REF_EVT(mode_parameter_change_reported),
|
||||
REF_EVT(lun_change_reported),
|
||||
NULL
|
||||
};
|
||||
|
||||
static struct attribute_group scsi_sdev_attr_group = {
|
||||
.attrs = scsi_sdev_attrs,
|
||||
};
|
||||
|
||||
static const struct attribute_group *scsi_sdev_attr_groups[] = {
|
||||
&scsi_sdev_attr_group,
|
||||
NULL
|
||||
};
|
||||
|
||||
static ssize_t
|
||||
sdev_store_queue_depth_rw(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
sdev_store_queue_depth(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
int depth, retval;
|
||||
struct scsi_device *sdev = to_scsi_device(dev);
|
||||
@@ -848,10 +863,10 @@ sdev_store_queue_depth_rw(struct device *dev, struct device_attribute *attr,
|
||||
|
||||
return count;
|
||||
}
|
||||
sdev_show_function(queue_depth, "%d\n");
|
||||
|
||||
static struct device_attribute sdev_attr_queue_depth_rw =
|
||||
__ATTR(queue_depth, S_IRUGO | S_IWUSR, sdev_show_queue_depth,
|
||||
sdev_store_queue_depth_rw);
|
||||
static DEVICE_ATTR(queue_depth, S_IRUGO | S_IWUSR, sdev_show_queue_depth,
|
||||
sdev_store_queue_depth);
|
||||
|
||||
static ssize_t
|
||||
sdev_show_queue_ramp_up_period(struct device *dev,
|
||||
@@ -879,40 +894,79 @@ sdev_store_queue_ramp_up_period(struct device *dev,
|
||||
return period;
|
||||
}
|
||||
|
||||
static struct device_attribute sdev_attr_queue_ramp_up_period =
|
||||
__ATTR(queue_ramp_up_period, S_IRUGO | S_IWUSR,
|
||||
sdev_show_queue_ramp_up_period,
|
||||
sdev_store_queue_ramp_up_period);
|
||||
static DEVICE_ATTR(queue_ramp_up_period, S_IRUGO | S_IWUSR,
|
||||
sdev_show_queue_ramp_up_period,
|
||||
sdev_store_queue_ramp_up_period);
|
||||
|
||||
static ssize_t
|
||||
sdev_store_queue_type_rw(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
static umode_t scsi_sdev_attr_is_visible(struct kobject *kobj,
|
||||
struct attribute *attr, int i)
|
||||
{
|
||||
struct device *dev = container_of(kobj, struct device, kobj);
|
||||
struct scsi_device *sdev = to_scsi_device(dev);
|
||||
struct scsi_host_template *sht = sdev->host->hostt;
|
||||
int tag_type = 0, retval;
|
||||
int prev_tag_type = scsi_get_tag_type(sdev);
|
||||
|
||||
if (!sdev->tagged_supported || !sht->change_queue_type)
|
||||
return -EINVAL;
|
||||
|
||||
if (strncmp(buf, "ordered", 7) == 0)
|
||||
tag_type = MSG_ORDERED_TAG;
|
||||
else if (strncmp(buf, "simple", 6) == 0)
|
||||
tag_type = MSG_SIMPLE_TAG;
|
||||
else if (strncmp(buf, "none", 4) != 0)
|
||||
return -EINVAL;
|
||||
if (attr == &dev_attr_queue_depth.attr &&
|
||||
!sdev->host->hostt->change_queue_depth)
|
||||
return S_IRUGO;
|
||||
|
||||
if (tag_type == prev_tag_type)
|
||||
return count;
|
||||
if (attr == &dev_attr_queue_ramp_up_period.attr &&
|
||||
!sdev->host->hostt->change_queue_depth)
|
||||
return 0;
|
||||
|
||||
retval = sht->change_queue_type(sdev, tag_type);
|
||||
if (retval < 0)
|
||||
return retval;
|
||||
if (attr == &dev_attr_queue_type.attr &&
|
||||
!sdev->host->hostt->change_queue_type)
|
||||
return S_IRUGO;
|
||||
|
||||
return count;
|
||||
return attr->mode;
|
||||
}
|
||||
|
||||
/* Default template for device attributes. May NOT be modified */
|
||||
static struct attribute *scsi_sdev_attrs[] = {
|
||||
&dev_attr_device_blocked.attr,
|
||||
&dev_attr_type.attr,
|
||||
&dev_attr_scsi_level.attr,
|
||||
&dev_attr_device_busy.attr,
|
||||
&dev_attr_vendor.attr,
|
||||
&dev_attr_model.attr,
|
||||
&dev_attr_rev.attr,
|
||||
&dev_attr_rescan.attr,
|
||||
&dev_attr_delete.attr,
|
||||
&dev_attr_state.attr,
|
||||
&dev_attr_timeout.attr,
|
||||
&dev_attr_eh_timeout.attr,
|
||||
&dev_attr_iocounterbits.attr,
|
||||
&dev_attr_iorequest_cnt.attr,
|
||||
&dev_attr_iodone_cnt.attr,
|
||||
&dev_attr_ioerr_cnt.attr,
|
||||
&dev_attr_modalias.attr,
|
||||
&dev_attr_queue_depth.attr,
|
||||
&dev_attr_queue_type.attr,
|
||||
&dev_attr_queue_ramp_up_period.attr,
|
||||
REF_EVT(media_change),
|
||||
REF_EVT(inquiry_change_reported),
|
||||
REF_EVT(capacity_change_reported),
|
||||
REF_EVT(soft_threshold_reached),
|
||||
REF_EVT(mode_parameter_change_reported),
|
||||
REF_EVT(lun_change_reported),
|
||||
NULL
|
||||
};
|
||||
|
||||
static struct bin_attribute *scsi_sdev_bin_attrs[] = {
|
||||
&dev_attr_vpd_pg83,
|
||||
&dev_attr_vpd_pg80,
|
||||
NULL
|
||||
};
|
||||
static struct attribute_group scsi_sdev_attr_group = {
|
||||
.attrs = scsi_sdev_attrs,
|
||||
.bin_attrs = scsi_sdev_bin_attrs,
|
||||
.is_visible = scsi_sdev_attr_is_visible,
|
||||
};
|
||||
|
||||
static const struct attribute_group *scsi_sdev_attr_groups[] = {
|
||||
&scsi_sdev_attr_group,
|
||||
NULL
|
||||
};
|
||||
|
||||
static int scsi_target_add(struct scsi_target *starget)
|
||||
{
|
||||
int error;
|
||||
@@ -935,10 +989,6 @@ static int scsi_target_add(struct scsi_target *starget)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct device_attribute sdev_attr_queue_type_rw =
|
||||
__ATTR(queue_type, S_IRUGO | S_IWUSR, show_queue_type_field,
|
||||
sdev_store_queue_type_rw);
|
||||
|
||||
/**
|
||||
* scsi_sysfs_add_sdev - add scsi device to sysfs
|
||||
* @sdev: scsi_device to add
|
||||
@@ -992,25 +1042,6 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev)
|
||||
transport_add_device(&sdev->sdev_gendev);
|
||||
sdev->is_visible = 1;
|
||||
|
||||
/* create queue files, which may be writable, depending on the host */
|
||||
if (sdev->host->hostt->change_queue_depth) {
|
||||
error = device_create_file(&sdev->sdev_gendev,
|
||||
&sdev_attr_queue_depth_rw);
|
||||
error = device_create_file(&sdev->sdev_gendev,
|
||||
&sdev_attr_queue_ramp_up_period);
|
||||
}
|
||||
else
|
||||
error = device_create_file(&sdev->sdev_gendev, &dev_attr_queue_depth);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
if (sdev->host->hostt->change_queue_type)
|
||||
error = device_create_file(&sdev->sdev_gendev, &sdev_attr_queue_type_rw);
|
||||
else
|
||||
error = device_create_file(&sdev->sdev_gendev, &dev_attr_queue_type);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
error = bsg_register_queue(rq, &sdev->sdev_gendev, NULL, NULL);
|
||||
|
||||
if (error)
|
||||
@@ -1060,6 +1091,13 @@ void __scsi_remove_device(struct scsi_device *sdev)
|
||||
sdev->host->hostt->slave_destroy(sdev);
|
||||
transport_destroy_device(dev);
|
||||
|
||||
/*
|
||||
* Paired with the kref_get() in scsi_sysfs_initialize(). We have
|
||||
* remoed sysfs visibility from the device, so make the target
|
||||
* invisible if this was the last device underneath it.
|
||||
*/
|
||||
scsi_target_reap(scsi_target(sdev));
|
||||
|
||||
put_device(dev);
|
||||
}
|
||||
|
||||
@@ -1122,7 +1160,7 @@ void scsi_remove_target(struct device *dev)
|
||||
continue;
|
||||
if (starget->dev.parent == dev || &starget->dev == dev) {
|
||||
/* assuming new targets arrive at the end */
|
||||
starget->reap_ref++;
|
||||
kref_get(&starget->reap_ref);
|
||||
spin_unlock_irqrestore(shost->host_lock, flags);
|
||||
if (last)
|
||||
scsi_target_reap(last);
|
||||
@@ -1206,6 +1244,12 @@ void scsi_sysfs_device_initialize(struct scsi_device *sdev)
|
||||
list_add_tail(&sdev->same_target_siblings, &starget->devices);
|
||||
list_add_tail(&sdev->siblings, &shost->__devices);
|
||||
spin_unlock_irqrestore(shost->host_lock, flags);
|
||||
/*
|
||||
* device can now only be removed via __scsi_remove_device() so hold
|
||||
* the target. Target will be held in CREATED state until something
|
||||
* beneath it becomes visible (in which case it moves to RUNNING)
|
||||
*/
|
||||
kref_get(&starget->reap_ref);
|
||||
}
|
||||
|
||||
int scsi_is_sdev_device(const struct device *dev)
|
||||
|
Referência em uma nova issue
Block a user