[SCSI] libsas,libata: fix ->change_queue_{depth|type} for sata devices
Pass queue_depth change requests to libata, and prevent queue_type changes for ATA devices. Otherwise: 1/ we do not honor the libata specific restrictions on the queue depth 2/ libsas drivers that do not set sdev->tagged_supported are unable to change the queue_depth of ata devices via sysfs Signed-off-by: Dan Williams <dan.j.williams@intel.com> Acked-by: Jeff Garzik <jgarzik@redhat.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
This commit is contained in:
parent
2fc62e2ac3
commit
f6e67035a9
|
@ -6713,6 +6713,7 @@ EXPORT_SYMBOL_GPL(ata_scsi_queuecmd);
|
||||||
EXPORT_SYMBOL_GPL(ata_scsi_slave_config);
|
EXPORT_SYMBOL_GPL(ata_scsi_slave_config);
|
||||||
EXPORT_SYMBOL_GPL(ata_scsi_slave_destroy);
|
EXPORT_SYMBOL_GPL(ata_scsi_slave_destroy);
|
||||||
EXPORT_SYMBOL_GPL(ata_scsi_change_queue_depth);
|
EXPORT_SYMBOL_GPL(ata_scsi_change_queue_depth);
|
||||||
|
EXPORT_SYMBOL_GPL(__ata_change_queue_depth);
|
||||||
EXPORT_SYMBOL_GPL(sata_scr_valid);
|
EXPORT_SYMBOL_GPL(sata_scr_valid);
|
||||||
EXPORT_SYMBOL_GPL(sata_scr_read);
|
EXPORT_SYMBOL_GPL(sata_scr_read);
|
||||||
EXPORT_SYMBOL_GPL(sata_scr_write);
|
EXPORT_SYMBOL_GPL(sata_scr_write);
|
||||||
|
|
|
@ -1215,25 +1215,15 @@ void ata_scsi_slave_destroy(struct scsi_device *sdev)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ata_scsi_change_queue_depth - SCSI callback for queue depth config
|
* __ata_change_queue_depth - helper for ata_scsi_change_queue_depth
|
||||||
* @sdev: SCSI device to configure queue depth for
|
|
||||||
* @queue_depth: new queue depth
|
|
||||||
* @reason: calling context
|
|
||||||
*
|
*
|
||||||
* This is libata standard hostt->change_queue_depth callback.
|
* libsas and libata have different approaches for associating a sdev to
|
||||||
* SCSI will call into this callback when user tries to set queue
|
* its ata_port.
|
||||||
* depth via sysfs.
|
|
||||||
*
|
*
|
||||||
* LOCKING:
|
|
||||||
* SCSI layer (we don't care)
|
|
||||||
*
|
|
||||||
* RETURNS:
|
|
||||||
* Newly configured queue depth.
|
|
||||||
*/
|
*/
|
||||||
int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth,
|
int __ata_change_queue_depth(struct ata_port *ap, struct scsi_device *sdev,
|
||||||
int reason)
|
int queue_depth, int reason)
|
||||||
{
|
{
|
||||||
struct ata_port *ap = ata_shost_to_port(sdev->host);
|
|
||||||
struct ata_device *dev;
|
struct ata_device *dev;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
|
@ -1268,6 +1258,30 @@ int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth,
|
||||||
return queue_depth;
|
return queue_depth;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ata_scsi_change_queue_depth - SCSI callback for queue depth config
|
||||||
|
* @sdev: SCSI device to configure queue depth for
|
||||||
|
* @queue_depth: new queue depth
|
||||||
|
* @reason: calling context
|
||||||
|
*
|
||||||
|
* This is libata standard hostt->change_queue_depth callback.
|
||||||
|
* SCSI will call into this callback when user tries to set queue
|
||||||
|
* depth via sysfs.
|
||||||
|
*
|
||||||
|
* LOCKING:
|
||||||
|
* SCSI layer (we don't care)
|
||||||
|
*
|
||||||
|
* RETURNS:
|
||||||
|
* Newly configured queue depth.
|
||||||
|
*/
|
||||||
|
int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth,
|
||||||
|
int reason)
|
||||||
|
{
|
||||||
|
struct ata_port *ap = ata_shost_to_port(sdev->host);
|
||||||
|
|
||||||
|
return __ata_change_queue_depth(ap, sdev, queue_depth, reason);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ata_scsi_start_stop_xlat - Translate SCSI START STOP UNIT command
|
* ata_scsi_start_stop_xlat - Translate SCSI START STOP UNIT command
|
||||||
* @qc: Storage for translated ATA taskfile
|
* @qc: Storage for translated ATA taskfile
|
||||||
|
|
|
@ -808,8 +808,13 @@ void sas_slave_destroy(struct scsi_device *scsi_dev)
|
||||||
int sas_change_queue_depth(struct scsi_device *scsi_dev, int new_depth,
|
int sas_change_queue_depth(struct scsi_device *scsi_dev, int new_depth,
|
||||||
int reason)
|
int reason)
|
||||||
{
|
{
|
||||||
|
struct domain_device *dev = sdev_to_domain_dev(scsi_dev);
|
||||||
int res = min(new_depth, SAS_MAX_QD);
|
int res = min(new_depth, SAS_MAX_QD);
|
||||||
|
|
||||||
|
if (dev_is_sata(dev))
|
||||||
|
return __ata_change_queue_depth(dev->sata_dev.ap, scsi_dev,
|
||||||
|
new_depth, reason);
|
||||||
|
|
||||||
if (reason != SCSI_QDEPTH_DEFAULT)
|
if (reason != SCSI_QDEPTH_DEFAULT)
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
|
|
||||||
|
@ -817,7 +822,6 @@ int sas_change_queue_depth(struct scsi_device *scsi_dev, int new_depth,
|
||||||
scsi_adjust_queue_depth(scsi_dev, scsi_get_tag_type(scsi_dev),
|
scsi_adjust_queue_depth(scsi_dev, scsi_get_tag_type(scsi_dev),
|
||||||
res);
|
res);
|
||||||
else {
|
else {
|
||||||
struct domain_device *dev = sdev_to_domain_dev(scsi_dev);
|
|
||||||
sas_printk("device %llx LUN %x queue depth changed to 1\n",
|
sas_printk("device %llx LUN %x queue depth changed to 1\n",
|
||||||
SAS_ADDR(dev->sas_addr),
|
SAS_ADDR(dev->sas_addr),
|
||||||
scsi_dev->lun);
|
scsi_dev->lun);
|
||||||
|
@ -830,6 +834,11 @@ int sas_change_queue_depth(struct scsi_device *scsi_dev, int new_depth,
|
||||||
|
|
||||||
int sas_change_queue_type(struct scsi_device *scsi_dev, int qt)
|
int sas_change_queue_type(struct scsi_device *scsi_dev, int qt)
|
||||||
{
|
{
|
||||||
|
struct domain_device *dev = sdev_to_domain_dev(scsi_dev);
|
||||||
|
|
||||||
|
if (dev_is_sata(dev))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
if (!scsi_dev->tagged_supported)
|
if (!scsi_dev->tagged_supported)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
|
@ -1052,6 +1052,8 @@ extern int ata_scsi_slave_config(struct scsi_device *sdev);
|
||||||
extern void ata_scsi_slave_destroy(struct scsi_device *sdev);
|
extern void ata_scsi_slave_destroy(struct scsi_device *sdev);
|
||||||
extern int ata_scsi_change_queue_depth(struct scsi_device *sdev,
|
extern int ata_scsi_change_queue_depth(struct scsi_device *sdev,
|
||||||
int queue_depth, int reason);
|
int queue_depth, int reason);
|
||||||
|
extern int __ata_change_queue_depth(struct ata_port *ap, struct scsi_device *sdev,
|
||||||
|
int queue_depth, int reason);
|
||||||
extern struct ata_device *ata_dev_pair(struct ata_device *adev);
|
extern struct ata_device *ata_dev_pair(struct ata_device *adev);
|
||||||
extern int ata_do_set_mode(struct ata_link *link, struct ata_device **r_failed_dev);
|
extern int ata_do_set_mode(struct ata_link *link, struct ata_device **r_failed_dev);
|
||||||
extern void ata_scsi_port_error_handler(struct Scsi_Host *host, struct ata_port *ap);
|
extern void ata_scsi_port_error_handler(struct Scsi_Host *host, struct ata_port *ap);
|
||||||
|
|
Loading…
Reference in New Issue