diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-11 14:23:17 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-06-11 14:23:17 -0400 |
commit | 6adc74b7d03c06a8e15d51fe33c3d924ada9271a (patch) | |
tree | 84b934ed223e0c4aa4f6233b38eea0f8e50f00ef /drivers/ata | |
parent | c9059598ea8981d02356eead3188bf7fa4d717b8 (diff) | |
parent | 517d3cc15b36392e518abab6bacbb72089658313 (diff) |
Merge branch 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev
* 'upstream-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jgarzik/libata-dev:
[libata] ata_piix: Enable parallel scan
sata_nv: use hardreset only for post-boot probing
[libata] ahci: Restore SB600 SATA controller 64 bit DMA
ata_piix: Remove stale comment
ata_piix: Turn on hotplugging support for older chips
ahci: misc cleanups for EM stuff
[libata] get rid of ATA_MAX_QUEUE loop in ata_qc_complete_multiple() v2
sata_sil: enable 32-bit PIO
sata_sx4: speed up ECC initialization
libata-sff: avoid byte swapping in ata_sff_data_xfer()
[libata] ahci: use less error-prone array initializers
Diffstat (limited to 'drivers/ata')
-rw-r--r-- | drivers/ata/ahci.c | 87 | ||||
-rw-r--r-- | drivers/ata/ata_piix.c | 11 | ||||
-rw-r--r-- | drivers/ata/libata-core.c | 11 | ||||
-rw-r--r-- | drivers/ata/libata-sff.c | 20 | ||||
-rw-r--r-- | drivers/ata/sata_nv.c | 131 | ||||
-rw-r--r-- | drivers/ata/sata_sil.c | 2 | ||||
-rw-r--r-- | drivers/ata/sata_sx4.c | 11 |
7 files changed, 180 insertions, 93 deletions
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c index 6b91c26a4635..15a23031833f 100644 --- a/drivers/ata/ahci.c +++ b/drivers/ata/ahci.c | |||
@@ -77,8 +77,6 @@ static ssize_t ahci_led_store(struct ata_port *ap, const char *buf, | |||
77 | size_t size); | 77 | size_t size); |
78 | static ssize_t ahci_transmit_led_message(struct ata_port *ap, u32 state, | 78 | static ssize_t ahci_transmit_led_message(struct ata_port *ap, u32 state, |
79 | ssize_t size); | 79 | ssize_t size); |
80 | #define MAX_SLOTS 8 | ||
81 | #define MAX_RETRY 15 | ||
82 | 80 | ||
83 | enum { | 81 | enum { |
84 | AHCI_PCI_BAR = 5, | 82 | AHCI_PCI_BAR = 5, |
@@ -231,6 +229,10 @@ enum { | |||
231 | 229 | ||
232 | ICH_MAP = 0x90, /* ICH MAP register */ | 230 | ICH_MAP = 0x90, /* ICH MAP register */ |
233 | 231 | ||
232 | /* em constants */ | ||
233 | EM_MAX_SLOTS = 8, | ||
234 | EM_MAX_RETRY = 5, | ||
235 | |||
234 | /* em_ctl bits */ | 236 | /* em_ctl bits */ |
235 | EM_CTL_RST = (1 << 9), /* Reset */ | 237 | EM_CTL_RST = (1 << 9), /* Reset */ |
236 | EM_CTL_TM = (1 << 8), /* Transmit Message */ | 238 | EM_CTL_TM = (1 << 8), /* Transmit Message */ |
@@ -282,8 +284,8 @@ struct ahci_port_priv { | |||
282 | unsigned int ncq_saw_dmas:1; | 284 | unsigned int ncq_saw_dmas:1; |
283 | unsigned int ncq_saw_sdb:1; | 285 | unsigned int ncq_saw_sdb:1; |
284 | u32 intr_mask; /* interrupts to enable */ | 286 | u32 intr_mask; /* interrupts to enable */ |
285 | struct ahci_em_priv em_priv[MAX_SLOTS];/* enclosure management info | 287 | /* enclosure management info per PM slot */ |
286 | * per PM slot */ | 288 | struct ahci_em_priv em_priv[EM_MAX_SLOTS]; |
287 | }; | 289 | }; |
288 | 290 | ||
289 | static int ahci_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val); | 291 | static int ahci_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val); |
@@ -313,7 +315,6 @@ static void ahci_error_handler(struct ata_port *ap); | |||
313 | static void ahci_post_internal_cmd(struct ata_queued_cmd *qc); | 315 | static void ahci_post_internal_cmd(struct ata_queued_cmd *qc); |
314 | static int ahci_port_resume(struct ata_port *ap); | 316 | static int ahci_port_resume(struct ata_port *ap); |
315 | static void ahci_dev_config(struct ata_device *dev); | 317 | static void ahci_dev_config(struct ata_device *dev); |
316 | static unsigned int ahci_fill_sg(struct ata_queued_cmd *qc, void *cmd_tbl); | ||
317 | static void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag, | 318 | static void ahci_fill_cmd_slot(struct ahci_port_priv *pp, unsigned int tag, |
318 | u32 opts); | 319 | u32 opts); |
319 | #ifdef CONFIG_PM | 320 | #ifdef CONFIG_PM |
@@ -404,14 +405,14 @@ static struct ata_port_operations ahci_sb600_ops = { | |||
404 | #define AHCI_HFLAGS(flags) .private_data = (void *)(flags) | 405 | #define AHCI_HFLAGS(flags) .private_data = (void *)(flags) |
405 | 406 | ||
406 | static const struct ata_port_info ahci_port_info[] = { | 407 | static const struct ata_port_info ahci_port_info[] = { |
407 | /* board_ahci */ | 408 | [board_ahci] = |
408 | { | 409 | { |
409 | .flags = AHCI_FLAG_COMMON, | 410 | .flags = AHCI_FLAG_COMMON, |
410 | .pio_mask = ATA_PIO4, | 411 | .pio_mask = ATA_PIO4, |
411 | .udma_mask = ATA_UDMA6, | 412 | .udma_mask = ATA_UDMA6, |
412 | .port_ops = &ahci_ops, | 413 | .port_ops = &ahci_ops, |
413 | }, | 414 | }, |
414 | /* board_ahci_vt8251 */ | 415 | [board_ahci_vt8251] = |
415 | { | 416 | { |
416 | AHCI_HFLAGS (AHCI_HFLAG_NO_NCQ | AHCI_HFLAG_NO_PMP), | 417 | AHCI_HFLAGS (AHCI_HFLAG_NO_NCQ | AHCI_HFLAG_NO_PMP), |
417 | .flags = AHCI_FLAG_COMMON, | 418 | .flags = AHCI_FLAG_COMMON, |
@@ -419,7 +420,7 @@ static const struct ata_port_info ahci_port_info[] = { | |||
419 | .udma_mask = ATA_UDMA6, | 420 | .udma_mask = ATA_UDMA6, |
420 | .port_ops = &ahci_vt8251_ops, | 421 | .port_ops = &ahci_vt8251_ops, |
421 | }, | 422 | }, |
422 | /* board_ahci_ign_iferr */ | 423 | [board_ahci_ign_iferr] = |
423 | { | 424 | { |
424 | AHCI_HFLAGS (AHCI_HFLAG_IGN_IRQ_IF_ERR), | 425 | AHCI_HFLAGS (AHCI_HFLAG_IGN_IRQ_IF_ERR), |
425 | .flags = AHCI_FLAG_COMMON, | 426 | .flags = AHCI_FLAG_COMMON, |
@@ -427,17 +428,16 @@ static const struct ata_port_info ahci_port_info[] = { | |||
427 | .udma_mask = ATA_UDMA6, | 428 | .udma_mask = ATA_UDMA6, |
428 | .port_ops = &ahci_ops, | 429 | .port_ops = &ahci_ops, |
429 | }, | 430 | }, |
430 | /* board_ahci_sb600 */ | 431 | [board_ahci_sb600] = |
431 | { | 432 | { |
432 | AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL | | 433 | AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL | |
433 | AHCI_HFLAG_32BIT_ONLY | AHCI_HFLAG_NO_MSI | | 434 | AHCI_HFLAG_NO_MSI | AHCI_HFLAG_SECT255), |
434 | AHCI_HFLAG_SECT255), | ||
435 | .flags = AHCI_FLAG_COMMON, | 435 | .flags = AHCI_FLAG_COMMON, |
436 | .pio_mask = ATA_PIO4, | 436 | .pio_mask = ATA_PIO4, |
437 | .udma_mask = ATA_UDMA6, | 437 | .udma_mask = ATA_UDMA6, |
438 | .port_ops = &ahci_sb600_ops, | 438 | .port_ops = &ahci_sb600_ops, |
439 | }, | 439 | }, |
440 | /* board_ahci_mv */ | 440 | [board_ahci_mv] = |
441 | { | 441 | { |
442 | AHCI_HFLAGS (AHCI_HFLAG_NO_NCQ | AHCI_HFLAG_NO_MSI | | 442 | AHCI_HFLAGS (AHCI_HFLAG_NO_NCQ | AHCI_HFLAG_NO_MSI | |
443 | AHCI_HFLAG_MV_PATA | AHCI_HFLAG_NO_PMP), | 443 | AHCI_HFLAG_MV_PATA | AHCI_HFLAG_NO_PMP), |
@@ -447,7 +447,7 @@ static const struct ata_port_info ahci_port_info[] = { | |||
447 | .udma_mask = ATA_UDMA6, | 447 | .udma_mask = ATA_UDMA6, |
448 | .port_ops = &ahci_ops, | 448 | .port_ops = &ahci_ops, |
449 | }, | 449 | }, |
450 | /* board_ahci_sb700, for SB700 and SB800 */ | 450 | [board_ahci_sb700] = /* for SB700 and SB800 */ |
451 | { | 451 | { |
452 | AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL), | 452 | AHCI_HFLAGS (AHCI_HFLAG_IGN_SERR_INTERNAL), |
453 | .flags = AHCI_FLAG_COMMON, | 453 | .flags = AHCI_FLAG_COMMON, |
@@ -455,7 +455,7 @@ static const struct ata_port_info ahci_port_info[] = { | |||
455 | .udma_mask = ATA_UDMA6, | 455 | .udma_mask = ATA_UDMA6, |
456 | .port_ops = &ahci_sb600_ops, | 456 | .port_ops = &ahci_sb600_ops, |
457 | }, | 457 | }, |
458 | /* board_ahci_mcp65 */ | 458 | [board_ahci_mcp65] = |
459 | { | 459 | { |
460 | AHCI_HFLAGS (AHCI_HFLAG_YES_NCQ), | 460 | AHCI_HFLAGS (AHCI_HFLAG_YES_NCQ), |
461 | .flags = AHCI_FLAG_COMMON, | 461 | .flags = AHCI_FLAG_COMMON, |
@@ -463,7 +463,7 @@ static const struct ata_port_info ahci_port_info[] = { | |||
463 | .udma_mask = ATA_UDMA6, | 463 | .udma_mask = ATA_UDMA6, |
464 | .port_ops = &ahci_ops, | 464 | .port_ops = &ahci_ops, |
465 | }, | 465 | }, |
466 | /* board_ahci_nopmp */ | 466 | [board_ahci_nopmp] = |
467 | { | 467 | { |
468 | AHCI_HFLAGS (AHCI_HFLAG_NO_PMP), | 468 | AHCI_HFLAGS (AHCI_HFLAG_NO_PMP), |
469 | .flags = AHCI_FLAG_COMMON, | 469 | .flags = AHCI_FLAG_COMMON, |
@@ -1141,12 +1141,12 @@ static void ahci_start_port(struct ata_port *ap) | |||
1141 | emp = &pp->em_priv[link->pmp]; | 1141 | emp = &pp->em_priv[link->pmp]; |
1142 | 1142 | ||
1143 | /* EM Transmit bit maybe busy during init */ | 1143 | /* EM Transmit bit maybe busy during init */ |
1144 | for (i = 0; i < MAX_RETRY; i++) { | 1144 | for (i = 0; i < EM_MAX_RETRY; i++) { |
1145 | rc = ahci_transmit_led_message(ap, | 1145 | rc = ahci_transmit_led_message(ap, |
1146 | emp->led_state, | 1146 | emp->led_state, |
1147 | 4); | 1147 | 4); |
1148 | if (rc == -EBUSY) | 1148 | if (rc == -EBUSY) |
1149 | udelay(100); | 1149 | msleep(1); |
1150 | else | 1150 | else |
1151 | break; | 1151 | break; |
1152 | } | 1152 | } |
@@ -1340,7 +1340,7 @@ static ssize_t ahci_transmit_led_message(struct ata_port *ap, u32 state, | |||
1340 | 1340 | ||
1341 | /* get the slot number from the message */ | 1341 | /* get the slot number from the message */ |
1342 | pmp = (state & EM_MSG_LED_PMP_SLOT) >> 8; | 1342 | pmp = (state & EM_MSG_LED_PMP_SLOT) >> 8; |
1343 | if (pmp < MAX_SLOTS) | 1343 | if (pmp < EM_MAX_SLOTS) |
1344 | emp = &pp->em_priv[pmp]; | 1344 | emp = &pp->em_priv[pmp]; |
1345 | else | 1345 | else |
1346 | return -EINVAL; | 1346 | return -EINVAL; |
@@ -1408,7 +1408,7 @@ static ssize_t ahci_led_store(struct ata_port *ap, const char *buf, | |||
1408 | 1408 | ||
1409 | /* get the slot number from the message */ | 1409 | /* get the slot number from the message */ |
1410 | pmp = (state & EM_MSG_LED_PMP_SLOT) >> 8; | 1410 | pmp = (state & EM_MSG_LED_PMP_SLOT) >> 8; |
1411 | if (pmp < MAX_SLOTS) | 1411 | if (pmp < EM_MAX_SLOTS) |
1412 | emp = &pp->em_priv[pmp]; | 1412 | emp = &pp->em_priv[pmp]; |
1413 | else | 1413 | else |
1414 | return -EINVAL; | 1414 | return -EINVAL; |
@@ -2584,6 +2584,51 @@ static void ahci_p5wdh_workaround(struct ata_host *host) | |||
2584 | } | 2584 | } |
2585 | } | 2585 | } |
2586 | 2586 | ||
2587 | /* | ||
2588 | * SB600 ahci controller on ASUS M2A-VM can't do 64bit DMA with older | ||
2589 | * BIOS. The oldest version known to be broken is 0901 and working is | ||
2590 | * 1501 which was released on 2007-10-26. Force 32bit DMA on anything | ||
2591 | * older than 1501. Please read bko#9412 for more info. | ||
2592 | */ | ||
2593 | static bool ahci_asus_m2a_vm_32bit_only(struct pci_dev *pdev) | ||
2594 | { | ||
2595 | static const struct dmi_system_id sysids[] = { | ||
2596 | { | ||
2597 | .ident = "ASUS M2A-VM", | ||
2598 | .matches = { | ||
2599 | DMI_MATCH(DMI_BOARD_VENDOR, | ||
2600 | "ASUSTeK Computer INC."), | ||
2601 | DMI_MATCH(DMI_BOARD_NAME, "M2A-VM"), | ||
2602 | }, | ||
2603 | }, | ||
2604 | { } | ||
2605 | }; | ||
2606 | const char *cutoff_mmdd = "10/26"; | ||
2607 | const char *date; | ||
2608 | int year; | ||
2609 | |||
2610 | if (pdev->bus->number != 0 || pdev->devfn != PCI_DEVFN(0x12, 0) || | ||
2611 | !dmi_check_system(sysids)) | ||
2612 | return false; | ||
2613 | |||
2614 | /* | ||
2615 | * Argh.... both version and date are free form strings. | ||
2616 | * Let's hope they're using the same date format across | ||
2617 | * different versions. | ||
2618 | */ | ||
2619 | date = dmi_get_system_info(DMI_BIOS_DATE); | ||
2620 | year = dmi_get_year(DMI_BIOS_DATE); | ||
2621 | if (date && strlen(date) >= 10 && date[2] == '/' && date[5] == '/' && | ||
2622 | (year > 2007 || | ||
2623 | (year == 2007 && strncmp(date, cutoff_mmdd, 5) >= 0))) | ||
2624 | return false; | ||
2625 | |||
2626 | dev_printk(KERN_WARNING, &pdev->dev, "ASUS M2A-VM: BIOS too old, " | ||
2627 | "forcing 32bit DMA, update BIOS\n"); | ||
2628 | |||
2629 | return true; | ||
2630 | } | ||
2631 | |||
2587 | static bool ahci_broken_system_poweroff(struct pci_dev *pdev) | 2632 | static bool ahci_broken_system_poweroff(struct pci_dev *pdev) |
2588 | { | 2633 | { |
2589 | static const struct dmi_system_id broken_systems[] = { | 2634 | static const struct dmi_system_id broken_systems[] = { |
@@ -2744,6 +2789,10 @@ static int ahci_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
2744 | if (board_id == board_ahci_sb700 && pdev->revision >= 0x40) | 2789 | if (board_id == board_ahci_sb700 && pdev->revision >= 0x40) |
2745 | hpriv->flags &= ~AHCI_HFLAG_IGN_SERR_INTERNAL; | 2790 | hpriv->flags &= ~AHCI_HFLAG_IGN_SERR_INTERNAL; |
2746 | 2791 | ||
2792 | /* apply ASUS M2A_VM quirk */ | ||
2793 | if (ahci_asus_m2a_vm_32bit_only(pdev)) | ||
2794 | hpriv->flags |= AHCI_HFLAG_32BIT_ONLY; | ||
2795 | |||
2747 | if (!(hpriv->flags & AHCI_HFLAG_NO_MSI)) | 2796 | if (!(hpriv->flags & AHCI_HFLAG_NO_MSI)) |
2748 | pci_enable_msi(pdev); | 2797 | pci_enable_msi(pdev); |
2749 | 2798 | ||
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c index 1aeb7082b0c4..d0a14cf2bd74 100644 --- a/drivers/ata/ata_piix.c +++ b/drivers/ata/ata_piix.c | |||
@@ -223,10 +223,8 @@ static const struct pci_device_id piix_pci_tbl[] = { | |||
223 | /* ICH8 Mobile PATA Controller */ | 223 | /* ICH8 Mobile PATA Controller */ |
224 | { 0x8086, 0x2850, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 }, | 224 | { 0x8086, 0x2850, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich_pata_100 }, |
225 | 225 | ||
226 | /* NOTE: The following PCI ids must be kept in sync with the | 226 | /* SATA ports */ |
227 | * list in drivers/pci/quirks.c. | 227 | |
228 | */ | ||
229 | |||
230 | /* 82801EB (ICH5) */ | 228 | /* 82801EB (ICH5) */ |
231 | { 0x8086, 0x24d1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich5_sata }, | 229 | { 0x8086, 0x24d1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich5_sata }, |
232 | /* 82801EB (ICH5) */ | 230 | /* 82801EB (ICH5) */ |
@@ -1509,8 +1507,8 @@ static int __devinit piix_init_one(struct pci_dev *pdev, | |||
1509 | dev_printk(KERN_DEBUG, &pdev->dev, | 1507 | dev_printk(KERN_DEBUG, &pdev->dev, |
1510 | "version " DRV_VERSION "\n"); | 1508 | "version " DRV_VERSION "\n"); |
1511 | 1509 | ||
1512 | /* no hotplugging support (FIXME) */ | 1510 | /* no hotplugging support for later devices (FIXME) */ |
1513 | if (!in_module_init) | 1511 | if (!in_module_init && ent->driver_data >= ich5_sata) |
1514 | return -ENODEV; | 1512 | return -ENODEV; |
1515 | 1513 | ||
1516 | if (piix_broken_system_poweroff(pdev)) { | 1514 | if (piix_broken_system_poweroff(pdev)) { |
@@ -1591,6 +1589,7 @@ static int __devinit piix_init_one(struct pci_dev *pdev, | |||
1591 | host->ports[1]->mwdma_mask = 0; | 1589 | host->ports[1]->mwdma_mask = 0; |
1592 | host->ports[1]->udma_mask = 0; | 1590 | host->ports[1]->udma_mask = 0; |
1593 | } | 1591 | } |
1592 | host->flags |= ATA_HOST_PARALLEL_SCAN; | ||
1594 | 1593 | ||
1595 | pci_set_master(pdev); | 1594 | pci_set_master(pdev); |
1596 | return ata_pci_sff_activate_host(host, ata_sff_interrupt, &piix_sht); | 1595 | return ata_pci_sff_activate_host(host, ata_sff_interrupt, &piix_sht); |
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c index c9242301cfa1..ca4d208ddf3b 100644 --- a/drivers/ata/libata-core.c +++ b/drivers/ata/libata-core.c | |||
@@ -5031,7 +5031,6 @@ int ata_qc_complete_multiple(struct ata_port *ap, u32 qc_active) | |||
5031 | { | 5031 | { |
5032 | int nr_done = 0; | 5032 | int nr_done = 0; |
5033 | u32 done_mask; | 5033 | u32 done_mask; |
5034 | int i; | ||
5035 | 5034 | ||
5036 | done_mask = ap->qc_active ^ qc_active; | 5035 | done_mask = ap->qc_active ^ qc_active; |
5037 | 5036 | ||
@@ -5041,16 +5040,16 @@ int ata_qc_complete_multiple(struct ata_port *ap, u32 qc_active) | |||
5041 | return -EINVAL; | 5040 | return -EINVAL; |
5042 | } | 5041 | } |
5043 | 5042 | ||
5044 | for (i = 0; i < ATA_MAX_QUEUE; i++) { | 5043 | while (done_mask) { |
5045 | struct ata_queued_cmd *qc; | 5044 | struct ata_queued_cmd *qc; |
5045 | unsigned int tag = __ffs(done_mask); | ||
5046 | 5046 | ||
5047 | if (!(done_mask & (1 << i))) | 5047 | qc = ata_qc_from_tag(ap, tag); |
5048 | continue; | 5048 | if (qc) { |
5049 | |||
5050 | if ((qc = ata_qc_from_tag(ap, i))) { | ||
5051 | ata_qc_complete(qc); | 5049 | ata_qc_complete(qc); |
5052 | nr_done++; | 5050 | nr_done++; |
5053 | } | 5051 | } |
5052 | done_mask &= ~(1 << tag); | ||
5054 | } | 5053 | } |
5055 | 5054 | ||
5056 | return nr_done; | 5055 | return nr_done; |
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c index bb18415d3d63..bbbb1fab1755 100644 --- a/drivers/ata/libata-sff.c +++ b/drivers/ata/libata-sff.c | |||
@@ -727,17 +727,23 @@ unsigned int ata_sff_data_xfer(struct ata_device *dev, unsigned char *buf, | |||
727 | else | 727 | else |
728 | iowrite16_rep(data_addr, buf, words); | 728 | iowrite16_rep(data_addr, buf, words); |
729 | 729 | ||
730 | /* Transfer trailing 1 byte, if any. */ | 730 | /* Transfer trailing byte, if any. */ |
731 | if (unlikely(buflen & 0x01)) { | 731 | if (unlikely(buflen & 0x01)) { |
732 | __le16 align_buf[1] = { 0 }; | 732 | unsigned char pad[2]; |
733 | unsigned char *trailing_buf = buf + buflen - 1; | ||
734 | 733 | ||
734 | /* Point buf to the tail of buffer */ | ||
735 | buf += buflen - 1; | ||
736 | |||
737 | /* | ||
738 | * Use io*16_rep() accessors here as well to avoid pointlessly | ||
739 | * swapping bytes to and fro on the big endian machines... | ||
740 | */ | ||
735 | if (rw == READ) { | 741 | if (rw == READ) { |
736 | align_buf[0] = cpu_to_le16(ioread16(data_addr)); | 742 | ioread16_rep(data_addr, pad, 1); |
737 | memcpy(trailing_buf, align_buf, 1); | 743 | *buf = pad[0]; |
738 | } else { | 744 | } else { |
739 | memcpy(align_buf, trailing_buf, 1); | 745 | pad[0] = *buf; |
740 | iowrite16(le16_to_cpu(align_buf[0]), data_addr); | 746 | iowrite16_rep(data_addr, pad, 1); |
741 | } | 747 | } |
742 | words++; | 748 | words++; |
743 | } | 749 | } |
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c index 6cda12ba8122..b2d11f300c39 100644 --- a/drivers/ata/sata_nv.c +++ b/drivers/ata/sata_nv.c | |||
@@ -305,8 +305,8 @@ static irqreturn_t nv_ck804_interrupt(int irq, void *dev_instance); | |||
305 | static int nv_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val); | 305 | static int nv_scr_read(struct ata_link *link, unsigned int sc_reg, u32 *val); |
306 | static int nv_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val); | 306 | static int nv_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val); |
307 | 307 | ||
308 | static int nv_noclassify_hardreset(struct ata_link *link, unsigned int *class, | 308 | static int nv_hardreset(struct ata_link *link, unsigned int *class, |
309 | unsigned long deadline); | 309 | unsigned long deadline); |
310 | static void nv_nf2_freeze(struct ata_port *ap); | 310 | static void nv_nf2_freeze(struct ata_port *ap); |
311 | static void nv_nf2_thaw(struct ata_port *ap); | 311 | static void nv_nf2_thaw(struct ata_port *ap); |
312 | static void nv_ck804_freeze(struct ata_port *ap); | 312 | static void nv_ck804_freeze(struct ata_port *ap); |
@@ -406,49 +406,82 @@ static struct scsi_host_template nv_swncq_sht = { | |||
406 | .slave_configure = nv_swncq_slave_config, | 406 | .slave_configure = nv_swncq_slave_config, |
407 | }; | 407 | }; |
408 | 408 | ||
409 | static struct ata_port_operations nv_common_ops = { | 409 | /* |
410 | * NV SATA controllers have various different problems with hardreset | ||
411 | * protocol depending on the specific controller and device. | ||
412 | * | ||
413 | * GENERIC: | ||
414 | * | ||
415 | * bko11195 reports that link doesn't come online after hardreset on | ||
416 | * generic nv's and there have been several other similar reports on | ||
417 | * linux-ide. | ||
418 | * | ||
419 | * bko12351#c23 reports that warmplug on MCP61 doesn't work with | ||
420 | * softreset. | ||
421 | * | ||
422 | * NF2/3: | ||
423 | * | ||
424 | * bko3352 reports nf2/3 controllers can't determine device signature | ||
425 | * reliably after hardreset. The following thread reports detection | ||
426 | * failure on cold boot with the standard debouncing timing. | ||
427 | * | ||
428 | * http://thread.gmane.org/gmane.linux.ide/34098 | ||
429 | * | ||
430 | * bko12176 reports that hardreset fails to bring up the link during | ||
431 | * boot on nf2. | ||
432 | * | ||
433 | * CK804: | ||
434 | * | ||
435 | * For initial probing after boot and hot plugging, hardreset mostly | ||
436 | * works fine on CK804 but curiously, reprobing on the initial port | ||
437 | * by rescanning or rmmod/insmod fails to acquire the initial D2H Reg | ||
438 | * FIS in somewhat undeterministic way. | ||
439 | * | ||
440 | * SWNCQ: | ||
441 | * | ||
442 | * bko12351 reports that when SWNCQ is enabled, for hotplug to work, | ||
443 | * hardreset should be used and hardreset can't report proper | ||
444 | * signature, which suggests that mcp5x is closer to nf2 as long as | ||
445 | * reset quirkiness is concerned. | ||
446 | * | ||
447 | * bko12703 reports that boot probing fails for intel SSD with | ||
448 | * hardreset. Link fails to come online. Softreset works fine. | ||
449 | * | ||
450 | * The failures are varied but the following patterns seem true for | ||
451 | * all flavors. | ||
452 | * | ||
453 | * - Softreset during boot always works. | ||
454 | * | ||
455 | * - Hardreset during boot sometimes fails to bring up the link on | ||
456 | * certain comibnations and device signature acquisition is | ||
457 | * unreliable. | ||
458 | * | ||
459 | * - Hardreset is often necessary after hotplug. | ||
460 | * | ||
461 | * So, preferring softreset for boot probing and error handling (as | ||
462 | * hardreset might bring down the link) but using hardreset for | ||
463 | * post-boot probing should work around the above issues in most | ||
464 | * cases. Define nv_hardreset() which only kicks in for post-boot | ||
465 | * probing and use it for all variants. | ||
466 | */ | ||
467 | static struct ata_port_operations nv_generic_ops = { | ||
410 | .inherits = &ata_bmdma_port_ops, | 468 | .inherits = &ata_bmdma_port_ops, |
411 | .lost_interrupt = ATA_OP_NULL, | 469 | .lost_interrupt = ATA_OP_NULL, |
412 | .scr_read = nv_scr_read, | 470 | .scr_read = nv_scr_read, |
413 | .scr_write = nv_scr_write, | 471 | .scr_write = nv_scr_write, |
472 | .hardreset = nv_hardreset, | ||
414 | }; | 473 | }; |
415 | 474 | ||
416 | /* OSDL bz11195 reports that link doesn't come online after hardreset | ||
417 | * on generic nv's and there have been several other similar reports | ||
418 | * on linux-ide. Disable hardreset for generic nv's. | ||
419 | */ | ||
420 | static struct ata_port_operations nv_generic_ops = { | ||
421 | .inherits = &nv_common_ops, | ||
422 | .hardreset = ATA_OP_NULL, | ||
423 | }; | ||
424 | |||
425 | /* nf2 is ripe with hardreset related problems. | ||
426 | * | ||
427 | * kernel bz#3352 reports nf2/3 controllers can't determine device | ||
428 | * signature reliably. The following thread reports detection failure | ||
429 | * on cold boot with the standard debouncing timing. | ||
430 | * | ||
431 | * http://thread.gmane.org/gmane.linux.ide/34098 | ||
432 | * | ||
433 | * And bz#12176 reports that hardreset simply doesn't work on nf2. | ||
434 | * Give up on it and just don't do hardreset. | ||
435 | */ | ||
436 | static struct ata_port_operations nv_nf2_ops = { | 475 | static struct ata_port_operations nv_nf2_ops = { |
437 | .inherits = &nv_generic_ops, | 476 | .inherits = &nv_generic_ops, |
438 | .freeze = nv_nf2_freeze, | 477 | .freeze = nv_nf2_freeze, |
439 | .thaw = nv_nf2_thaw, | 478 | .thaw = nv_nf2_thaw, |
440 | }; | 479 | }; |
441 | 480 | ||
442 | /* For initial probing after boot and hot plugging, hardreset mostly | ||
443 | * works fine on CK804 but curiously, reprobing on the initial port by | ||
444 | * rescanning or rmmod/insmod fails to acquire the initial D2H Reg FIS | ||
445 | * in somewhat undeterministic way. Use noclassify hardreset. | ||
446 | */ | ||
447 | static struct ata_port_operations nv_ck804_ops = { | 481 | static struct ata_port_operations nv_ck804_ops = { |
448 | .inherits = &nv_common_ops, | 482 | .inherits = &nv_generic_ops, |
449 | .freeze = nv_ck804_freeze, | 483 | .freeze = nv_ck804_freeze, |
450 | .thaw = nv_ck804_thaw, | 484 | .thaw = nv_ck804_thaw, |
451 | .hardreset = nv_noclassify_hardreset, | ||
452 | .host_stop = nv_ck804_host_stop, | 485 | .host_stop = nv_ck804_host_stop, |
453 | }; | 486 | }; |
454 | 487 | ||
@@ -476,19 +509,8 @@ static struct ata_port_operations nv_adma_ops = { | |||
476 | .host_stop = nv_adma_host_stop, | 509 | .host_stop = nv_adma_host_stop, |
477 | }; | 510 | }; |
478 | 511 | ||
479 | /* Kernel bz#12351 reports that when SWNCQ is enabled, for hotplug to | ||
480 | * work, hardreset should be used and hardreset can't report proper | ||
481 | * signature, which suggests that mcp5x is closer to nf2 as long as | ||
482 | * reset quirkiness is concerned. Define separate ops for mcp5x with | ||
483 | * nv_noclassify_hardreset(). | ||
484 | */ | ||
485 | static struct ata_port_operations nv_mcp5x_ops = { | ||
486 | .inherits = &nv_common_ops, | ||
487 | .hardreset = nv_noclassify_hardreset, | ||
488 | }; | ||
489 | |||
490 | static struct ata_port_operations nv_swncq_ops = { | 512 | static struct ata_port_operations nv_swncq_ops = { |
491 | .inherits = &nv_mcp5x_ops, | 513 | .inherits = &nv_generic_ops, |
492 | 514 | ||
493 | .qc_defer = ata_std_qc_defer, | 515 | .qc_defer = ata_std_qc_defer, |
494 | .qc_prep = nv_swncq_qc_prep, | 516 | .qc_prep = nv_swncq_qc_prep, |
@@ -557,7 +579,7 @@ static const struct ata_port_info nv_port_info[] = { | |||
557 | .pio_mask = NV_PIO_MASK, | 579 | .pio_mask = NV_PIO_MASK, |
558 | .mwdma_mask = NV_MWDMA_MASK, | 580 | .mwdma_mask = NV_MWDMA_MASK, |
559 | .udma_mask = NV_UDMA_MASK, | 581 | .udma_mask = NV_UDMA_MASK, |
560 | .port_ops = &nv_mcp5x_ops, | 582 | .port_ops = &nv_generic_ops, |
561 | .private_data = NV_PI_PRIV(nv_generic_interrupt, &nv_sht), | 583 | .private_data = NV_PI_PRIV(nv_generic_interrupt, &nv_sht), |
562 | }, | 584 | }, |
563 | /* SWNCQ */ | 585 | /* SWNCQ */ |
@@ -1559,15 +1581,24 @@ static int nv_scr_write(struct ata_link *link, unsigned int sc_reg, u32 val) | |||
1559 | return 0; | 1581 | return 0; |
1560 | } | 1582 | } |
1561 | 1583 | ||
1562 | static int nv_noclassify_hardreset(struct ata_link *link, unsigned int *class, | 1584 | static int nv_hardreset(struct ata_link *link, unsigned int *class, |
1563 | unsigned long deadline) | 1585 | unsigned long deadline) |
1564 | { | 1586 | { |
1565 | bool online; | 1587 | struct ata_eh_context *ehc = &link->eh_context; |
1566 | int rc; | ||
1567 | 1588 | ||
1568 | rc = sata_link_hardreset(link, sata_deb_timing_hotplug, deadline, | 1589 | /* Do hardreset iff it's post-boot probing, please read the |
1569 | &online, NULL); | 1590 | * comment above port ops for details. |
1570 | return online ? -EAGAIN : rc; | 1591 | */ |
1592 | if (!(link->ap->pflags & ATA_PFLAG_LOADING) && | ||
1593 | !ata_dev_enabled(link->device)) | ||
1594 | sata_link_hardreset(link, sata_deb_timing_hotplug, deadline, | ||
1595 | NULL, NULL); | ||
1596 | else if (!(ehc->i.flags & ATA_EHI_QUIET)) | ||
1597 | ata_link_printk(link, KERN_INFO, | ||
1598 | "nv: skipping hardreset on occupied port\n"); | ||
1599 | |||
1600 | /* device signature acquisition is unreliable */ | ||
1601 | return -EAGAIN; | ||
1571 | } | 1602 | } |
1572 | 1603 | ||
1573 | static void nv_nf2_freeze(struct ata_port *ap) | 1604 | static void nv_nf2_freeze(struct ata_port *ap) |
diff --git a/drivers/ata/sata_sil.c b/drivers/ata/sata_sil.c index e67ce8e5caa5..030ec079b184 100644 --- a/drivers/ata/sata_sil.c +++ b/drivers/ata/sata_sil.c | |||
@@ -183,7 +183,7 @@ static struct scsi_host_template sil_sht = { | |||
183 | }; | 183 | }; |
184 | 184 | ||
185 | static struct ata_port_operations sil_ops = { | 185 | static struct ata_port_operations sil_ops = { |
186 | .inherits = &ata_bmdma_port_ops, | 186 | .inherits = &ata_bmdma32_port_ops, |
187 | .dev_config = sil_dev_config, | 187 | .dev_config = sil_dev_config, |
188 | .set_mode = sil_set_mode, | 188 | .set_mode = sil_set_mode, |
189 | .bmdma_setup = sil_bmdma_setup, | 189 | .bmdma_setup = sil_bmdma_setup, |
diff --git a/drivers/ata/sata_sx4.c b/drivers/ata/sata_sx4.c index eb05a3c82a9e..bbcf970068ad 100644 --- a/drivers/ata/sata_sx4.c +++ b/drivers/ata/sata_sx4.c | |||
@@ -193,6 +193,7 @@ enum { | |||
193 | PDC_TIMER_MASK_INT, | 193 | PDC_TIMER_MASK_INT, |
194 | }; | 194 | }; |
195 | 195 | ||
196 | #define ECC_ERASE_BUF_SZ (128 * 1024) | ||
196 | 197 | ||
197 | struct pdc_port_priv { | 198 | struct pdc_port_priv { |
198 | u8 dimm_buf[(ATA_PRD_SZ * ATA_MAX_PRD) + 512]; | 199 | u8 dimm_buf[(ATA_PRD_SZ * ATA_MAX_PRD) + 512]; |
@@ -1280,7 +1281,6 @@ static unsigned int pdc20621_dimm_init(struct ata_host *host) | |||
1280 | { | 1281 | { |
1281 | int speed, size, length; | 1282 | int speed, size, length; |
1282 | u32 addr, spd0, pci_status; | 1283 | u32 addr, spd0, pci_status; |
1283 | u32 tmp = 0; | ||
1284 | u32 time_period = 0; | 1284 | u32 time_period = 0; |
1285 | u32 tcount = 0; | 1285 | u32 tcount = 0; |
1286 | u32 ticks = 0; | 1286 | u32 ticks = 0; |
@@ -1395,14 +1395,17 @@ static unsigned int pdc20621_dimm_init(struct ata_host *host) | |||
1395 | pdc20621_i2c_read(host, PDC_DIMM0_SPD_DEV_ADDRESS, | 1395 | pdc20621_i2c_read(host, PDC_DIMM0_SPD_DEV_ADDRESS, |
1396 | PDC_DIMM_SPD_TYPE, &spd0); | 1396 | PDC_DIMM_SPD_TYPE, &spd0); |
1397 | if (spd0 == 0x02) { | 1397 | if (spd0 == 0x02) { |
1398 | void *buf; | ||
1398 | VPRINTK("Start ECC initialization\n"); | 1399 | VPRINTK("Start ECC initialization\n"); |
1399 | addr = 0; | 1400 | addr = 0; |
1400 | length = size * 1024 * 1024; | 1401 | length = size * 1024 * 1024; |
1402 | buf = kzalloc(ECC_ERASE_BUF_SZ, GFP_KERNEL); | ||
1401 | while (addr < length) { | 1403 | while (addr < length) { |
1402 | pdc20621_put_to_dimm(host, (void *) &tmp, addr, | 1404 | pdc20621_put_to_dimm(host, buf, addr, |
1403 | sizeof(u32)); | 1405 | ECC_ERASE_BUF_SZ); |
1404 | addr += sizeof(u32); | 1406 | addr += ECC_ERASE_BUF_SZ; |
1405 | } | 1407 | } |
1408 | kfree(buf); | ||
1406 | VPRINTK("Finish ECC initialization\n"); | 1409 | VPRINTK("Finish ECC initialization\n"); |
1407 | } | 1410 | } |
1408 | return 0; | 1411 | return 0; |