提交 b00eec1d 编写于 作者: T Tejun Heo 提交者: Jeff Garzik

[PATCH] libata: add per-device max_sectors

If a low level driver wants to control max_sectors, it had to adjust
ap->host->max_sectors and set ATA_DFLAG_LOCK_SECTORS to tell
ata_scsi_slave_config not to override the limit.  This is not only
cumbersome but also incorrect for hosts which support more than one
devices per port.

This patch adds per-device ->max_sectors.  If the field is unset
(zero), libata core layer will adjust ->max_sectors according to
default rules.  If the field is set, libata honors the setting.
Signed-off-by: NTejun Heo <htejun@gmail.com>
Signed-off-by: NJeff Garzik <jgarzik@pobox.com>
上级 6e7846e9
...@@ -1147,9 +1147,7 @@ void ata_dev_config(struct ata_port *ap, unsigned int i) ...@@ -1147,9 +1147,7 @@ void ata_dev_config(struct ata_port *ap, unsigned int i)
printk(KERN_INFO "ata%u(%u): applying bridge limits\n", printk(KERN_INFO "ata%u(%u): applying bridge limits\n",
ap->id, i); ap->id, i);
ap->udma_mask &= ATA_UDMA5; ap->udma_mask &= ATA_UDMA5;
ap->host->max_sectors = ATA_MAX_SECTORS; ap->device[i].max_sectors = ATA_MAX_SECTORS;
ap->host->hostt->max_sectors = ATA_MAX_SECTORS;
ap->device[i].flags |= ATA_DFLAG_LOCK_SECTORS;
} }
if (ap->ops->dev_config) if (ap->ops->dev_config)
......
...@@ -684,23 +684,23 @@ int ata_scsi_slave_config(struct scsi_device *sdev) ...@@ -684,23 +684,23 @@ int ata_scsi_slave_config(struct scsi_device *sdev)
if (sdev->id < ATA_MAX_DEVICES) { if (sdev->id < ATA_MAX_DEVICES) {
struct ata_port *ap; struct ata_port *ap;
struct ata_device *dev; struct ata_device *dev;
unsigned int max_sectors;
ap = (struct ata_port *) &sdev->host->hostdata[0]; ap = (struct ata_port *) &sdev->host->hostdata[0];
dev = &ap->device[sdev->id]; dev = &ap->device[sdev->id];
/* TODO: 1024 is an arbitrary number, not the /* TODO: 2048 is an arbitrary number, not the
* hardware maximum. This should be increased to * hardware maximum. This should be increased to
* 65534 when Jens Axboe's patch for dynamically * 65534 when Jens Axboe's patch for dynamically
* determining max_sectors is merged. * determining max_sectors is merged.
*/ */
if ((dev->flags & ATA_DFLAG_LBA48) && max_sectors = ATA_MAX_SECTORS;
((dev->flags & ATA_DFLAG_LOCK_SECTORS) == 0)) { if (dev->flags & ATA_DFLAG_LBA48)
/* max_sectors = 2048;
* do not overwrite sdev->host->max_sectors, since if (dev->max_sectors)
* other drives on this host may not support LBA48 max_sectors = dev->max_sectors;
*/
blk_queue_max_sectors(sdev->request_queue, 2048); blk_queue_max_sectors(sdev->request_queue, max_sectors);
}
/* /*
* SATA DMA transfers must be multiples of 4 byte, so * SATA DMA transfers must be multiples of 4 byte, so
......
...@@ -354,9 +354,7 @@ static void sil_dev_config(struct ata_port *ap, struct ata_device *dev) ...@@ -354,9 +354,7 @@ static void sil_dev_config(struct ata_port *ap, struct ata_device *dev)
(quirks & SIL_QUIRK_MOD15WRITE))) { (quirks & SIL_QUIRK_MOD15WRITE))) {
printk(KERN_INFO "ata%u(%u): applying Seagate errata fix (mod15write workaround)\n", printk(KERN_INFO "ata%u(%u): applying Seagate errata fix (mod15write workaround)\n",
ap->id, dev->devno); ap->id, dev->devno);
ap->host->max_sectors = 15; dev->max_sectors = 15;
ap->host->hostt->max_sectors = 15;
dev->flags |= ATA_DFLAG_LOCK_SECTORS;
return; return;
} }
......
...@@ -122,8 +122,7 @@ enum { ...@@ -122,8 +122,7 @@ enum {
/* struct ata_device stuff */ /* struct ata_device stuff */
ATA_DFLAG_LBA48 = (1 << 0), /* device supports LBA48 */ ATA_DFLAG_LBA48 = (1 << 0), /* device supports LBA48 */
ATA_DFLAG_PIO = (1 << 1), /* device currently in PIO mode */ ATA_DFLAG_PIO = (1 << 1), /* device currently in PIO mode */
ATA_DFLAG_LOCK_SECTORS = (1 << 2), /* don't adjust max_sectors */ ATA_DFLAG_LBA = (1 << 2), /* device supports LBA */
ATA_DFLAG_LBA = (1 << 3), /* device supports LBA */
ATA_DEV_UNKNOWN = 0, /* unknown device */ ATA_DEV_UNKNOWN = 0, /* unknown device */
ATA_DEV_ATA = 1, /* ATA device */ ATA_DEV_ATA = 1, /* ATA device */
...@@ -348,6 +347,7 @@ struct ata_device { ...@@ -348,6 +347,7 @@ struct ata_device {
unsigned int multi_count; /* sectors count for unsigned int multi_count; /* sectors count for
READ/WRITE MULTIPLE */ READ/WRITE MULTIPLE */
unsigned int max_sectors; /* per-device max sectors */
unsigned int cdb_len; unsigned int cdb_len;
/* for CHS addressing */ /* for CHS addressing */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册