aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTejun Heo <htejun@gmail.com>2006-05-15 08:03:48 -0400
committerTejun Heo <htejun@gmail.com>2006-05-15 08:03:48 -0400
commita6e6ce8e8dc907a2cf2b994b0ea4099423f046bf (patch)
treecc308c45c0d2df9e52be69959b9fd189371ad5d7
parente8ee84518c159a663c07bf691ace187527380f61 (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.c31
-rw-r--r--drivers/scsi/libata-scsi.c46
-rw-r--r--include/linux/libata.h4
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
1254static 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);
5675EXPORT_SYMBOL_GPL(ata_scsi_ioctl); 5701EXPORT_SYMBOL_GPL(ata_scsi_ioctl);
5676EXPORT_SYMBOL_GPL(ata_scsi_queuecmd); 5702EXPORT_SYMBOL_GPL(ata_scsi_queuecmd);
5677EXPORT_SYMBOL_GPL(ata_scsi_slave_config); 5703EXPORT_SYMBOL_GPL(ata_scsi_slave_config);
5704EXPORT_SYMBOL_GPL(ata_scsi_change_queue_depth);
5678EXPORT_SYMBOL_GPL(ata_scsi_release); 5705EXPORT_SYMBOL_GPL(ata_scsi_release);
5679EXPORT_SYMBOL_GPL(ata_host_intr); 5706EXPORT_SYMBOL_GPL(ata_host_intr);
5680EXPORT_SYMBOL_GPL(sata_scr_valid); 5707EXPORT_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 */
744int 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[]);
681extern int ata_scsi_slave_config(struct scsi_device *sdev); 681extern int ata_scsi_slave_config(struct scsi_device *sdev);
682extern int ata_scsi_change_queue_depth(struct scsi_device *sdev,
683 int queue_depth);
682extern struct ata_device *ata_dev_pair(struct ata_device *adev); 684extern struct ata_device *ata_dev_pair(struct ata_device *adev);
683 685
684/* 686/*