diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2009-02-25 18:12:48 -0500 |
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2009-02-25 18:12:48 -0500 |
| commit | c4eb1bf63f3dc03611b79d6dd260dfa70c5e72f9 (patch) | |
| tree | 0f10702cae9263f445754aa581bc9ae297358388 | |
| parent | a36e4f0cab6311110d1703eafb325baead9caff8 (diff) | |
| parent | c55af1f5abf606118b32e3ce9c3b1bbce5236e7e (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] pata_legacy: for VLB 32bit PIO don't try tricks with slop
[libata] pata_amd: program FIFO
sata_mv: fix SoC interrupt breakage
pata_it821x: resume from hibernation fails with RAID volume
| -rw-r--r-- | drivers/ata/pata_amd.c | 76 | ||||
| -rw-r--r-- | drivers/ata/pata_it821x.c | 3 | ||||
| -rw-r--r-- | drivers/ata/pata_legacy.c | 7 | ||||
| -rw-r--r-- | drivers/ata/sata_mv.c | 20 |
4 files changed, 75 insertions, 31 deletions
diff --git a/drivers/ata/pata_amd.c b/drivers/ata/pata_amd.c index 63719ab9ea44..115b1cd6dcf5 100644 --- a/drivers/ata/pata_amd.c +++ b/drivers/ata/pata_amd.c | |||
| @@ -24,7 +24,7 @@ | |||
| 24 | #include <linux/libata.h> | 24 | #include <linux/libata.h> |
| 25 | 25 | ||
| 26 | #define DRV_NAME "pata_amd" | 26 | #define DRV_NAME "pata_amd" |
| 27 | #define DRV_VERSION "0.3.11" | 27 | #define DRV_VERSION "0.4.1" |
| 28 | 28 | ||
| 29 | /** | 29 | /** |
| 30 | * timing_setup - shared timing computation and load | 30 | * timing_setup - shared timing computation and load |
| @@ -145,6 +145,13 @@ static int amd_pre_reset(struct ata_link *link, unsigned long deadline) | |||
| 145 | return ata_sff_prereset(link, deadline); | 145 | return ata_sff_prereset(link, deadline); |
| 146 | } | 146 | } |
| 147 | 147 | ||
| 148 | /** | ||
| 149 | * amd_cable_detect - report cable type | ||
| 150 | * @ap: port | ||
| 151 | * | ||
| 152 | * AMD controller/BIOS setups record the cable type in word 0x42 | ||
| 153 | */ | ||
| 154 | |||
| 148 | static int amd_cable_detect(struct ata_port *ap) | 155 | static int amd_cable_detect(struct ata_port *ap) |
| 149 | { | 156 | { |
| 150 | static const u32 bitmask[2] = {0x03, 0x0C}; | 157 | static const u32 bitmask[2] = {0x03, 0x0C}; |
| @@ -158,6 +165,40 @@ static int amd_cable_detect(struct ata_port *ap) | |||
| 158 | } | 165 | } |
| 159 | 166 | ||
| 160 | /** | 167 | /** |
| 168 | * amd_fifo_setup - set the PIO FIFO for ATA/ATAPI | ||
| 169 | * @ap: ATA interface | ||
| 170 | * @adev: ATA device | ||
| 171 | * | ||
| 172 | * Set the PCI fifo for this device according to the devices present | ||
| 173 | * on the bus at this point in time. We need to turn the post write buffer | ||
| 174 | * off for ATAPI devices as we may need to issue a word sized write to the | ||
| 175 | * device as the final I/O | ||
| 176 | */ | ||
| 177 | |||
| 178 | static void amd_fifo_setup(struct ata_port *ap) | ||
| 179 | { | ||
| 180 | struct ata_device *adev; | ||
| 181 | struct pci_dev *pdev = to_pci_dev(ap->host->dev); | ||
| 182 | static const u8 fifobit[2] = { 0xC0, 0x30}; | ||
| 183 | u8 fifo = fifobit[ap->port_no]; | ||
| 184 | u8 r; | ||
| 185 | |||
| 186 | |||
| 187 | ata_for_each_dev(adev, &ap->link, ENABLED) { | ||
| 188 | if (adev->class == ATA_DEV_ATAPI) | ||
| 189 | fifo = 0; | ||
| 190 | } | ||
| 191 | if (pdev->device == PCI_DEVICE_ID_AMD_VIPER_7411) /* FIFO is broken */ | ||
| 192 | fifo = 0; | ||
| 193 | |||
| 194 | /* On the later chips the read prefetch bits become no-op bits */ | ||
| 195 | pci_read_config_byte(pdev, 0x41, &r); | ||
| 196 | r &= ~fifobit[ap->port_no]; | ||
| 197 | r |= fifo; | ||
| 198 | pci_write_config_byte(pdev, 0x41, r); | ||
| 199 | } | ||
| 200 | |||
| 201 | /** | ||
| 161 | * amd33_set_piomode - set initial PIO mode data | 202 | * amd33_set_piomode - set initial PIO mode data |
| 162 | * @ap: ATA interface | 203 | * @ap: ATA interface |
| 163 | * @adev: ATA device | 204 | * @adev: ATA device |
| @@ -167,21 +208,25 @@ static int amd_cable_detect(struct ata_port *ap) | |||
| 167 | 208 | ||
| 168 | static void amd33_set_piomode(struct ata_port *ap, struct ata_device *adev) | 209 | static void amd33_set_piomode(struct ata_port *ap, struct ata_device *adev) |
| 169 | { | 210 | { |
| 211 | amd_fifo_setup(ap); | ||
| 170 | timing_setup(ap, adev, 0x40, adev->pio_mode, 1); | 212 | timing_setup(ap, adev, 0x40, adev->pio_mode, 1); |
| 171 | } | 213 | } |
| 172 | 214 | ||
| 173 | static void amd66_set_piomode(struct ata_port *ap, struct ata_device *adev) | 215 | static void amd66_set_piomode(struct ata_port *ap, struct ata_device *adev) |
| 174 | { | 216 | { |
| 217 | amd_fifo_setup(ap); | ||
| 175 | timing_setup(ap, adev, 0x40, adev->pio_mode, 2); | 218 | timing_setup(ap, adev, 0x40, adev->pio_mode, 2); |
| 176 | } | 219 | } |
| 177 | 220 | ||
| 178 | static void amd100_set_piomode(struct ata_port *ap, struct ata_device *adev) | 221 | static void amd100_set_piomode(struct ata_port *ap, struct ata_device *adev) |
| 179 | { | 222 | { |
| 223 | amd_fifo_setup(ap); | ||
| 180 | timing_setup(ap, adev, 0x40, adev->pio_mode, 3); | 224 | timing_setup(ap, adev, 0x40, adev->pio_mode, 3); |
| 181 | } | 225 | } |
| 182 | 226 | ||
| 183 | static void amd133_set_piomode(struct ata_port *ap, struct ata_device *adev) | 227 | static void amd133_set_piomode(struct ata_port *ap, struct ata_device *adev) |
| 184 | { | 228 | { |
| 229 | amd_fifo_setup(ap); | ||
| 185 | timing_setup(ap, adev, 0x40, adev->pio_mode, 4); | 230 | timing_setup(ap, adev, 0x40, adev->pio_mode, 4); |
| 186 | } | 231 | } |
| 187 | 232 | ||
| @@ -397,6 +442,16 @@ static struct ata_port_operations nv133_port_ops = { | |||
| 397 | .set_dmamode = nv133_set_dmamode, | 442 | .set_dmamode = nv133_set_dmamode, |
| 398 | }; | 443 | }; |
| 399 | 444 | ||
| 445 | static void amd_clear_fifo(struct pci_dev *pdev) | ||
| 446 | { | ||
| 447 | u8 fifo; | ||
| 448 | /* Disable the FIFO, the FIFO logic will re-enable it as | ||
| 449 | appropriate */ | ||
| 450 | pci_read_config_byte(pdev, 0x41, &fifo); | ||
| 451 | fifo &= 0x0F; | ||
| 452 | pci_write_config_byte(pdev, 0x41, fifo); | ||
| 453 | } | ||
| 454 | |||
| 400 | static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | 455 | static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id) |
| 401 | { | 456 | { |
| 402 | static const struct ata_port_info info[10] = { | 457 | static const struct ata_port_info info[10] = { |
| @@ -503,14 +558,8 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
| 503 | 558 | ||
| 504 | if (type < 3) | 559 | if (type < 3) |
| 505 | ata_pci_bmdma_clear_simplex(pdev); | 560 | ata_pci_bmdma_clear_simplex(pdev); |
| 506 | 561 | if (pdev->vendor == PCI_VENDOR_ID_AMD) | |
| 507 | /* Check for AMD7411 */ | 562 | amd_clear_fifo(pdev); |
| 508 | if (type == 3) | ||
| 509 | /* FIFO is broken */ | ||
| 510 | pci_write_config_byte(pdev, 0x41, fifo & 0x0F); | ||
| 511 | else | ||
| 512 | pci_write_config_byte(pdev, 0x41, fifo | 0xF0); | ||
| 513 | |||
| 514 | /* Cable detection on Nvidia chips doesn't work too well, | 563 | /* Cable detection on Nvidia chips doesn't work too well, |
| 515 | * cache BIOS programmed UDMA mode. | 564 | * cache BIOS programmed UDMA mode. |
| 516 | */ | 565 | */ |
| @@ -536,18 +585,11 @@ static int amd_reinit_one(struct pci_dev *pdev) | |||
| 536 | return rc; | 585 | return rc; |
| 537 | 586 | ||
| 538 | if (pdev->vendor == PCI_VENDOR_ID_AMD) { | 587 | if (pdev->vendor == PCI_VENDOR_ID_AMD) { |
| 539 | u8 fifo; | 588 | amd_clear_fifo(pdev); |
| 540 | pci_read_config_byte(pdev, 0x41, &fifo); | ||
| 541 | if (pdev->device == PCI_DEVICE_ID_AMD_VIPER_7411) | ||
| 542 | /* FIFO is broken */ | ||
| 543 | pci_write_config_byte(pdev, 0x41, fifo & 0x0F); | ||
| 544 | else | ||
| 545 | pci_write_config_byte(pdev, 0x41, fifo | 0xF0); | ||
| 546 | if (pdev->device == PCI_DEVICE_ID_AMD_VIPER_7409 || | 589 | if (pdev->device == PCI_DEVICE_ID_AMD_VIPER_7409 || |
| 547 | pdev->device == PCI_DEVICE_ID_AMD_COBRA_7401) | 590 | pdev->device == PCI_DEVICE_ID_AMD_COBRA_7401) |
| 548 | ata_pci_bmdma_clear_simplex(pdev); | 591 | ata_pci_bmdma_clear_simplex(pdev); |
| 549 | } | 592 | } |
| 550 | |||
| 551 | ata_host_resume(host); | 593 | ata_host_resume(host); |
| 552 | return 0; | 594 | return 0; |
| 553 | } | 595 | } |
diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c index f1bb2f9fecbf..b05b86a912c5 100644 --- a/drivers/ata/pata_it821x.c +++ b/drivers/ata/pata_it821x.c | |||
| @@ -557,6 +557,9 @@ static unsigned int it821x_read_id(struct ata_device *adev, | |||
| 557 | id[83] |= 0x4400; /* Word 83 is valid and LBA48 */ | 557 | id[83] |= 0x4400; /* Word 83 is valid and LBA48 */ |
| 558 | id[86] |= 0x0400; /* LBA48 on */ | 558 | id[86] |= 0x0400; /* LBA48 on */ |
| 559 | id[ATA_ID_MAJOR_VER] |= 0x1F; | 559 | id[ATA_ID_MAJOR_VER] |= 0x1F; |
| 560 | /* Clear the serial number because it's different each boot | ||
| 561 | which breaks validation on resume */ | ||
| 562 | memset(&id[ATA_ID_SERNO], 0x20, ATA_ID_SERNO_LEN); | ||
| 560 | } | 563 | } |
| 561 | return err_mask; | 564 | return err_mask; |
| 562 | } | 565 | } |
diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c index 6c1d778b63a9..e3bc1b436284 100644 --- a/drivers/ata/pata_legacy.c +++ b/drivers/ata/pata_legacy.c | |||
| @@ -283,9 +283,10 @@ static void pdc20230_set_piomode(struct ata_port *ap, struct ata_device *adev) | |||
| 283 | static unsigned int pdc_data_xfer_vlb(struct ata_device *dev, | 283 | static unsigned int pdc_data_xfer_vlb(struct ata_device *dev, |
| 284 | unsigned char *buf, unsigned int buflen, int rw) | 284 | unsigned char *buf, unsigned int buflen, int rw) |
| 285 | { | 285 | { |
| 286 | if (ata_id_has_dword_io(dev->id)) { | 286 | int slop = buflen & 3; |
| 287 | /* 32bit I/O capable *and* we need to write a whole number of dwords */ | ||
| 288 | if (ata_id_has_dword_io(dev->id) && (slop == 0 || slop == 3)) { | ||
| 287 | struct ata_port *ap = dev->link->ap; | 289 | struct ata_port *ap = dev->link->ap; |
| 288 | int slop = buflen & 3; | ||
| 289 | unsigned long flags; | 290 | unsigned long flags; |
| 290 | 291 | ||
| 291 | local_irq_save(flags); | 292 | local_irq_save(flags); |
| @@ -735,7 +736,7 @@ static unsigned int vlb32_data_xfer(struct ata_device *adev, unsigned char *buf, | |||
| 735 | struct ata_port *ap = adev->link->ap; | 736 | struct ata_port *ap = adev->link->ap; |
| 736 | int slop = buflen & 3; | 737 | int slop = buflen & 3; |
| 737 | 738 | ||
| 738 | if (ata_id_has_dword_io(adev->id)) { | 739 | if (ata_id_has_dword_io(adev->id) && (slop == 0 || slop == 3)) { |
| 739 | if (rw == WRITE) | 740 | if (rw == WRITE) |
| 740 | iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2); | 741 | iowrite32_rep(ap->ioaddr.data_addr, buf, buflen >> 2); |
| 741 | else | 742 | else |
diff --git a/drivers/ata/sata_mv.c b/drivers/ata/sata_mv.c index 4ae1a4138b47..7007edd2d451 100644 --- a/drivers/ata/sata_mv.c +++ b/drivers/ata/sata_mv.c | |||
| @@ -3114,19 +3114,17 @@ static int mv_init_host(struct ata_host *host, unsigned int board_idx) | |||
| 3114 | writelfl(0, hc_mmio + HC_IRQ_CAUSE_OFS); | 3114 | writelfl(0, hc_mmio + HC_IRQ_CAUSE_OFS); |
| 3115 | } | 3115 | } |
| 3116 | 3116 | ||
| 3117 | if (!IS_SOC(hpriv)) { | 3117 | /* Clear any currently outstanding host interrupt conditions */ |
| 3118 | /* Clear any currently outstanding host interrupt conditions */ | 3118 | writelfl(0, mmio + hpriv->irq_cause_ofs); |
| 3119 | writelfl(0, mmio + hpriv->irq_cause_ofs); | ||
| 3120 | 3119 | ||
| 3121 | /* and unmask interrupt generation for host regs */ | 3120 | /* and unmask interrupt generation for host regs */ |
| 3122 | writelfl(hpriv->unmask_all_irqs, mmio + hpriv->irq_mask_ofs); | 3121 | writelfl(hpriv->unmask_all_irqs, mmio + hpriv->irq_mask_ofs); |
| 3123 | 3122 | ||
| 3124 | /* | 3123 | /* |
| 3125 | * enable only global host interrupts for now. | 3124 | * enable only global host interrupts for now. |
| 3126 | * The per-port interrupts get done later as ports are set up. | 3125 | * The per-port interrupts get done later as ports are set up. |
| 3127 | */ | 3126 | */ |
| 3128 | mv_set_main_irq_mask(host, 0, PCI_ERR); | 3127 | mv_set_main_irq_mask(host, 0, PCI_ERR); |
| 3129 | } | ||
| 3130 | done: | 3128 | done: |
| 3131 | return rc; | 3129 | return rc; |
| 3132 | } | 3130 | } |
