Commit 90d2aee3 authored by Linus Torvalds's avatar Linus Torvalds

Merge bk://gkernel.bkbits.net/libata-2.5

into ppc970.osdl.org:/home/torvalds/v2.5/linux
parents 7265df88 333f957c
/* /*
libata-core.c - helper library for ATA libata-core.c - helper library for ATA
Copyright 2003 Red Hat, Inc. All rights reserved. Copyright 2003-2004 Red Hat, Inc. All rights reserved.
Copyright 2003 Jeff Garzik Copyright 2003-2004 Jeff Garzik
The contents of this file are subject to the Open The contents of this file are subject to the Open
Software License version 1.1 that can be found at Software License version 1.1 that can be found at
...@@ -1653,18 +1653,41 @@ void ata_fill_sg(struct ata_queued_cmd *qc) ...@@ -1653,18 +1653,41 @@ void ata_fill_sg(struct ata_queued_cmd *qc)
{ {
struct scatterlist *sg = qc->sg; struct scatterlist *sg = qc->sg;
struct ata_port *ap = qc->ap; struct ata_port *ap = qc->ap;
unsigned int i; unsigned int idx, nelem;
assert(sg != NULL); assert(sg != NULL);
assert(qc->n_elem > 0); assert(qc->n_elem > 0);
for (i = 0; i < qc->n_elem; i++) { idx = 0;
ap->prd[i].addr = cpu_to_le32(sg_dma_address(&sg[i])); for (nelem = qc->n_elem; nelem; nelem--,sg++) {
ap->prd[i].flags_len = cpu_to_le32(sg_dma_len(&sg[i])); u32 addr, boundary;
VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", u32 sg_len, len;
i, le32_to_cpu(ap->prd[i].addr), le32_to_cpu(ap->prd[i].flags_len));
/* determine if physical DMA addr spans 64K boundary.
* Note h/w doesn't support 64-bit, so we unconditionally
* truncate dma_addr_t to u32.
*/
addr = (u32) sg_dma_address(sg);
sg_len = sg_dma_len(sg);
while (sg_len) {
boundary = (addr & ~0xffff) + (0xffff + 1);
len = sg_len;
if ((addr + sg_len) > boundary)
len = boundary - addr;
ap->prd[idx].addr = cpu_to_le32(addr);
ap->prd[idx].flags_len = cpu_to_le32(len & 0xffff);
VPRINTK("PRD[%u] = (0x%X, 0x%X)\n", idx, addr, len);
idx++;
sg_len -= len;
addr += len;
}
} }
ap->prd[qc->n_elem - 1].flags_len |= cpu_to_le32(ATA_PRD_EOT);
if (idx)
ap->prd[idx - 1].flags_len |= cpu_to_le32(ATA_PRD_EOT);
} }
/** /**
...@@ -2385,41 +2408,6 @@ static inline unsigned int ata_host_intr (struct ata_port *ap, ...@@ -2385,41 +2408,6 @@ static inline unsigned int ata_host_intr (struct ata_port *ap,
return handled; return handled;
} }
/**
* ata_chk_spurious_int - Check for spurious interrupts
* @ap: port to which command is being issued
*
* Examines the DMA status registers and clears
* unexpected interrupts. Created to work around
* hardware bug on Intel ICH5, but is applied to all
* chipsets using the standard irq handler, just for safety.
* If the bug is not present, this is simply a single
* PIO or MMIO read addition to the irq handler.
*
* LOCKING:
*/
static inline void ata_chk_spurious_int(struct ata_port *ap) {
int host_stat;
if (ap->flags & ATA_FLAG_MMIO) {
void *mmio = (void *) ap->ioaddr.bmdma_addr;
host_stat = readb(mmio + ATA_DMA_STATUS);
} else
host_stat = inb(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
if ((host_stat & (ATA_DMA_INTR | ATA_DMA_ERR | ATA_DMA_ACTIVE)) == ATA_DMA_INTR) {
if (ap->flags & ATA_FLAG_MMIO) {
void *mmio = (void *) ap->ioaddr.bmdma_addr;
writeb(host_stat & ~ATA_DMA_ERR, mmio + ATA_DMA_STATUS);
} else
outb(host_stat & ~ATA_DMA_ERR, ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
DPRINTK("ata%u: Caught spurious interrupt, status 0x%X\n", ap->id, host_stat);
udelay(1);
}
}
/** /**
* ata_interrupt - * ata_interrupt -
* @irq: * @irq:
...@@ -2452,7 +2440,6 @@ irqreturn_t ata_interrupt (int irq, void *dev_instance, struct pt_regs *regs) ...@@ -2452,7 +2440,6 @@ irqreturn_t ata_interrupt (int irq, void *dev_instance, struct pt_regs *regs)
qc = ata_qc_from_tag(ap, ap->active_tag); qc = ata_qc_from_tag(ap, ap->active_tag);
if (qc && ((qc->flags & ATA_QCFLAG_POLL) == 0)) if (qc && ((qc->flags & ATA_QCFLAG_POLL) == 0))
handled += ata_host_intr(ap, qc); handled += ata_host_intr(ap, qc);
ata_chk_spurious_int(ap);
} }
} }
......
...@@ -123,6 +123,7 @@ int ata_scsi_slave_config(struct scsi_device *sdev) ...@@ -123,6 +123,7 @@ int ata_scsi_slave_config(struct scsi_device *sdev)
{ {
sdev->use_10_for_rw = 1; sdev->use_10_for_rw = 1;
sdev->use_10_for_ms = 1; sdev->use_10_for_ms = 1;
blk_queue_max_phys_segments(sdev->request_queue, ATA_MAX_PRD / 2);
return 0; /* scsi layer doesn't check return value, sigh */ return 0; /* scsi layer doesn't check return value, sigh */
} }
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
#define __LIBATA_H__ #define __LIBATA_H__
#define DRV_NAME "libata" #define DRV_NAME "libata"
#define DRV_VERSION "1.00" /* must be exactly four chars */ #define DRV_VERSION "1.01" /* must be exactly four chars */
struct ata_scsi_args { struct ata_scsi_args {
struct ata_port *ap; struct ata_port *ap;
......
...@@ -35,7 +35,7 @@ ...@@ -35,7 +35,7 @@
#include <asm/io.h> #include <asm/io.h>
#define DRV_NAME "sata_promise" #define DRV_NAME "sata_promise"
#define DRV_VERSION "0.89" #define DRV_VERSION "0.90"
enum { enum {
...@@ -115,7 +115,12 @@ enum { ...@@ -115,7 +115,12 @@ enum {
PDC_DIMM_SPD_SYSTEM_FREQ = 126, PDC_DIMM_SPD_SYSTEM_FREQ = 126,
PDC_CTL_STATUS = 0x08, PDC_CTL_STATUS = 0x08,
PDC_DIMM_WINDOW_CTLR = 0x0C, PDC_DIMM_WINDOW_CTLR = 0x0C,
PDC_TIME_CONTROL = 0x3C,
PDC_TIME_PERIOD = 0x40,
PDC_TIME_COUNTER = 0x44,
PDC_GENERAL_CTLR = 0x484, PDC_GENERAL_CTLR = 0x484,
PCI_PLL_INIT = 0x8A531824,
PCI_X_TCOUNT = 0xEE1E5CFF
}; };
...@@ -1454,13 +1459,64 @@ static unsigned int pdc20621_dimm_init(struct ata_probe_ent *pe) ...@@ -1454,13 +1459,64 @@ static unsigned int pdc20621_dimm_init(struct ata_probe_ent *pe)
int speed, size, length; int speed, size, length;
u32 addr,spd0,pci_status; u32 addr,spd0,pci_status;
u32 tmp=0; u32 tmp=0;
u32 time_period=0;
u32 tcount=0;
u32 ticks=0;
u32 clock=0;
u32 fparam=0;
void *mmio = pe->mmio_base; void *mmio = pe->mmio_base;
/* hard-code chip #0 */ /* hard-code chip #0 */
mmio += PDC_CHIP0_OFS; mmio += PDC_CHIP0_OFS;
/* Initialize PLL based upon PCI Bus Frequency */
/* Initialize Time Period Register */
writel(0xffffffff, mmio + PDC_TIME_PERIOD);
time_period = readl(mmio + PDC_TIME_PERIOD);
VPRINTK("Time Period Register (0x40): 0x%x\n", time_period);
/* Enable timer */
writel(0x00001a0, mmio + PDC_TIME_CONTROL);
readl(mmio + PDC_TIME_CONTROL);
/* Wait 3 seconds */
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(3 * HZ);
/*
When timer is enabled, counter is decreased every internal
clock cycle.
*/
tcount = readl(mmio + PDC_TIME_COUNTER);
VPRINTK("Time Counter Register (0x44): 0x%x\n", tcount);
/*
If SX4 is on PCI-X bus, after 3 seconds, the timer counter
register should be >= (0xffffffff - 3x10^8).
*/
if(tcount >= PCI_X_TCOUNT) {
ticks = (time_period - tcount);
VPRINTK("Num counters 0x%x (%d)\n", ticks, ticks);
clock = (ticks / 300000);
VPRINTK("10 * Internal clk = 0x%x (%d)\n", clock, clock);
clock = (clock * 33);
VPRINTK("10 * Internal clk * 33 = 0x%x (%d)\n", clock, clock);
/* PLL F Param (bit 22:16) */
fparam = (1400000 / clock) - 2;
VPRINTK("PLL F Param: 0x%x (%d)\n", fparam, fparam);
/* OD param = 0x2 (bit 31:30), R param = 0x5 (bit 29:25) */
pci_status = (0x8a001824 | (fparam << 16));
} else
pci_status = PCI_PLL_INIT;
/* Initialize PLL. */ /* Initialize PLL. */
pci_status = 0x8a531824; VPRINTK("pci_status: 0x%x\n", pci_status);
writel(pci_status, mmio + PDC_CTL_STATUS); writel(pci_status, mmio + PDC_CTL_STATUS);
readl(mmio + PDC_CTL_STATUS); readl(mmio + PDC_CTL_STATUS);
......
...@@ -35,7 +35,7 @@ ...@@ -35,7 +35,7 @@
#include <linux/libata.h> #include <linux/libata.h>
#define DRV_NAME "sata_sil" #define DRV_NAME "sata_sil"
#define DRV_VERSION "0.52" #define DRV_VERSION "0.53"
enum { enum {
sil_3112 = 0, sil_3112 = 0,
...@@ -44,6 +44,11 @@ enum { ...@@ -44,6 +44,11 @@ enum {
SIL_SYSCFG = 0x48, SIL_SYSCFG = 0x48,
SIL_MASK_IDE0_INT = (1 << 22), SIL_MASK_IDE0_INT = (1 << 22),
SIL_MASK_IDE1_INT = (1 << 23), SIL_MASK_IDE1_INT = (1 << 23),
SIL_MASK_IDE2_INT = (1 << 24),
SIL_MASK_IDE3_INT = (1 << 25),
SIL_MASK_2PORT = SIL_MASK_IDE0_INT | SIL_MASK_IDE1_INT,
SIL_MASK_4PORT = SIL_MASK_2PORT |
SIL_MASK_IDE2_INT | SIL_MASK_IDE3_INT,
SIL_IDE0_TF = 0x80, SIL_IDE0_TF = 0x80,
SIL_IDE0_CTL = 0x8A, SIL_IDE0_CTL = 0x8A,
...@@ -59,6 +64,7 @@ enum { ...@@ -59,6 +64,7 @@ enum {
SIL_IDE2_CTL = 0x28A, SIL_IDE2_CTL = 0x28A,
SIL_IDE2_BMDMA = 0x200, SIL_IDE2_BMDMA = 0x200,
SIL_IDE2_SCR = 0x300, SIL_IDE2_SCR = 0x300,
SIL_INTR_STEERING = (1 << 1),
SIL_IDE3_TF = 0x2C0, SIL_IDE3_TF = 0x2C0,
SIL_IDE3_CTL = 0x2CA, SIL_IDE3_CTL = 0x2CA,
...@@ -304,7 +310,7 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -304,7 +310,7 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
unsigned long base; unsigned long base;
void *mmio_base; void *mmio_base;
int rc; int rc;
u32 tmp; u32 tmp, irq_mask;
if (!printed_version++) if (!printed_version++)
printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n"); printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
...@@ -365,14 +371,6 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -365,14 +371,6 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
probe_ent->port[1].scr_addr = base + SIL_IDE1_SCR; probe_ent->port[1].scr_addr = base + SIL_IDE1_SCR;
ata_std_ports(&probe_ent->port[1]); ata_std_ports(&probe_ent->port[1]);
/* make sure IDE0/1 interrupts are not masked */
tmp = readl(mmio_base + SIL_SYSCFG);
if (tmp & (SIL_MASK_IDE0_INT | SIL_MASK_IDE1_INT)) {
tmp &= ~(SIL_MASK_IDE0_INT | SIL_MASK_IDE1_INT);
writel(tmp, mmio_base + SIL_SYSCFG);
readl(mmio_base + SIL_SYSCFG); /* flush */
}
if (ent->driver_data == sil_3114) { if (ent->driver_data == sil_3114) {
probe_ent->port[2].cmd_addr = base + SIL_IDE2_TF; probe_ent->port[2].cmd_addr = base + SIL_IDE2_TF;
probe_ent->port[2].ctl_addr = base + SIL_IDE2_CTL; probe_ent->port[2].ctl_addr = base + SIL_IDE2_CTL;
...@@ -385,6 +383,25 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) ...@@ -385,6 +383,25 @@ static int sil_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
probe_ent->port[3].bmdma_addr = base + SIL_IDE3_BMDMA; probe_ent->port[3].bmdma_addr = base + SIL_IDE3_BMDMA;
probe_ent->port[3].scr_addr = base + SIL_IDE3_SCR; probe_ent->port[3].scr_addr = base + SIL_IDE3_SCR;
ata_std_ports(&probe_ent->port[3]); ata_std_ports(&probe_ent->port[3]);
irq_mask = SIL_MASK_4PORT;
/* flip the magic "make 4 ports work" bit */
tmp = readl(mmio_base + SIL_IDE2_BMDMA);
if ((tmp & SIL_INTR_STEERING) == 0)
writel(tmp | SIL_INTR_STEERING,
mmio_base + SIL_IDE2_BMDMA);
} else {
irq_mask = SIL_MASK_2PORT;
}
/* make sure IDE0/1/2/3 interrupts are not masked */
tmp = readl(mmio_base + SIL_SYSCFG);
if (tmp & irq_mask) {
tmp &= ~irq_mask;
writel(tmp, mmio_base + SIL_SYSCFG);
readl(mmio_base + SIL_SYSCFG); /* flush */
} }
pci_set_master(pdev); pci_set_master(pdev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment