patch-2.1.44 linux/drivers/sbus/char/cgsix.c
Next file: linux/drivers/sbus/char/cgthree.c
Previous file: linux/drivers/sbus/char/cgfourteen.c
Back to the patch index
Back to the overall index
- Lines: 105
- Date:
Mon Jul 7 08:18:55 1997
- Orig file:
v2.1.43/linux/drivers/sbus/char/cgsix.c
- Orig date:
Mon Jun 16 16:35:56 1997
diff -u --recursive --new-file v2.1.43/linux/drivers/sbus/char/cgsix.c linux/drivers/sbus/char/cgsix.c
@@ -1,4 +1,4 @@
-/* $Id: cgsix.c,v 1.30 1997/06/04 08:27:28 davem Exp $
+/* $Id: cgsix.c,v 1.33 1997/07/01 09:12:05 jj Exp $
* cgsix.c: cgsix frame buffer driver
*
* Copyright (C) 1996 Miguel de Icaza (miguel@nuclecu.unam.mx)
@@ -233,12 +233,33 @@
long base, fbinfo_t *fb)
{
uint size, page, r, map_size;
- uint map_offset = 0;
-
+ unsigned long map_offset = 0;
+
size = vma->vm_end - vma->vm_start;
if (vma->vm_offset & ~PAGE_MASK)
return -ENXIO;
+#ifdef __sparc_v9__
+ /* Try to align RAM */
+#define ALIGNMENT 0x80000
+ map_offset = vma->vm_offset + size;
+ if (vma->vm_offset <= CG6_RAM && map_offset >= CG6_RAM + fb->type.fb_size) {
+ struct vm_area_struct *vmm = find_vma(current->mm, vma->vm_start);
+ int alignment = ALIGNMENT - ((vma->vm_start + CG6_RAM - vma->vm_offset) & (ALIGNMENT - 1));
+ int sz = 0, fbsz;
+
+ if (alignment == ALIGNMENT) alignment = 0;
+ fbsz = ((fb->type.fb_size + ALIGNMENT - 1) & ~(ALIGNMENT - 1));
+ if (map_offset < CG6_RAM + fbsz)
+ sz = fbsz - map_offset + CG6_RAM;
+ if ((sz || alignment) && (!vmm || vmm->vm_start >= vma->vm_end + sz + alignment)) {
+ vma->vm_start += alignment;
+ vma->vm_end += alignment + sz;
+ }
+ }
+#undef ALIGNMENT
+#endif
+
/* To stop the swapper from even considering these pages */
vma->vm_flags |= FB_MMAP_VM_FLAGS;
@@ -247,7 +268,7 @@
switch (vma->vm_offset+page){
case CG6_TEC:
map_size = PAGE_SIZE;
- map_offset = get_phys ((unsigned long)fb->info.cg6.tec);
+ map_offset = get_phys ((unsigned long)fb->info.cg6.tec) & PAGE_MASK;
break;
case CG6_FBC:
map_size = PAGE_SIZE;
@@ -259,18 +280,25 @@
break;
case CG6_THC:
map_size = PAGE_SIZE;
- map_offset = get_phys ((unsigned long)fb->info.cg6.thc);
+ map_offset = get_phys ((unsigned long)fb->info.cg6.thc) & PAGE_MASK;
break;
case CG6_BTREGS:
map_size = PAGE_SIZE;
map_offset = get_phys ((unsigned long)fb->info.cg6.bt);
break;
+
+ /* For Ultra, make sure the following two are right.
+ * The above two happen to work out (for example FBC and
+ * TEC will get mapped by one I/O page mapping because
+ * of the 8192 byte page size, same for FHC/THC. -DaveM
+ */
+
case CG6_DHC:
- map_size = PAGE_SIZE * 40;
+ map_size = /* PAGE_SIZE * 40 */ (4096 * 40);
map_offset = get_phys ((unsigned long)fb->info.cg6.dhc);
break;
case CG6_ROM:
- map_size = PAGE_SIZE * 16;
+ map_size = /* PAGE_SIZE * 16 */ (4096 * 16);
map_offset = get_phys ((unsigned long)fb->info.cg6.rom);
break;
case CG6_RAM:
@@ -449,14 +477,22 @@
sizeof (struct bt_regs), "cgsix_dac", cg6_io, 0);
cg6info->fhc = sparc_alloc_io (cg6+CG6_FHC_OFFSET, 0,
sizeof (int), "cgsix_fhc", cg6_io, 0);
+#if PAGE_SHIFT <= 12
cg6info->thc = sparc_alloc_io (cg6+CG6_THC_OFFSET, 0,
sizeof (struct cg6_thc), "cgsix_thc", cg6_io, 0);
+#else
+ cg6info->thc = (struct cg6_thc *)(((char *)cg6info->fhc)+0x1000);
+#endif
+ cg6info->fbc = sparc_alloc_io (cg6+CG6_FBC_OFFSET, 0,
+ 0x1000, "cgsix_fbc", cg6_io, 0);
+#if PAGE_SHIFT <= 12
cg6info->tec = sparc_alloc_io (cg6+CG6_TEC_OFFSET, 0,
sizeof (struct cg6_tec), "cgsix_tec", cg6_io, 0);
+#else
+ cg6info->tec = (struct cg6_tec *)(((char *)cg6info->fbc)+0x1000);
+#endif
cg6info->dhc = sparc_alloc_io (cg6+CG6_DHC_OFFSET, 0,
0x40000, "cgsix_dhc", cg6_io, 0);
- cg6info->fbc = sparc_alloc_io (cg6+CG6_FBC_OFFSET, 0,
- 0x1000, "cgsix_fbc", cg6_io, 0);
cg6info->rom = sparc_alloc_io (cg6+CG6_ROM_OFFSET, 0,
0x10000, "cgsix_rom", cg6_io, 0);
if (!fb->base) {
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov