diff options
author | Dan Williams <dan.j.williams@intel.com> | 2011-09-20 18:10:33 -0400 |
---|---|---|
committer | James Bottomley <JBottomley@Parallels.com> | 2011-10-02 13:30:30 -0400 |
commit | f6e67035a9edd79b8b202c159d5bec560bb9c358 (patch) | |
tree | ba884b5a2de7cb60bd1e6f67813b47fdb8ff509a | |
parent | 2fc62e2ac350b8f574e0a09170b350a8f2fa4a02 (diff) |
[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>
-rw-r--r-- | drivers/ata/libata-core.c | 1 | ||||
-rw-r--r-- | drivers/ata/libata-scsi.c | 44 | ||||
-rw-r--r-- | drivers/scsi/libsas/sas_scsi_host.c | 11 | ||||
-rw-r--r-- | include/linux/libata.h | 2 |
4 files changed, 42 insertions, 16 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 4a3a5ae7bb45..d26c7f4c887b 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -6713,6 +6713,7 @@ EXPORT_SYMBOL_GPL(ata_scsi_queuecmd); | |||
6713 | EXPORT_SYMBOL_GPL(ata_scsi_slave_config); | 6713 | EXPORT_SYMBOL_GPL(ata_scsi_slave_config); |
6714 | EXPORT_SYMBOL_GPL(ata_scsi_slave_destroy); | 6714 | EXPORT_SYMBOL_GPL(ata_scsi_slave_destroy); |
6715 | EXPORT_SYMBOL_GPL(ata_scsi_change_queue_depth); | 6715 | EXPORT_SYMBOL_GPL(ata_scsi_change_queue_depth); |
6716 | EXPORT_SYMBOL_GPL(__ata_change_queue_depth); | ||
6716 | EXPORT_SYMBOL_GPL(sata_scr_valid); | 6717 | EXPORT_SYMBOL_GPL(sata_scr_valid); |
6717 | EXPORT_SYMBOL_GPL(sata_scr_read); | 6718 | EXPORT_SYMBOL_GPL(sata_scr_read); |
6718 | EXPORT_SYMBOL_GPL(sata_scr_write); | 6719 | EXPORT_SYMBOL_GPL(sata_scr_write); |
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c index 46d087f08607..19ba77032ac2 100644 --- a/drivers/ata/libata-scsi.c +++ b/drivers/ata/libata-scsi.c | |||
@@ -1215,25 +1215,15 @@ void ata_scsi_slave_destroy(struct scsi_device *sdev) | |||
1215 | } | 1215 | } |
1216 | 1216 | ||
1217 | /** | 1217 | /** |
1218 | * ata_scsi_change_queue_depth - SCSI callback for queue depth config | 1218 | * __ata_change_queue_depth - helper for ata_scsi_change_queue_depth |
1219 | * @sdev: SCSI device to configure queue depth for | ||
1220 | * @queue_depth: new queue depth | ||
1221 | * @reason: calling context | ||
1222 | * | ||
1223 | * This is libata standard hostt->change_queue_depth callback. | ||
1224 | * SCSI will call into this callback when user tries to set queue | ||
1225 | * depth via sysfs. | ||
1226 | * | 1219 | * |
1227 | * LOCKING: | 1220 | * libsas and libata have different approaches for associating a sdev to |
1228 | * SCSI layer (we don't care) | 1221 | * its ata_port. |
1229 | * | 1222 | * |
1230 | * RETURNS: | ||
1231 | * Newly configured queue depth. | ||
1232 | */ | 1223 | */ |
1233 | int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth, | 1224 | int __ata_change_queue_depth(struct ata_port *ap, struct scsi_device *sdev, |
1234 | int reason) | 1225 | int queue_depth, int reason) |
1235 | { | 1226 | { |
1236 | struct ata_port *ap = ata_shost_to_port(sdev->host); | ||
1237 | struct ata_device *dev; | 1227 | struct ata_device *dev; |
1238 | unsigned long flags; | 1228 | unsigned long flags; |
1239 | 1229 | ||
@@ -1269,6 +1259,30 @@ int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth, | |||
1269 | } | 1259 | } |
1270 | 1260 | ||
1271 | /** | 1261 | /** |
1262 | * ata_scsi_change_queue_depth - SCSI callback for queue depth config | ||
1263 | * @sdev: SCSI device to configure queue depth for | ||
1264 | * @queue_depth: new queue depth | ||
1265 | * @reason: calling context | ||
1266 | * | ||
1267 | * This is libata standard hostt->change_queue_depth callback. | ||
1268 | * SCSI will call into this callback when user tries to set queue | ||
1269 | * depth via sysfs. | ||
1270 | * | ||
1271 | * LOCKING: | ||
1272 | * SCSI layer (we don't care) | ||
1273 | * | ||
1274 | * RETURNS: | ||
1275 | * Newly configured queue depth. | ||
1276 | */ | ||
1277 | int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth, | ||
1278 | int reason) | ||
1279 | { | ||
1280 | struct ata_port *ap = ata_shost_to_port(sdev->host); | ||
1281 | |||
1282 | return __ata_change_queue_depth(ap, sdev, queue_depth, reason); | ||
1283 | } | ||
1284 | |||
1285 | /** | ||
1272 | * ata_scsi_start_stop_xlat - Translate SCSI START STOP UNIT command | 1286 | * ata_scsi_start_stop_xlat - Translate SCSI START STOP UNIT command |
1273 | * @qc: Storage for translated ATA taskfile | 1287 | * @qc: Storage for translated ATA taskfile |
1274 | * | 1288 | * |
diff --git a/drivers/scsi/libsas/sas_scsi_host.c b/drivers/scsi/libsas/sas_scsi_host.c index d625577ed152..8f3c4cc1bfe4 100644 --- a/drivers/scsi/libsas/sas_scsi_host.c +++ b/drivers/scsi/libsas/sas_scsi_host.c | |||
@@ -808,8 +808,13 @@ void sas_slave_destroy(struct scsi_device *scsi_dev) | |||
808 | int sas_change_queue_depth(struct scsi_device *scsi_dev, int new_depth, | 808 | int sas_change_queue_depth(struct scsi_device *scsi_dev, int new_depth, |
809 | int reason) | 809 | int reason) |
810 | { | 810 | { |
811 | struct domain_device *dev = sdev_to_domain_dev(scsi_dev); | ||
811 | int res = min(new_depth, SAS_MAX_QD); | 812 | int res = min(new_depth, SAS_MAX_QD); |
812 | 813 | ||
814 | if (dev_is_sata(dev)) | ||
815 | return __ata_change_queue_depth(dev->sata_dev.ap, scsi_dev, | ||
816 | new_depth, reason); | ||
817 | |||
813 | if (reason != SCSI_QDEPTH_DEFAULT) | 818 | if (reason != SCSI_QDEPTH_DEFAULT) |
814 | return -EOPNOTSUPP; | 819 | return -EOPNOTSUPP; |
815 | 820 | ||
@@ -817,7 +822,6 @@ int sas_change_queue_depth(struct scsi_device *scsi_dev, int new_depth, | |||
817 | scsi_adjust_queue_depth(scsi_dev, scsi_get_tag_type(scsi_dev), | 822 | scsi_adjust_queue_depth(scsi_dev, scsi_get_tag_type(scsi_dev), |
818 | res); | 823 | res); |
819 | else { | 824 | else { |
820 | struct domain_device *dev = sdev_to_domain_dev(scsi_dev); | ||
821 | sas_printk("device %llx LUN %x queue depth changed to 1\n", | 825 | sas_printk("device %llx LUN %x queue depth changed to 1\n", |
822 | SAS_ADDR(dev->sas_addr), | 826 | SAS_ADDR(dev->sas_addr), |
823 | scsi_dev->lun); | 827 | scsi_dev->lun); |
@@ -830,6 +834,11 @@ int sas_change_queue_depth(struct scsi_device *scsi_dev, int new_depth, | |||
830 | 834 | ||
831 | int sas_change_queue_type(struct scsi_device *scsi_dev, int qt) | 835 | int sas_change_queue_type(struct scsi_device *scsi_dev, int qt) |
832 | { | 836 | { |
837 | struct domain_device *dev = sdev_to_domain_dev(scsi_dev); | ||
838 | |||
839 | if (dev_is_sata(dev)) | ||
840 | return -EINVAL; | ||
841 | |||
833 | if (!scsi_dev->tagged_supported) | 842 | if (!scsi_dev->tagged_supported) |
834 | return 0; | 843 | return 0; |
835 | 844 | ||
diff --git a/include/linux/libata.h b/include/linux/libata.h index efd6f9800762..23fa829bf7a3 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h | |||
@@ -1052,6 +1052,8 @@ extern int ata_scsi_slave_config(struct scsi_device *sdev); | |||
1052 | extern void ata_scsi_slave_destroy(struct scsi_device *sdev); | 1052 | extern void ata_scsi_slave_destroy(struct scsi_device *sdev); |
1053 | extern int ata_scsi_change_queue_depth(struct scsi_device *sdev, | 1053 | extern int ata_scsi_change_queue_depth(struct scsi_device *sdev, |
1054 | int queue_depth, int reason); | 1054 | int queue_depth, int reason); |
1055 | extern int __ata_change_queue_depth(struct ata_port *ap, struct scsi_device *sdev, | ||
1056 | int queue_depth, int reason); | ||
1055 | extern struct ata_device *ata_dev_pair(struct ata_device *adev); | 1057 | extern struct ata_device *ata_dev_pair(struct ata_device *adev); |
1056 | extern int ata_do_set_mode(struct ata_link *link, struct ata_device **r_failed_dev); | 1058 | extern int ata_do_set_mode(struct ata_link *link, struct ata_device **r_failed_dev); |
1057 | extern void ata_scsi_port_error_handler(struct Scsi_Host *host, struct ata_port *ap); | 1059 | extern void ata_scsi_port_error_handler(struct Scsi_Host *host, struct ata_port *ap); |