diff options
| -rw-r--r-- | Documentation/kernel-parameters.txt | 3 | ||||
| -rw-r--r-- | drivers/ata/libata-core.c | 46 | ||||
| -rw-r--r-- | drivers/ata/libata-eh.c | 4 | ||||
| -rw-r--r-- | include/linux/libata.h | 1 |
4 files changed, 38 insertions, 16 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt index a8976467a983..1150444a21ab 100644 --- a/Documentation/kernel-parameters.txt +++ b/Documentation/kernel-parameters.txt | |||
| @@ -1074,6 +1074,9 @@ and is between 256 and 4096 characters. It is defined in the file | |||
| 1074 | 1074 | ||
| 1075 | * [no]ncq: Turn on or off NCQ. | 1075 | * [no]ncq: Turn on or off NCQ. |
| 1076 | 1076 | ||
| 1077 | * nohrst, nosrst, norst: suppress hard, soft | ||
| 1078 | and both resets. | ||
| 1079 | |||
| 1077 | If there are multiple matching configurations changing | 1080 | If there are multiple matching configurations changing |
| 1078 | the same attribute, the last one is used. | 1081 | the same attribute, the last one is used. |
| 1079 | 1082 | ||
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 | ||
| 109 | struct ata_force_ent { | 110 | struct 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 | */ |
| 213 | static void ata_force_spd_limit(struct ata_link *link) | 214 | static 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; |
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c index 58bdc538d229..a570ca47e239 100644 --- a/drivers/ata/libata-eh.c +++ b/drivers/ata/libata-eh.c | |||
| @@ -2210,6 +2210,10 @@ int ata_eh_reset(struct ata_link *link, int classify, | |||
| 2210 | */ | 2210 | */ |
| 2211 | while (ata_eh_reset_timeouts[max_tries] != ULONG_MAX) | 2211 | while (ata_eh_reset_timeouts[max_tries] != ULONG_MAX) |
| 2212 | max_tries++; | 2212 | max_tries++; |
| 2213 | if (link->flags & ATA_LFLAG_NO_HRST) | ||
| 2214 | hardreset = NULL; | ||
| 2215 | if (link->flags & ATA_LFLAG_NO_SRST) | ||
| 2216 | softreset = NULL; | ||
| 2213 | 2217 | ||
| 2214 | now = jiffies; | 2218 | now = jiffies; |
| 2215 | deadline = ata_deadline(ehc->last_reset, ATA_EH_RESET_COOL_DOWN); | 2219 | deadline = ata_deadline(ehc->last_reset, ATA_EH_RESET_COOL_DOWN); |
diff --git a/include/linux/libata.h b/include/linux/libata.h index 06b80337303b..5340d4c83fd9 100644 --- a/include/linux/libata.h +++ b/include/linux/libata.h | |||
| @@ -163,6 +163,7 @@ enum { | |||
| 163 | ATA_DEV_NONE = 9, /* no device */ | 163 | ATA_DEV_NONE = 9, /* no device */ |
| 164 | 164 | ||
| 165 | /* struct ata_link flags */ | 165 | /* struct ata_link flags */ |
| 166 | ATA_LFLAG_NO_HRST = (1 << 1), /* avoid hardreset */ | ||
| 166 | ATA_LFLAG_NO_SRST = (1 << 2), /* avoid softreset */ | 167 | ATA_LFLAG_NO_SRST = (1 << 2), /* avoid softreset */ |
| 167 | ATA_LFLAG_ASSUME_ATA = (1 << 3), /* assume ATA class */ | 168 | ATA_LFLAG_ASSUME_ATA = (1 << 3), /* assume ATA class */ |
| 168 | ATA_LFLAG_ASSUME_SEMB = (1 << 4), /* assume SEMB class */ | 169 | ATA_LFLAG_ASSUME_SEMB = (1 << 4), /* assume SEMB class */ |
