diff options
author | Tejun Heo <htejun@gmail.com> | 2006-05-15 08:03:48 -0400 |
---|---|---|
committer | Tejun Heo <htejun@gmail.com> | 2006-05-15 08:03:48 -0400 |
commit | a6e6ce8e8dc907a2cf2b994b0ea4099423f046bf (patch) | |
tree | cc308c45c0d2df9e52be69959b9fd189371ad5d7 | |
parent | e8ee84518c159a663c07bf691ace187527380f61 (diff) |
[PATCH] libata-ncq: implement NCQ device configuration
Now that all NCQ related stuff are in place, implement NCQ device
configuration and bump ATA_MAX_QUEUE to 32 thus activating NCQ
support.
Original implementation is from Jens Axboe.
Signed-off-by: Tejun Heo <htejun@gmail.com>
-rw-r--r-- | drivers/scsi/libata-core.c | 31 | ||||
-rw-r--r-- | drivers/scsi/libata-scsi.c | 46 | ||||
-rw-r--r-- | include/linux/libata.h | 4 |
3 files changed, 78 insertions, 3 deletions
diff --git a/drivers/scsi/libata-core.c b/drivers/scsi/libata-core.c index 14ffb5264b65..9051b6821c1c 100644 --- a/drivers/scsi/libata-core.c +++ b/drivers/scsi/libata-core.c | |||
@@ -1251,6 +1251,28 @@ static inline u8 ata_dev_knobble(struct ata_device *dev) | |||
1251 | return ((dev->ap->cbl == ATA_CBL_SATA) && (!ata_id_is_sata(dev->id))); | 1251 | return ((dev->ap->cbl == ATA_CBL_SATA) && (!ata_id_is_sata(dev->id))); |
1252 | } | 1252 | } |
1253 | 1253 | ||
1254 | static void ata_dev_config_ncq(struct ata_device *dev, | ||
1255 | char *desc, size_t desc_sz) | ||
1256 | { | ||
1257 | struct ata_port *ap = dev->ap; | ||
1258 | int hdepth = 0, ddepth = ata_id_queue_depth(dev->id); | ||
1259 | |||
1260 | if (!ata_id_has_ncq(dev->id)) { | ||
1261 | desc[0] = '\0'; | ||
1262 | return; | ||
1263 | } | ||
1264 | |||
1265 | if (ap->flags & ATA_FLAG_NCQ) { | ||
1266 | hdepth = min(ap->host->can_queue, ATA_MAX_QUEUE - 1); | ||
1267 | dev->flags |= ATA_DFLAG_NCQ; | ||
1268 | } | ||
1269 | |||
1270 | if (hdepth >= ddepth) | ||
1271 | snprintf(desc, desc_sz, "NCQ (depth %d)", ddepth); | ||
1272 | else | ||
1273 | snprintf(desc, desc_sz, "NCQ (depth %d/%d)", hdepth, ddepth); | ||
1274 | } | ||
1275 | |||
1254 | /** | 1276 | /** |
1255 | * ata_dev_configure - Configure the specified ATA/ATAPI device | 1277 | * ata_dev_configure - Configure the specified ATA/ATAPI device |
1256 | * @dev: Target device to configure | 1278 | * @dev: Target device to configure |
@@ -1311,6 +1333,7 @@ static int ata_dev_configure(struct ata_device *dev, int print_info) | |||
1311 | 1333 | ||
1312 | if (ata_id_has_lba(id)) { | 1334 | if (ata_id_has_lba(id)) { |
1313 | const char *lba_desc; | 1335 | const char *lba_desc; |
1336 | char ncq_desc[20]; | ||
1314 | 1337 | ||
1315 | lba_desc = "LBA"; | 1338 | lba_desc = "LBA"; |
1316 | dev->flags |= ATA_DFLAG_LBA; | 1339 | dev->flags |= ATA_DFLAG_LBA; |
@@ -1319,14 +1342,17 @@ static int ata_dev_configure(struct ata_device *dev, int print_info) | |||
1319 | lba_desc = "LBA48"; | 1342 | lba_desc = "LBA48"; |
1320 | } | 1343 | } |
1321 | 1344 | ||
1345 | /* config NCQ */ | ||
1346 | ata_dev_config_ncq(dev, ncq_desc, sizeof(ncq_desc)); | ||
1347 | |||
1322 | /* print device info to dmesg */ | 1348 | /* print device info to dmesg */ |
1323 | if (print_info) | 1349 | if (print_info) |
1324 | ata_dev_printk(dev, KERN_INFO, "ATA-%d, " | 1350 | ata_dev_printk(dev, KERN_INFO, "ATA-%d, " |
1325 | "max %s, %Lu sectors: %s\n", | 1351 | "max %s, %Lu sectors: %s %s\n", |
1326 | ata_id_major_version(id), | 1352 | ata_id_major_version(id), |
1327 | ata_mode_string(xfer_mask), | 1353 | ata_mode_string(xfer_mask), |
1328 | (unsigned long long)dev->n_sectors, | 1354 | (unsigned long long)dev->n_sectors, |
1329 | lba_desc); | 1355 | lba_desc, ncq_desc); |
1330 | } else { | 1356 | } else { |
1331 | /* CHS */ | 1357 | /* CHS */ |
1332 | 1358 | ||
@@ -5675,6 +5701,7 @@ EXPORT_SYMBOL_GPL(ata_port_queue_task); | |||
5675 | EXPORT_SYMBOL_GPL(ata_scsi_ioctl); | 5701 | EXPORT_SYMBOL_GPL(ata_scsi_ioctl); |
5676 | EXPORT_SYMBOL_GPL(ata_scsi_queuecmd); | 5702 | EXPORT_SYMBOL_GPL(ata_scsi_queuecmd); |
5677 | EXPORT_SYMBOL_GPL(ata_scsi_slave_config); | 5703 | EXPORT_SYMBOL_GPL(ata_scsi_slave_config); |
5704 | EXPORT_SYMBOL_GPL(ata_scsi_change_queue_depth); | ||
5678 | EXPORT_SYMBOL_GPL(ata_scsi_release); | 5705 | EXPORT_SYMBOL_GPL(ata_scsi_release); |
5679 | EXPORT_SYMBOL_GPL(ata_host_intr); | 5706 | EXPORT_SYMBOL_GPL(ata_host_intr); |
5680 | EXPORT_SYMBOL_GPL(sata_scr_valid); | 5707 | EXPORT_SYMBOL_GPL(sata_scr_valid); |
diff --git a/drivers/scsi/libata-scsi.c b/drivers/scsi/libata-scsi.c index 9bef68c7c1de..996058af1bcd 100644 --- a/drivers/scsi/libata-scsi.c +++ b/drivers/scsi/libata-scsi.c | |||
@@ -41,6 +41,7 @@ | |||
41 | #include <scsi/scsi_eh.h> | 41 | #include <scsi/scsi_eh.h> |
42 | #include <scsi/scsi_device.h> | 42 | #include <scsi/scsi_device.h> |
43 | #include <scsi/scsi_request.h> | 43 | #include <scsi/scsi_request.h> |
44 | #include <scsi/scsi_tcq.h> | ||
44 | #include <scsi/scsi_transport.h> | 45 | #include <scsi/scsi_transport.h> |
45 | #include <linux/libata.h> | 46 | #include <linux/libata.h> |
46 | #include <linux/hdreg.h> | 47 | #include <linux/hdreg.h> |
@@ -684,6 +685,14 @@ static void ata_scsi_dev_config(struct scsi_device *sdev, | |||
684 | request_queue_t *q = sdev->request_queue; | 685 | request_queue_t *q = sdev->request_queue; |
685 | blk_queue_max_hw_segments(q, q->max_hw_segments - 1); | 686 | blk_queue_max_hw_segments(q, q->max_hw_segments - 1); |
686 | } | 687 | } |
688 | |||
689 | if (dev->flags & ATA_DFLAG_NCQ) { | ||
690 | int depth; | ||
691 | |||
692 | depth = min(sdev->host->can_queue, ata_id_queue_depth(dev->id)); | ||
693 | depth = min(ATA_MAX_QUEUE - 1, depth); | ||
694 | scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG, depth); | ||
695 | } | ||
687 | } | 696 | } |
688 | 697 | ||
689 | /** | 698 | /** |
@@ -718,6 +727,43 @@ int ata_scsi_slave_config(struct scsi_device *sdev) | |||
718 | } | 727 | } |
719 | 728 | ||
720 | /** | 729 | /** |
730 | * ata_scsi_change_queue_depth - SCSI callback for queue depth config | ||
731 | * @sdev: SCSI device to configure queue depth for | ||
732 | * @queue_depth: new queue depth | ||
733 | * | ||
734 | * This is libata standard hostt->change_queue_depth callback. | ||
735 | * SCSI will call into this callback when user tries to set queue | ||
736 | * depth via sysfs. | ||
737 | * | ||
738 | * LOCKING: | ||
739 | * SCSI layer (we don't care) | ||
740 | * | ||
741 | * RETURNS: | ||
742 | * Newly configured queue depth. | ||
743 | */ | ||
744 | int ata_scsi_change_queue_depth(struct scsi_device *sdev, int queue_depth) | ||
745 | { | ||
746 | struct ata_port *ap = ata_shost_to_port(sdev->host); | ||
747 | struct ata_device *dev; | ||
748 | int max_depth; | ||
749 | |||
750 | if (queue_depth < 1) | ||
751 | return sdev->queue_depth; | ||
752 | |||
753 | dev = ata_scsi_find_dev(ap, sdev); | ||
754 | if (!dev || !ata_dev_enabled(dev)) | ||
755 | return sdev->queue_depth; | ||
756 | |||
757 | max_depth = min(sdev->host->can_queue, ata_id_queue_depth(dev->id)); | ||
758 | max_depth = min(ATA_MAX_QUEUE - 1, max_depth); | ||
759 | if (queue_depth > max_depth) | ||
760 | queue_depth = max_depth; | ||
761 | |||
762 | scsi_adjust_queue_depth(sdev, MSG_SIMPLE_TAG, queue_depth); | ||
763 | return queue_depth; | ||
764 | } | ||
765 | |||
766 | /** | ||
721 | * ata_scsi_start_stop_xlat - Translate SCSI START STOP UNIT command | 767 | * ata_scsi_start_stop_xlat - Translate SCSI START STOP UNIT command |
722 | * @qc: Storage for translated ATA taskfile | 768 | * @qc: Storage for translated ATA taskfile |
723 | * @scsicmd: SCSI command to translate | 769 | * @scsicmd: SCSI command to translate |
diff --git a/include/linux/libata.h b/include/linux/libata.h index dd0db2d21bc5..fcdd798bb086 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h | |||
@@ -109,7 +109,7 @@ enum { | |||
109 | ATA_MAX_PORTS = 8, | 109 | ATA_MAX_PORTS = 8, |
110 | ATA_DEF_QUEUE = 1, | 110 | ATA_DEF_QUEUE = 1, |
111 | /* tag ATA_MAX_QUEUE - 1 is reserved for internal commands */ | 111 | /* tag ATA_MAX_QUEUE - 1 is reserved for internal commands */ |
112 | ATA_MAX_QUEUE = 2, | 112 | ATA_MAX_QUEUE = 32, |
113 | ATA_TAG_INTERNAL = ATA_MAX_QUEUE - 1, | 113 | ATA_TAG_INTERNAL = ATA_MAX_QUEUE - 1, |
114 | ATA_MAX_SECTORS = 200, /* FIXME */ | 114 | ATA_MAX_SECTORS = 200, /* FIXME */ |
115 | ATA_MAX_BUS = 2, | 115 | ATA_MAX_BUS = 2, |
@@ -679,6 +679,8 @@ extern int ata_std_bios_param(struct scsi_device *sdev, | |||
679 | struct block_device *bdev, | 679 | struct block_device *bdev, |
680 | sector_t capacity, int geom[]); | 680 | sector_t capacity, int geom[]); |
681 | extern int ata_scsi_slave_config(struct scsi_device *sdev); | 681 | extern int ata_scsi_slave_config(struct scsi_device *sdev); |
682 | extern int ata_scsi_change_queue_depth(struct scsi_device *sdev, | ||
683 | int queue_depth); | ||
682 | extern struct ata_device *ata_dev_pair(struct ata_device *adev); | 684 | extern struct ata_device *ata_dev_pair(struct ata_device *adev); |
683 | 685 | ||
684 | /* | 686 | /* |