diff options
Diffstat (limited to 'drivers/ata/libata-core.c')
-rw-r--r-- | drivers/ata/libata-core.c | 60 |
1 files changed, 37 insertions, 23 deletions
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index 5ba96c5052c8..79e3a8e7a84a 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 | ||
@@ -3277,7 +3288,7 @@ int ata_do_set_mode(struct ata_link *link, struct ata_device **r_failed_dev) | |||
3277 | dev->dma_mode = ata_xfer_mask2mode(dma_mask); | 3288 | dev->dma_mode = ata_xfer_mask2mode(dma_mask); |
3278 | 3289 | ||
3279 | found = 1; | 3290 | found = 1; |
3280 | if (dev->dma_mode != 0xff) | 3291 | if (ata_dma_enabled(dev)) |
3281 | used_dma = 1; | 3292 | used_dma = 1; |
3282 | } | 3293 | } |
3283 | if (!found) | 3294 | if (!found) |
@@ -3302,7 +3313,7 @@ int ata_do_set_mode(struct ata_link *link, struct ata_device **r_failed_dev) | |||
3302 | 3313 | ||
3303 | /* step 3: set host DMA timings */ | 3314 | /* step 3: set host DMA timings */ |
3304 | ata_link_for_each_dev(dev, link) { | 3315 | ata_link_for_each_dev(dev, link) { |
3305 | if (!ata_dev_enabled(dev) || dev->dma_mode == 0xff) | 3316 | if (!ata_dev_enabled(dev) || !ata_dma_enabled(dev)) |
3306 | continue; | 3317 | continue; |
3307 | 3318 | ||
3308 | dev->xfer_mode = dev->dma_mode; | 3319 | dev->xfer_mode = dev->dma_mode; |
@@ -5188,19 +5199,18 @@ void ata_link_init(struct ata_port *ap, struct ata_link *link, int pmp) | |||
5188 | */ | 5199 | */ |
5189 | int sata_link_init_spd(struct ata_link *link) | 5200 | int sata_link_init_spd(struct ata_link *link) |
5190 | { | 5201 | { |
5191 | u32 scontrol; | ||
5192 | u8 spd; | 5202 | u8 spd; |
5193 | int rc; | 5203 | int rc; |
5194 | 5204 | ||
5195 | rc = sata_scr_read(link, SCR_CONTROL, &scontrol); | 5205 | rc = sata_scr_read(link, SCR_CONTROL, &link->saved_scontrol); |
5196 | if (rc) | 5206 | if (rc) |
5197 | return rc; | 5207 | return rc; |
5198 | 5208 | ||
5199 | spd = (scontrol >> 4) & 0xf; | 5209 | spd = (link->saved_scontrol >> 4) & 0xf; |
5200 | if (spd) | 5210 | if (spd) |
5201 | link->hw_sata_spd_limit &= (1 << spd) - 1; | 5211 | link->hw_sata_spd_limit &= (1 << spd) - 1; |
5202 | 5212 | ||
5203 | ata_force_spd_limit(link); | 5213 | ata_force_link_limits(link); |
5204 | 5214 | ||
5205 | link->sata_spd_limit = link->hw_sata_spd_limit; | 5215 | link->sata_spd_limit = link->hw_sata_spd_limit; |
5206 | 5216 | ||
@@ -5783,9 +5793,10 @@ static void ata_port_detach(struct ata_port *ap) | |||
5783 | ata_port_wait_eh(ap); | 5793 | ata_port_wait_eh(ap); |
5784 | 5794 | ||
5785 | /* EH is now guaranteed to see UNLOADING - EH context belongs | 5795 | /* EH is now guaranteed to see UNLOADING - EH context belongs |
5786 | * to us. Disable all existing devices. | 5796 | * to us. Restore SControl and disable all existing devices. |
5787 | */ | 5797 | */ |
5788 | ata_port_for_each_link(link, ap) { | 5798 | __ata_port_for_each_link(link, ap) { |
5799 | sata_scr_write(link, SCR_CONTROL, link->saved_scontrol); | ||
5789 | ata_link_for_each_dev(dev, link) | 5800 | ata_link_for_each_dev(dev, link) |
5790 | ata_dev_disable(dev); | 5801 | ata_dev_disable(dev); |
5791 | } | 5802 | } |
@@ -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; |