Commit f8cc5756 authored by Linus Torvalds's avatar Linus Torvalds

Merge master.kernel.org:/pub/scm/linux/kernel/git/davem/sparc-2.6

parents bf7c7dec b4d1b825
This diff is collapsed.
...@@ -1207,13 +1207,9 @@ static void psycho_scan_bus(struct pci_controller_info *p) ...@@ -1207,13 +1207,9 @@ static void psycho_scan_bus(struct pci_controller_info *p)
static void psycho_iommu_init(struct pci_controller_info *p) static void psycho_iommu_init(struct pci_controller_info *p)
{ {
struct pci_iommu *iommu = p->pbm_A.iommu; struct pci_iommu *iommu = p->pbm_A.iommu;
unsigned long tsbbase, i; unsigned long i;
u64 control; u64 control;
/* Setup initial software IOMMU state. */
spin_lock_init(&iommu->lock);
iommu->ctx_lowest_free = 1;
/* Register addresses. */ /* Register addresses. */
iommu->iommu_control = p->pbm_A.controller_regs + PSYCHO_IOMMU_CONTROL; iommu->iommu_control = p->pbm_A.controller_regs + PSYCHO_IOMMU_CONTROL;
iommu->iommu_tsbbase = p->pbm_A.controller_regs + PSYCHO_IOMMU_TSBBASE; iommu->iommu_tsbbase = p->pbm_A.controller_regs + PSYCHO_IOMMU_TSBBASE;
...@@ -1240,40 +1236,10 @@ static void psycho_iommu_init(struct pci_controller_info *p) ...@@ -1240,40 +1236,10 @@ static void psycho_iommu_init(struct pci_controller_info *p)
/* Leave diag mode enabled for full-flushing done /* Leave diag mode enabled for full-flushing done
* in pci_iommu.c * in pci_iommu.c
*/ */
pci_iommu_table_init(iommu, IO_TSB_SIZE, 0xc0000000, 0xffffffff);
iommu->dummy_page = __get_free_pages(GFP_KERNEL, 0); psycho_write(p->pbm_A.controller_regs + PSYCHO_IOMMU_TSBBASE,
if (!iommu->dummy_page) { __pa(iommu->page_table));
prom_printf("PSYCHO_IOMMU: Error, gfp(dummy_page) failed.\n");
prom_halt();
}
memset((void *)iommu->dummy_page, 0, PAGE_SIZE);
iommu->dummy_page_pa = (unsigned long) __pa(iommu->dummy_page);
/* Using assumed page size 8K with 128K entries we need 1MB iommu page
* table (128K ioptes * 8 bytes per iopte). This is
* page order 7 on UltraSparc.
*/
tsbbase = __get_free_pages(GFP_KERNEL, get_order(IO_TSB_SIZE));
if (!tsbbase) {
prom_printf("PSYCHO_IOMMU: Error, gfp(tsb) failed.\n");
prom_halt();
}
iommu->page_table = (iopte_t *)tsbbase;
iommu->page_table_sz_bits = 17;
iommu->page_table_map_base = 0xc0000000;
iommu->dma_addr_mask = 0xffffffff;
pci_iommu_table_init(iommu, IO_TSB_SIZE);
/* We start with no consistent mappings. */
iommu->lowest_consistent_map =
1 << (iommu->page_table_sz_bits - PBM_LOGCLUSTERS);
for (i = 0; i < PBM_NCLUSTERS; i++) {
iommu->alloc_info[i].flush = 0;
iommu->alloc_info[i].next = 0;
}
psycho_write(p->pbm_A.controller_regs + PSYCHO_IOMMU_TSBBASE, __pa(tsbbase));
control = psycho_read(p->pbm_A.controller_regs + PSYCHO_IOMMU_CONTROL); control = psycho_read(p->pbm_A.controller_regs + PSYCHO_IOMMU_CONTROL);
control &= ~(PSYCHO_IOMMU_CTRL_TSBSZ | PSYCHO_IOMMU_CTRL_TBWSZ); control &= ~(PSYCHO_IOMMU_CTRL_TSBSZ | PSYCHO_IOMMU_CTRL_TBWSZ);
...@@ -1281,7 +1247,7 @@ static void psycho_iommu_init(struct pci_controller_info *p) ...@@ -1281,7 +1247,7 @@ static void psycho_iommu_init(struct pci_controller_info *p)
psycho_write(p->pbm_A.controller_regs + PSYCHO_IOMMU_CONTROL, control); psycho_write(p->pbm_A.controller_regs + PSYCHO_IOMMU_CONTROL, control);
/* If necessary, hook us up for starfire IRQ translations. */ /* If necessary, hook us up for starfire IRQ translations. */
if(this_is_starfire) if (this_is_starfire)
p->starfire_cookie = starfire_hookup(p->pbm_A.portid); p->starfire_cookie = starfire_hookup(p->pbm_A.portid);
else else
p->starfire_cookie = NULL; p->starfire_cookie = NULL;
......
...@@ -1267,13 +1267,9 @@ static void sabre_iommu_init(struct pci_controller_info *p, ...@@ -1267,13 +1267,9 @@ static void sabre_iommu_init(struct pci_controller_info *p,
u32 dma_mask) u32 dma_mask)
{ {
struct pci_iommu *iommu = p->pbm_A.iommu; struct pci_iommu *iommu = p->pbm_A.iommu;
unsigned long tsbbase, i, order; unsigned long i;
u64 control; u64 control;
/* Setup initial software IOMMU state. */
spin_lock_init(&iommu->lock);
iommu->ctx_lowest_free = 1;
/* Register addresses. */ /* Register addresses. */
iommu->iommu_control = p->pbm_A.controller_regs + SABRE_IOMMU_CONTROL; iommu->iommu_control = p->pbm_A.controller_regs + SABRE_IOMMU_CONTROL;
iommu->iommu_tsbbase = p->pbm_A.controller_regs + SABRE_IOMMU_TSBBASE; iommu->iommu_tsbbase = p->pbm_A.controller_regs + SABRE_IOMMU_TSBBASE;
...@@ -1295,26 +1291,10 @@ static void sabre_iommu_init(struct pci_controller_info *p, ...@@ -1295,26 +1291,10 @@ static void sabre_iommu_init(struct pci_controller_info *p,
/* Leave diag mode enabled for full-flushing done /* Leave diag mode enabled for full-flushing done
* in pci_iommu.c * in pci_iommu.c
*/ */
pci_iommu_table_init(iommu, tsbsize * 1024 * 8, dvma_offset, dma_mask);
iommu->dummy_page = __get_free_pages(GFP_KERNEL, 0); sabre_write(p->pbm_A.controller_regs + SABRE_IOMMU_TSBBASE,
if (!iommu->dummy_page) { __pa(iommu->page_table));
prom_printf("PSYCHO_IOMMU: Error, gfp(dummy_page) failed.\n");
prom_halt();
}
memset((void *)iommu->dummy_page, 0, PAGE_SIZE);
iommu->dummy_page_pa = (unsigned long) __pa(iommu->dummy_page);
tsbbase = __get_free_pages(GFP_KERNEL, order = get_order(tsbsize * 1024 * 8));
if (!tsbbase) {
prom_printf("SABRE_IOMMU: Error, gfp(tsb) failed.\n");
prom_halt();
}
iommu->page_table = (iopte_t *)tsbbase;
iommu->page_table_map_base = dvma_offset;
iommu->dma_addr_mask = dma_mask;
pci_iommu_table_init(iommu, PAGE_SIZE << order);
sabre_write(p->pbm_A.controller_regs + SABRE_IOMMU_TSBBASE, __pa(tsbbase));
control = sabre_read(p->pbm_A.controller_regs + SABRE_IOMMU_CONTROL); control = sabre_read(p->pbm_A.controller_regs + SABRE_IOMMU_CONTROL);
control &= ~(SABRE_IOMMUCTRL_TSBSZ | SABRE_IOMMUCTRL_TBWSZ); control &= ~(SABRE_IOMMUCTRL_TSBSZ | SABRE_IOMMUCTRL_TBWSZ);
...@@ -1322,11 +1302,9 @@ static void sabre_iommu_init(struct pci_controller_info *p, ...@@ -1322,11 +1302,9 @@ static void sabre_iommu_init(struct pci_controller_info *p,
switch(tsbsize) { switch(tsbsize) {
case 64: case 64:
control |= SABRE_IOMMU_TSBSZ_64K; control |= SABRE_IOMMU_TSBSZ_64K;
iommu->page_table_sz_bits = 16;
break; break;
case 128: case 128:
control |= SABRE_IOMMU_TSBSZ_128K; control |= SABRE_IOMMU_TSBSZ_128K;
iommu->page_table_sz_bits = 17;
break; break;
default: default:
prom_printf("iommu_init: Illegal TSB size %d\n", tsbsize); prom_printf("iommu_init: Illegal TSB size %d\n", tsbsize);
...@@ -1334,15 +1312,6 @@ static void sabre_iommu_init(struct pci_controller_info *p, ...@@ -1334,15 +1312,6 @@ static void sabre_iommu_init(struct pci_controller_info *p,
break; break;
} }
sabre_write(p->pbm_A.controller_regs + SABRE_IOMMU_CONTROL, control); sabre_write(p->pbm_A.controller_regs + SABRE_IOMMU_CONTROL, control);
/* We start with no consistent mappings. */
iommu->lowest_consistent_map =
1 << (iommu->page_table_sz_bits - PBM_LOGCLUSTERS);
for (i = 0; i < PBM_NCLUSTERS; i++) {
iommu->alloc_info[i].flush = 0;
iommu->alloc_info[i].next = 0;
}
} }
static void pbm_register_toplevel_resources(struct pci_controller_info *p, static void pbm_register_toplevel_resources(struct pci_controller_info *p,
......
...@@ -1765,7 +1765,7 @@ static void schizo_pbm_strbuf_init(struct pci_pbm_info *pbm) ...@@ -1765,7 +1765,7 @@ static void schizo_pbm_strbuf_init(struct pci_pbm_info *pbm)
static void schizo_pbm_iommu_init(struct pci_pbm_info *pbm) static void schizo_pbm_iommu_init(struct pci_pbm_info *pbm)
{ {
struct pci_iommu *iommu = pbm->iommu; struct pci_iommu *iommu = pbm->iommu;
unsigned long tsbbase, i, tagbase, database, order; unsigned long i, tagbase, database;
u32 vdma[2], dma_mask; u32 vdma[2], dma_mask;
u64 control; u64 control;
int err, tsbsize; int err, tsbsize;
...@@ -1800,10 +1800,6 @@ static void schizo_pbm_iommu_init(struct pci_pbm_info *pbm) ...@@ -1800,10 +1800,6 @@ static void schizo_pbm_iommu_init(struct pci_pbm_info *pbm)
prom_halt(); prom_halt();
}; };
/* Setup initial software IOMMU state. */
spin_lock_init(&iommu->lock);
iommu->ctx_lowest_free = 1;
/* Register addresses, SCHIZO has iommu ctx flushing. */ /* Register addresses, SCHIZO has iommu ctx flushing. */
iommu->iommu_control = pbm->pbm_regs + SCHIZO_IOMMU_CONTROL; iommu->iommu_control = pbm->pbm_regs + SCHIZO_IOMMU_CONTROL;
iommu->iommu_tsbbase = pbm->pbm_regs + SCHIZO_IOMMU_TSBBASE; iommu->iommu_tsbbase = pbm->pbm_regs + SCHIZO_IOMMU_TSBBASE;
...@@ -1832,56 +1828,9 @@ static void schizo_pbm_iommu_init(struct pci_pbm_info *pbm) ...@@ -1832,56 +1828,9 @@ static void schizo_pbm_iommu_init(struct pci_pbm_info *pbm)
/* Leave diag mode enabled for full-flushing done /* Leave diag mode enabled for full-flushing done
* in pci_iommu.c * in pci_iommu.c
*/ */
pci_iommu_table_init(iommu, tsbsize * 8 * 1024, vdma[0], dma_mask);
iommu->dummy_page = __get_free_pages(GFP_KERNEL, 0); schizo_write(iommu->iommu_tsbbase, __pa(iommu->page_table));
if (!iommu->dummy_page) {
prom_printf("PSYCHO_IOMMU: Error, gfp(dummy_page) failed.\n");
prom_halt();
}
memset((void *)iommu->dummy_page, 0, PAGE_SIZE);
iommu->dummy_page_pa = (unsigned long) __pa(iommu->dummy_page);
/* Using assumed page size 8K with 128K entries we need 1MB iommu page
* table (128K ioptes * 8 bytes per iopte). This is
* page order 7 on UltraSparc.
*/
order = get_order(tsbsize * 8 * 1024);
tsbbase = __get_free_pages(GFP_KERNEL, order);
if (!tsbbase) {
prom_printf("%s: Error, gfp(tsb) failed.\n", pbm->name);
prom_halt();
}
iommu->page_table = (iopte_t *)tsbbase;
iommu->page_table_map_base = vdma[0];
iommu->dma_addr_mask = dma_mask;
pci_iommu_table_init(iommu, PAGE_SIZE << order);
switch (tsbsize) {
case 64:
iommu->page_table_sz_bits = 16;
break;
case 128:
iommu->page_table_sz_bits = 17;
break;
default:
prom_printf("iommu_init: Illegal TSB size %d\n", tsbsize);
prom_halt();
break;
};
/* We start with no consistent mappings. */
iommu->lowest_consistent_map =
1 << (iommu->page_table_sz_bits - PBM_LOGCLUSTERS);
for (i = 0; i < PBM_NCLUSTERS; i++) {
iommu->alloc_info[i].flush = 0;
iommu->alloc_info[i].next = 0;
}
schizo_write(iommu->iommu_tsbbase, __pa(tsbbase));
control = schizo_read(iommu->iommu_control); control = schizo_read(iommu->iommu_control);
control &= ~(SCHIZO_IOMMU_CTRL_TSBSZ | SCHIZO_IOMMU_CTRL_TBWSZ); control &= ~(SCHIZO_IOMMU_CTRL_TSBSZ | SCHIZO_IOMMU_CTRL_TBWSZ);
......
...@@ -1001,13 +1001,6 @@ void smp_penguin_jailcell(int irq, struct pt_regs *regs) ...@@ -1001,13 +1001,6 @@ void smp_penguin_jailcell(int irq, struct pt_regs *regs)
preempt_enable(); preempt_enable();
} }
extern unsigned long xcall_promstop;
void smp_promstop_others(void)
{
smp_cross_call(&xcall_promstop, 0, 0, 0);
}
#define prof_multiplier(__cpu) cpu_data(__cpu).multiplier #define prof_multiplier(__cpu) cpu_data(__cpu).multiplier
#define prof_counter(__cpu) cpu_data(__cpu).counter #define prof_counter(__cpu) cpu_data(__cpu).counter
......
...@@ -453,22 +453,6 @@ xcall_flush_dcache_page_spitfire: /* %g1 == physical page address ...@@ -453,22 +453,6 @@ xcall_flush_dcache_page_spitfire: /* %g1 == physical page address
nop nop
nop nop
.globl xcall_promstop
xcall_promstop:
rdpr %pstate, %g2
wrpr %g2, PSTATE_IG | PSTATE_AG, %pstate
rdpr %pil, %g2
wrpr %g0, 15, %pil
sethi %hi(109f), %g7
b,pt %xcc, etrap_irq
109: or %g7, %lo(109b), %g7
flushw
call prom_stopself
nop
/* We should not return, just spin if we do... */
1: b,a,pt %xcc, 1b
nop
.data .data
errata32_hwbug: errata32_hwbug:
......
...@@ -68,19 +68,11 @@ void prom_cmdline(void) ...@@ -68,19 +68,11 @@ void prom_cmdline(void)
local_irq_restore(flags); local_irq_restore(flags);
} }
#ifdef CONFIG_SMP
extern void smp_promstop_others(void);
#endif
/* Drop into the prom, but completely terminate the program. /* Drop into the prom, but completely terminate the program.
* No chance of continuing. * No chance of continuing.
*/ */
void prom_halt(void) void prom_halt(void)
{ {
#ifdef CONFIG_SMP
smp_promstop_others();
udelay(8000);
#endif
again: again:
p1275_cmd("exit", P1275_INOUT(0, 0)); p1275_cmd("exit", P1275_INOUT(0, 0));
goto again; /* PROM is out to get me -DaveM */ goto again; /* PROM is out to get me -DaveM */
...@@ -88,10 +80,6 @@ again: ...@@ -88,10 +80,6 @@ again:
void prom_halt_power_off(void) void prom_halt_power_off(void)
{ {
#ifdef CONFIG_SMP
smp_promstop_others();
udelay(8000);
#endif
p1275_cmd("SUNW,power-off", P1275_INOUT(0, 0)); p1275_cmd("SUNW,power-off", P1275_INOUT(0, 0));
/* if nothing else helps, we just halt */ /* if nothing else helps, we just halt */
......
...@@ -1119,6 +1119,36 @@ static inline void update_can_queue(struct Scsi_Host *host, u_int in_ptr, u_int ...@@ -1119,6 +1119,36 @@ static inline void update_can_queue(struct Scsi_Host *host, u_int in_ptr, u_int
host->sg_tablesize = QLOGICPTI_MAX_SG(num_free); host->sg_tablesize = QLOGICPTI_MAX_SG(num_free);
} }
static unsigned int scsi_rbuf_get(struct scsi_cmnd *cmd, unsigned char **buf_out)
{
unsigned char *buf;
unsigned int buflen;
if (cmd->use_sg) {
struct scatterlist *sg;
sg = (struct scatterlist *) cmd->request_buffer;
buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset;
buflen = sg->length;
} else {
buf = cmd->request_buffer;
buflen = cmd->request_bufflen;
}
*buf_out = buf;
return buflen;
}
static void scsi_rbuf_put(struct scsi_cmnd *cmd, unsigned char *buf)
{
if (cmd->use_sg) {
struct scatterlist *sg;
sg = (struct scatterlist *) cmd->request_buffer;
kunmap_atomic(buf - sg->offset, KM_IRQ0);
}
}
/* /*
* Until we scan the entire bus with inquiries, go throught this fella... * Until we scan the entire bus with inquiries, go throught this fella...
*/ */
...@@ -1145,11 +1175,9 @@ static void ourdone(struct scsi_cmnd *Cmnd) ...@@ -1145,11 +1175,9 @@ static void ourdone(struct scsi_cmnd *Cmnd)
int ok = host_byte(Cmnd->result) == DID_OK; int ok = host_byte(Cmnd->result) == DID_OK;
if (Cmnd->cmnd[0] == 0x12 && ok) { if (Cmnd->cmnd[0] == 0x12 && ok) {
unsigned char *iqd; unsigned char *iqd;
unsigned int iqd_len;
if (Cmnd->use_sg != 0) iqd_len = scsi_rbuf_get(Cmnd, &iqd);
BUG();
iqd = ((unsigned char *)Cmnd->buffer);
/* tags handled in midlayer */ /* tags handled in midlayer */
/* enable sync mode? */ /* enable sync mode? */
...@@ -1163,6 +1191,9 @@ static void ourdone(struct scsi_cmnd *Cmnd) ...@@ -1163,6 +1191,9 @@ static void ourdone(struct scsi_cmnd *Cmnd)
if (iqd[7] & 0x20) { if (iqd[7] & 0x20) {
qpti->dev_param[tgt].device_flags |= 0x20; qpti->dev_param[tgt].device_flags |= 0x20;
} }
scsi_rbuf_put(Cmnd, iqd);
qpti->sbits |= (1 << tgt); qpti->sbits |= (1 << tgt);
} else if (!ok) { } else if (!ok) {
qpti->sbits |= (1 << tgt); qpti->sbits |= (1 << tgt);
......
...@@ -27,23 +27,27 @@ ...@@ -27,23 +27,27 @@
* PCI bus. * PCI bus.
*/ */
#define PBM_LOGCLUSTERS 3
#define PBM_NCLUSTERS (1 << PBM_LOGCLUSTERS)
struct pci_controller_info; struct pci_controller_info;
/* This contains the software state necessary to drive a PCI /* This contains the software state necessary to drive a PCI
* controller's IOMMU. * controller's IOMMU.
*/ */
struct pci_iommu_arena {
unsigned long *map;
unsigned int hint;
unsigned int limit;
};
struct pci_iommu { struct pci_iommu {
/* This protects the controller's IOMMU and all /* This protects the controller's IOMMU and all
* streaming buffers underneath. * streaming buffers underneath.
*/ */
spinlock_t lock; spinlock_t lock;
struct pci_iommu_arena arena;
/* IOMMU page table, a linear array of ioptes. */ /* IOMMU page table, a linear array of ioptes. */
iopte_t *page_table; /* The page table itself. */ iopte_t *page_table; /* The page table itself. */
int page_table_sz_bits; /* log2 of ow many pages does it map? */
/* Base PCI memory space address where IOMMU mappings /* Base PCI memory space address where IOMMU mappings
* begin. * begin.
...@@ -62,12 +66,6 @@ struct pci_iommu { ...@@ -62,12 +66,6 @@ struct pci_iommu {
*/ */
unsigned long write_complete_reg; unsigned long write_complete_reg;
/* The lowest used consistent mapping entry. Since
* we allocate consistent maps out of cluster 0 this
* is relative to the beginning of closter 0.
*/
u32 lowest_consistent_map;
/* In order to deal with some buggy third-party PCI bridges that /* In order to deal with some buggy third-party PCI bridges that
* do wrong prefetching, we never mark valid mappings as invalid. * do wrong prefetching, we never mark valid mappings as invalid.
* Instead we point them at this dummy page. * Instead we point them at this dummy page.
...@@ -75,16 +73,6 @@ struct pci_iommu { ...@@ -75,16 +73,6 @@ struct pci_iommu {
unsigned long dummy_page; unsigned long dummy_page;
unsigned long dummy_page_pa; unsigned long dummy_page_pa;
/* If PBM_NCLUSTERS is ever decreased to 4 or lower,
* or if largest supported page_table_sz * 8K goes above
* 2GB, you must increase the size of the type of
* these counters. You have been duly warned. -DaveM
*/
struct {
u16 next;
u16 flush;
} alloc_info[PBM_NCLUSTERS];
/* CTX allocation. */ /* CTX allocation. */
unsigned long ctx_lowest_free; unsigned long ctx_lowest_free;
unsigned long ctx_bitmap[IOMMU_NUM_CTXS / (sizeof(unsigned long) * 8)]; unsigned long ctx_bitmap[IOMMU_NUM_CTXS / (sizeof(unsigned long) * 8)];
...@@ -102,7 +90,7 @@ struct pci_iommu { ...@@ -102,7 +90,7 @@ struct pci_iommu {
u32 dma_addr_mask; u32 dma_addr_mask;
}; };
extern void pci_iommu_table_init(struct pci_iommu *, int); extern void pci_iommu_table_init(struct pci_iommu *iommu, int tsbsize, u32 dma_offset, u32 dma_addr_mask);
/* This describes a PCI bus module's streaming buffer. */ /* This describes a PCI bus module's streaming buffer. */
struct pci_strbuf { struct pci_strbuf {
......
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