aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/ata/libata-core.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/ata/libata-core.c')
-rw-r--r--drivers/ata/libata-core.c46
1 files changed, 30 insertions, 16 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 5ba96c5052c8..dddcb9fde35a 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -104,6 +104,7 @@ struct ata_force_param {
104 unsigned long xfer_mask; 104 unsigned long xfer_mask;
105 unsigned int horkage_on; 105 unsigned int horkage_on;
106 unsigned int horkage_off; 106 unsigned int horkage_off;
107 unsigned int lflags;
107}; 108};
108 109
109struct ata_force_ent { 110struct ata_force_ent {
@@ -196,22 +197,23 @@ void ata_force_cbl(struct ata_port *ap)
196} 197}
197 198
198/** 199/**
199 * ata_force_spd_limit - force SATA spd limit according to libata.force 200 * ata_force_link_limits - force link limits according to libata.force
200 * @link: ATA link of interest 201 * @link: ATA link of interest
201 * 202 *
202 * Force SATA spd limit according to libata.force and whine about 203 * Force link flags and SATA spd limit according to libata.force
203 * it. When only the port part is specified (e.g. 1:), the limit 204 * and whine about it. When only the port part is specified
204 * applies to all links connected to both the host link and all 205 * (e.g. 1:), the limit applies to all links connected to both
205 * fan-out ports connected via PMP. If the device part is 206 * the host link and all fan-out ports connected via PMP. If the
206 * specified as 0 (e.g. 1.00:), it specifies the first fan-out 207 * device part is specified as 0 (e.g. 1.00:), it specifies the
207 * link not the host link. Device number 15 always points to the 208 * first fan-out link not the host link. Device number 15 always
208 * host link whether PMP is attached or not. 209 * points to the host link whether PMP is attached or not.
209 * 210 *
210 * LOCKING: 211 * LOCKING:
211 * EH context. 212 * EH context.
212 */ 213 */
213static void ata_force_spd_limit(struct ata_link *link) 214static void ata_force_link_limits(struct ata_link *link)
214{ 215{
216 bool did_spd = false;
215 int linkno, i; 217 int linkno, i;
216 218
217 if (ata_is_host_link(link)) 219 if (ata_is_host_link(link))
@@ -228,13 +230,22 @@ static void ata_force_spd_limit(struct ata_link *link)
228 if (fe->device != -1 && fe->device != linkno) 230 if (fe->device != -1 && fe->device != linkno)
229 continue; 231 continue;
230 232
231 if (!fe->param.spd_limit) 233 /* only honor the first spd limit */
232 continue; 234 if (!did_spd && fe->param.spd_limit) {
235 link->hw_sata_spd_limit = (1 << fe->param.spd_limit) - 1;
236 ata_link_printk(link, KERN_NOTICE,
237 "FORCE: PHY spd limit set to %s\n",
238 fe->param.name);
239 did_spd = true;
240 }
233 241
234 link->hw_sata_spd_limit = (1 << fe->param.spd_limit) - 1; 242 /* let lflags stack */
235 ata_link_printk(link, KERN_NOTICE, 243 if (fe->param.lflags) {
236 "FORCE: PHY spd limit set to %s\n", fe->param.name); 244 link->flags |= fe->param.lflags;
237 return; 245 ata_link_printk(link, KERN_NOTICE,
246 "FORCE: link flag 0x%x forced -> 0x%x\n",
247 fe->param.lflags, link->flags);
248 }
238 } 249 }
239} 250}
240 251
@@ -5200,7 +5211,7 @@ int sata_link_init_spd(struct ata_link *link)
5200 if (spd) 5211 if (spd)
5201 link->hw_sata_spd_limit &= (1 << spd) - 1; 5212 link->hw_sata_spd_limit &= (1 << spd) - 1;
5202 5213
5203 ata_force_spd_limit(link); 5214 ata_force_link_limits(link);
5204 5215
5205 link->sata_spd_limit = link->hw_sata_spd_limit; 5216 link->sata_spd_limit = link->hw_sata_spd_limit;
5206 5217
@@ -5991,6 +6002,9 @@ static int __init ata_parse_force_one(char **cur,
5991 { "udma133", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 6) }, 6002 { "udma133", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 6) },
5992 { "udma/133", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 6) }, 6003 { "udma/133", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 6) },
5993 { "udma7", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 7) }, 6004 { "udma7", .xfer_mask = 1 << (ATA_SHIFT_UDMA + 7) },
6005 { "nohrst", .lflags = ATA_LFLAG_NO_HRST },
6006 { "nosrst", .lflags = ATA_LFLAG_NO_SRST },
6007 { "norst", .lflags = ATA_LFLAG_NO_HRST | ATA_LFLAG_NO_SRST },
5994 }; 6008 };
5995 char *start = *cur, *p = *cur; 6009 char *start = *cur, *p = *cur;
5996 char *id, *val, *endp; 6010 char *id, *val, *endp;