diff options
author | Tejun Heo <tj@kernel.org> | 2008-08-13 07:19:09 -0400 |
---|---|---|
committer | Jeff Garzik <jgarzik@redhat.com> | 2008-08-22 02:07:43 -0400 |
commit | 05944bdf6fadb5394710269df6770dde447b23ca (patch) | |
tree | 7dd0435f44518b01e5d3a229167e7122425e2255 /drivers/ata | |
parent | 6a55617ed5d1aa62b850de2cf66f5ede2eef4825 (diff) |
libata: implement no[hs]rst force params
Implement force params nohrst, nosrst and norst. This is to work
around reset related problems and ease debugging.
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Jeff Garzik <jgarzik@redhat.com>
Diffstat (limited to 'drivers/ata')
-rw-r--r-- | drivers/ata/libata-core.c | 46 | ||||
-rw-r--r-- | drivers/ata/libata-eh.c | 4 |
2 files changed, 34 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 | ||
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); |