|
@@ -104,6 +104,7 @@ struct ata_force_param {
|
|
|
unsigned long xfer_mask;
|
|
|
unsigned int horkage_on;
|
|
|
unsigned int horkage_off;
|
|
|
+ unsigned int lflags;
|
|
|
};
|
|
|
|
|
|
struct ata_force_ent {
|
|
@@ -196,22 +197,23 @@ void ata_force_cbl(struct ata_port *ap)
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * ata_force_spd_limit - force SATA spd limit according to libata.force
|
|
|
+ * ata_force_link_limits - force link limits according to libata.force
|
|
|
* @link: ATA link of interest
|
|
|
*
|
|
|
- * Force SATA spd limit according to libata.force and whine about
|
|
|
- * it. When only the port part is specified (e.g. 1:), the limit
|
|
|
- * applies to all links connected to both the host link and all
|
|
|
- * fan-out ports connected via PMP. If the device part is
|
|
|
- * specified as 0 (e.g. 1.00:), it specifies the first fan-out
|
|
|
- * link not the host link. Device number 15 always points to the
|
|
|
- * host link whether PMP is attached or not.
|
|
|
+ * Force link flags and SATA spd limit according to libata.force
|
|
|
+ * and whine about it. When only the port part is specified
|
|
|
+ * (e.g. 1:), the limit applies to all links connected to both
|
|
|
+ * the host link and all fan-out ports connected via PMP. If the
|
|
|
+ * device part is specified as 0 (e.g. 1.00:), it specifies the
|
|
|
+ * first fan-out link not the host link. Device number 15 always
|
|
|
+ * points to the host link whether PMP is attached or not.
|
|
|
*
|
|
|
* LOCKING:
|
|
|
* EH context.
|
|
|
*/
|
|
|
-static void ata_force_spd_limit(struct ata_link *link)
|
|
|
+static void ata_force_link_limits(struct ata_link *link)
|
|
|
{
|
|
|
+ bool did_spd = false;
|
|
|
int linkno, i;
|
|
|
|
|
|
if (ata_is_host_link(link))
|
|
@@ -228,13 +230,22 @@ static void ata_force_spd_limit(struct ata_link *link)
|
|
|
if (fe->device != -1 && fe->device != linkno)
|
|
|
continue;
|
|
|
|
|
|
- if (!fe->param.spd_limit)
|
|
|
- continue;
|
|
|
+ /* only honor the first spd limit */
|
|
|
+ if (!did_spd && fe->param.spd_limit) {
|
|
|
+ link->hw_sata_spd_limit = (1 << fe->param.spd_limit) - 1;
|
|
|
+ ata_link_printk(link, KERN_NOTICE,
|
|
|
+ "FORCE: PHY spd limit set to %s\n",
|
|
|
+ fe->param.name);
|
|
|
+ did_spd = true;
|
|
|
+ }
|
|
|
|
|
|
- link->hw_sata_spd_limit = (1 << fe->param.spd_limit) - 1;
|
|
|
- ata_link_printk(link, KERN_NOTICE,
|
|
|
- "FORCE: PHY spd limit set to %s\n", fe->param.name);
|
|
|
- return;
|
|
|
+ /* let lflags stack */
|
|
|
+ if (fe->param.lflags) {
|
|
|
+ link->flags |= fe->param.lflags;
|
|
|
+ ata_link_printk(link, KERN_NOTICE,
|
|
|
+ "FORCE: link flag 0x%x forced -> 0x%x\n",
|
|
|
+ fe->param.lflags, link->flags);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -5200,7 +5211,7 @@ int sata_link_init_spd(struct ata_link *link)
|
|
|
if (spd)
|
|
|
link->hw_sata_spd_limit &= (1 << spd) - 1;
|
|
|
|
|
|
- ata_force_spd_limit(link);
|
|
|
+ ata_force_link_limits(link);
|
|
|
|
|
|
link->sata_spd_limit = link->hw_sata_spd_limit;
|
|
|
|
|
@@ -5991,6 +6002,9 @@ static int __init ata_parse_force_one(char **cur,
|
|
|
{ "udma133", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 6) },
|
|
|
{ "udma/133", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 6) },
|
|
|
{ "udma7", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 7) },
|
|
|
+ { "nohrst", .lflags = ATA_LFLAG_NO_HRST },
|
|
|
+ { "nosrst", .lflags = ATA_LFLAG_NO_SRST },
|
|
|
+ { "norst", .lflags = ATA_LFLAG_NO_HRST | ATA_LFLAG_NO_SRST },
|
|
|
};
|
|
|
char *start = *cur, *p = *cur;
|
|
|
char *id, *val, *endp;
|