aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2008-07-21 00:55:14 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2008-07-21 00:55:14 -0400
commit908cf4b925e419bc74f3297b2f0e51d6f8a81da2 (patch)
tree6c2da79366d4695a9c2560ab18259eca8a2a25b4 /drivers/char
parent92c49890922d54cba4b1eadeb0b185773c2c9570 (diff)
parent14b395e35d1afdd8019d11b92e28041fad591b71 (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/torvalds/linux-2.6 into next
Diffstat (limited to 'drivers/char')
-rw-r--r--drivers/char/Kconfig20
-rw-r--r--drivers/char/Makefile2
-rw-r--r--drivers/char/agp/agp.h6
-rw-r--r--drivers/char/agp/alpha-agp.c4
-rw-r--r--drivers/char/agp/amd-k7-agp.c4
-rw-r--r--drivers/char/agp/amd64-agp.c89
-rw-r--r--drivers/char/agp/ati-agp.c8
-rw-r--r--drivers/char/agp/backend.c16
-rw-r--r--drivers/char/agp/compat_ioctl.c2
-rw-r--r--drivers/char/agp/efficeon-agp.c6
-rw-r--r--drivers/char/agp/frontend.c16
-rw-r--r--drivers/char/agp/generic.c37
-rw-r--r--drivers/char/agp/hp-agp.c6
-rw-r--r--drivers/char/agp/i460-agp.c2
-rw-r--r--drivers/char/agp/intel-agp.c239
-rw-r--r--drivers/char/agp/nvidia-agp.c4
-rw-r--r--drivers/char/agp/parisc-agp.c6
-rw-r--r--drivers/char/agp/sgi-agp.c8
-rw-r--r--drivers/char/agp/sworks-agp.c6
-rw-r--r--drivers/char/agp/uninorth-agp.c10
-rw-r--r--drivers/char/agp/via-agp.c13
-rw-r--r--drivers/char/apm-emulation.c349
-rw-r--r--drivers/char/briq_panel.c9
-rw-r--r--drivers/char/bsr.c312
-rw-r--r--drivers/char/cs5535_gpio.c2
-rw-r--r--drivers/char/cyclades.c352
-rw-r--r--drivers/char/drm/Kconfig107
-rw-r--r--drivers/char/drm/Makefile40
-rw-r--r--drivers/char/drm/README.drm43
-rw-r--r--drivers/char/drm/ati_pcigart.c183
-rw-r--r--drivers/char/drm/drm.h711
-rw-r--r--drivers/char/drm/drmP.h1210
-rw-r--r--drivers/char/drm/drm_agpsupport.c455
-rw-r--r--drivers/char/drm/drm_auth.c190
-rw-r--r--drivers/char/drm/drm_bufs.c1601
-rw-r--r--drivers/char/drm/drm_context.c471
-rw-r--r--drivers/char/drm/drm_core.h34
-rw-r--r--drivers/char/drm/drm_dma.c180
-rw-r--r--drivers/char/drm/drm_drawable.c192
-rw-r--r--drivers/char/drm/drm_drv.c539
-rw-r--r--drivers/char/drm/drm_fops.c469
-rw-r--r--drivers/char/drm/drm_hashtab.c202
-rw-r--r--drivers/char/drm/drm_hashtab.h67
-rw-r--r--drivers/char/drm/drm_ioc32.c1073
-rw-r--r--drivers/char/drm/drm_ioctl.c352
-rw-r--r--drivers/char/drm/drm_irq.c731
-rw-r--r--drivers/char/drm/drm_lock.c396
-rw-r--r--drivers/char/drm/drm_memory.c181
-rw-r--r--drivers/char/drm/drm_memory.h61
-rw-r--r--drivers/char/drm/drm_memory_debug.h309
-rw-r--r--drivers/char/drm/drm_mm.c295
-rw-r--r--drivers/char/drm/drm_os_linux.h108
-rw-r--r--drivers/char/drm/drm_pci.c183
-rw-r--r--drivers/char/drm/drm_pciids.h414
-rw-r--r--drivers/char/drm/drm_proc.c557
-rw-r--r--drivers/char/drm/drm_sarea.h84
-rw-r--r--drivers/char/drm/drm_scatter.c227
-rw-r--r--drivers/char/drm/drm_sman.c353
-rw-r--r--drivers/char/drm/drm_sman.h176
-rw-r--r--drivers/char/drm/drm_stub.c331
-rw-r--r--drivers/char/drm/drm_sysfs.c210
-rw-r--r--drivers/char/drm/drm_vm.c673
-rw-r--r--drivers/char/drm/i810_dma.c1283
-rw-r--r--drivers/char/drm/i810_drm.h281
-rw-r--r--drivers/char/drm/i810_drv.c97
-rw-r--r--drivers/char/drm/i810_drv.h242
-rw-r--r--drivers/char/drm/i830_dma.c1553
-rw-r--r--drivers/char/drm/i830_drm.h342
-rw-r--r--drivers/char/drm/i830_drv.c108
-rw-r--r--drivers/char/drm/i830_drv.h292
-rw-r--r--drivers/char/drm/i830_irq.c186
-rw-r--r--drivers/char/drm/i915_dma.c936
-rw-r--r--drivers/char/drm/i915_drm.h297
-rw-r--r--drivers/char/drm/i915_drv.c597
-rw-r--r--drivers/char/drm/i915_drv.h1204
-rw-r--r--drivers/char/drm/i915_ioc32.c222
-rw-r--r--drivers/char/drm/i915_irq.c916
-rw-r--r--drivers/char/drm/i915_mem.c386
-rw-r--r--drivers/char/drm/mga_dma.c1162
-rw-r--r--drivers/char/drm/mga_drm.h417
-rw-r--r--drivers/char/drm/mga_drv.c142
-rw-r--r--drivers/char/drm/mga_drv.h691
-rw-r--r--drivers/char/drm/mga_ioc32.c231
-rw-r--r--drivers/char/drm/mga_irq.c181
-rw-r--r--drivers/char/drm/mga_state.c1104
-rw-r--r--drivers/char/drm/mga_ucode.h11645
-rw-r--r--drivers/char/drm/mga_warp.c193
-rw-r--r--drivers/char/drm/r128_cce.c935
-rw-r--r--drivers/char/drm/r128_drm.h326
-rw-r--r--drivers/char/drm/r128_drv.c104
-rw-r--r--drivers/char/drm/r128_drv.h525
-rw-r--r--drivers/char/drm/r128_ioc32.c221
-rw-r--r--drivers/char/drm/r128_irq.c116
-rw-r--r--drivers/char/drm/r128_state.c1681
-rw-r--r--drivers/char/drm/r300_cmdbuf.c998
-rw-r--r--drivers/char/drm/r300_reg.h1626
-rw-r--r--drivers/char/drm/radeon_cp.c2435
-rw-r--r--drivers/char/drm/radeon_drm.h741
-rw-r--r--drivers/char/drm/radeon_drv.c126
-rw-r--r--drivers/char/drm/radeon_drv.h1308
-rw-r--r--drivers/char/drm/radeon_ioc32.c424
-rw-r--r--drivers/char/drm/radeon_irq.c315
-rw-r--r--drivers/char/drm/radeon_mem.c302
-rw-r--r--drivers/char/drm/radeon_state.c3192
-rw-r--r--drivers/char/drm/savage_bci.c1095
-rw-r--r--drivers/char/drm/savage_drm.h210
-rw-r--r--drivers/char/drm/savage_drv.c88
-rw-r--r--drivers/char/drm/savage_drv.h575
-rw-r--r--drivers/char/drm/savage_state.c1163
-rw-r--r--drivers/char/drm/sis_drm.h67
-rw-r--r--drivers/char/drm/sis_drv.c117
-rw-r--r--drivers/char/drm/sis_drv.h73
-rw-r--r--drivers/char/drm/sis_mm.c333
-rw-r--r--drivers/char/drm/tdfx_drv.c84
-rw-r--r--drivers/char/drm/tdfx_drv.h47
-rw-r--r--drivers/char/drm/via_3d_reg.h1650
-rw-r--r--drivers/char/drm/via_dma.c755
-rw-r--r--drivers/char/drm/via_dmablit.c816
-rw-r--r--drivers/char/drm/via_dmablit.h140
-rw-r--r--drivers/char/drm/via_drm.h275
-rw-r--r--drivers/char/drm/via_drv.c102
-rw-r--r--drivers/char/drm/via_drv.h156
-rw-r--r--drivers/char/drm/via_irq.c390
-rw-r--r--drivers/char/drm/via_map.c123
-rw-r--r--drivers/char/drm/via_mm.c194
-rw-r--r--drivers/char/drm/via_verifier.c1116
-rw-r--r--drivers/char/drm/via_verifier.h62
-rw-r--r--drivers/char/drm/via_video.c93
-rw-r--r--drivers/char/ds1286.c4
-rw-r--r--drivers/char/ds1620.c9
-rw-r--r--drivers/char/dsp56k.c100
-rw-r--r--drivers/char/dtlk.c3
-rw-r--r--drivers/char/efirtc.c2
-rw-r--r--drivers/char/epca.c110
-rw-r--r--drivers/char/epca.h7
-rw-r--r--drivers/char/esp.c272
-rw-r--r--drivers/char/generic_nvram.c2
-rw-r--r--drivers/char/generic_serial.c158
-rw-r--r--drivers/char/genrtc.c7
-rw-r--r--drivers/char/hpet.c4
-rw-r--r--drivers/char/hvc_console.c8
-rw-r--r--drivers/char/hvc_console.h10
-rw-r--r--drivers/char/hvc_xen.c61
-rw-r--r--drivers/char/hw_random/Kconfig9
-rw-r--r--drivers/char/hw_random/Makefile1
-rw-r--r--drivers/char/hw_random/core.c2
-rw-r--r--drivers/char/hw_random/intel-rng.c2
-rw-r--r--drivers/char/hw_random/pasemi-rng.c2
-rw-r--r--drivers/char/hw_random/virtio-rng.c155
-rw-r--r--drivers/char/ip2/Makefile4
-rw-r--r--drivers/char/ip2/fip_firm.h2149
-rw-r--r--drivers/char/ip2/i2lib.c4
-rw-r--r--drivers/char/ip2/ip2base.c5
-rw-r--r--drivers/char/ip2/ip2main.c111
-rw-r--r--drivers/char/ip27-rtc.c4
-rw-r--r--drivers/char/ipmi/ipmi_devintf.c10
-rw-r--r--drivers/char/ipmi/ipmi_watchdog.c6
-rw-r--r--drivers/char/isicom.c215
-rw-r--r--drivers/char/istallion.c116
-rw-r--r--drivers/char/keyboard.c7
-rw-r--r--drivers/char/lcd.c3
-rw-r--r--drivers/char/lp.c38
-rw-r--r--drivers/char/mbcs.c5
-rw-r--r--drivers/char/mem.c10
-rw-r--r--drivers/char/misc.c3
-rw-r--r--drivers/char/moxa.c97
-rw-r--r--drivers/char/mwave/mwavedd.c2
-rw-r--r--drivers/char/mxser.c284
-rw-r--r--drivers/char/n_hdlc.c6
-rw-r--r--drivers/char/n_r3964.c2
-rw-r--r--drivers/char/n_tty.c2
-rw-r--r--drivers/char/nvram.c6
-rw-r--r--drivers/char/pc8736x_gpio.c2
-rw-r--r--drivers/char/pcmcia/cm4000_cs.c118
-rw-r--r--drivers/char/pcmcia/cm4040_cs.c23
-rw-r--r--drivers/char/pcmcia/ipwireless/hardware.c24
-rw-r--r--drivers/char/pcmcia/ipwireless/main.c1
-rw-r--r--drivers/char/pcmcia/synclink_cs.c32
-rw-r--r--drivers/char/ppdev.c2
-rw-r--r--drivers/char/pty.c10
-rw-r--r--drivers/char/raw.c3
-rw-r--r--drivers/char/rio/cirrus.h3
-rw-r--r--drivers/char/rio/cmdblk.h6
-rw-r--r--drivers/char/rio/cmdpkt.h6
-rw-r--r--drivers/char/rio/daemon.h6
-rw-r--r--drivers/char/rio/errors.h6
-rw-r--r--drivers/char/rio/func.h6
-rw-r--r--drivers/char/rio/map.h4
-rw-r--r--drivers/char/rio/param.h5
-rw-r--r--drivers/char/rio/parmmap.h7
-rw-r--r--drivers/char/rio/pci.h4
-rw-r--r--drivers/char/rio/protsts.h7
-rw-r--r--drivers/char/rio/rio_linux.c25
-rw-r--r--drivers/char/rio/rioboard.h6
-rw-r--r--drivers/char/rio/riocmd.c13
-rw-r--r--drivers/char/rio/rioctrl.c4
-rw-r--r--drivers/char/rio/riodrvr.h4
-rw-r--r--drivers/char/rio/rioinfo.h4
-rw-r--r--drivers/char/rio/rioinit.c3
-rw-r--r--drivers/char/rio/riointr.c14
-rw-r--r--drivers/char/rio/rioparam.c6
-rw-r--r--drivers/char/rio/rioroute.c3
-rw-r--r--drivers/char/rio/riospace.h4
-rw-r--r--drivers/char/rio/riotable.c3
-rw-r--r--drivers/char/rio/riotty.c20
-rw-r--r--drivers/char/rio/route.h6
-rw-r--r--drivers/char/rio/unixrup.h4
-rw-r--r--drivers/char/riscom8.c187
-rw-r--r--drivers/char/riscom8.h10
-rw-r--r--drivers/char/rocket.c139
-rw-r--r--drivers/char/rocket.h4
-rw-r--r--drivers/char/rocket_int.h11
-rw-r--r--drivers/char/rtc.c7
-rw-r--r--drivers/char/scx200_gpio.c2
-rw-r--r--drivers/char/selection.c3
-rw-r--r--drivers/char/snsc.c5
-rw-r--r--drivers/char/snsc_event.c2
-rw-r--r--drivers/char/sonypi.c3
-rw-r--r--drivers/char/specialix.c153
-rw-r--r--drivers/char/specialix_io8.h8
-rw-r--r--drivers/char/stallion.c160
-rw-r--r--drivers/char/sx.c115
-rw-r--r--drivers/char/synclink.c246
-rw-r--r--drivers/char/synclink_gt.c247
-rw-r--r--drivers/char/synclinkmp.c250
-rw-r--r--drivers/char/sysrq.c3
-rw-r--r--drivers/char/tb0219.c2
-rw-r--r--drivers/char/tlclk.c19
-rw-r--r--drivers/char/tpm/tpm.c5
-rw-r--r--drivers/char/tpm/tpm_tis.c1
-rw-r--r--drivers/char/tty_io.c463
-rw-r--r--drivers/char/tty_ioctl.c23
-rw-r--r--drivers/char/vc_screen.c9
-rw-r--r--drivers/char/viocons.c2
-rw-r--r--drivers/char/viotape.c28
-rw-r--r--drivers/char/vme_scc.c4
-rw-r--r--drivers/char/vr41xx_giu.c2
-rw-r--r--drivers/char/vt.c15
-rw-r--r--drivers/char/xilinx_hwicap/xilinx_hwicap.c6
239 files changed, 3311 insertions, 67977 deletions
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index 595a925c62a9..650e6b44ce65 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -118,8 +118,8 @@ config COMPUTONE
118 order to become a dial-in server. If you have a card like that, say 118 order to become a dial-in server. If you have a card like that, say
119 Y here and read <file:Documentation/computone.txt>. 119 Y here and read <file:Documentation/computone.txt>.
120 120
121 To compile this driver as modules, choose M here: the 121 To compile this driver as module, choose M here: the
122 modules will be called ip2 and ip2main. 122 module will be called ip2.
123 123
124config ROCKETPORT 124config ROCKETPORT
125 tristate "Comtrol RocketPort support" 125 tristate "Comtrol RocketPort support"
@@ -649,6 +649,14 @@ config HVCS
649 which will also be compiled when this driver is built as a 649 which will also be compiled when this driver is built as a
650 module. 650 module.
651 651
652config IBM_BSR
653 tristate "IBM POWER Barrier Synchronization Register support"
654 depends on PPC_PSERIES
655 help
656 This devices exposes a hardware mechanism for fast synchronization
657 of threads across a large system which avoids bouncing a cacheline
658 between several cores on a system
659
652source "drivers/char/ipmi/Kconfig" 660source "drivers/char/ipmi/Kconfig"
653 661
654config DS1620 662config DS1620
@@ -749,7 +757,7 @@ config NVRAM
749if RTC_LIB=n 757if RTC_LIB=n
750 758
751config RTC 759config RTC
752 tristate "Enhanced Real Time Clock Support" 760 tristate "Enhanced Real Time Clock Support (legacy PC RTC driver)"
753 depends on !PPC && !PARISC && !IA64 && !M68K && !SPARC && !FRV \ 761 depends on !PPC && !PARISC && !IA64 && !M68K && !SPARC && !FRV \
754 && !ARM && !SUPERH && !S390 && !AVR32 762 && !ARM && !SUPERH && !S390 && !AVR32
755 ---help--- 763 ---help---
@@ -1036,9 +1044,9 @@ config HPET
1036 non-periodic and/or periodic. 1044 non-periodic and/or periodic.
1037 1045
1038config HPET_RTC_IRQ 1046config HPET_RTC_IRQ
1039 bool "HPET Control RTC IRQ" if !HPET_EMULATE_RTC 1047 bool
1040 default n 1048 default HPET_EMULATE_RTC
1041 depends on HPET 1049 depends on RTC && HPET
1042 help 1050 help
1043 If you say Y here, you will disable RTC_IRQ in drivers/char/rtc.c. It 1051 If you say Y here, you will disable RTC_IRQ in drivers/char/rtc.c. It
1044 is assumed the platform called hpet_alloc with the RTC IRQ values for 1052 is assumed the platform called hpet_alloc with the RTC IRQ values for
diff --git a/drivers/char/Makefile b/drivers/char/Makefile
index 4c1c584e9eb6..0e0d12a06462 100644
--- a/drivers/char/Makefile
+++ b/drivers/char/Makefile
@@ -57,6 +57,7 @@ obj-$(CONFIG_MMTIMER) += mmtimer.o
57obj-$(CONFIG_VIOCONS) += viocons.o 57obj-$(CONFIG_VIOCONS) += viocons.o
58obj-$(CONFIG_VIOTAPE) += viotape.o 58obj-$(CONFIG_VIOTAPE) += viotape.o
59obj-$(CONFIG_HVCS) += hvcs.o 59obj-$(CONFIG_HVCS) += hvcs.o
60obj-$(CONFIG_IBM_BSR) += bsr.o
60obj-$(CONFIG_SGI_MBCS) += mbcs.o 61obj-$(CONFIG_SGI_MBCS) += mbcs.o
61obj-$(CONFIG_BRIQ_PANEL) += briq_panel.o 62obj-$(CONFIG_BRIQ_PANEL) += briq_panel.o
62obj-$(CONFIG_BFIN_OTP) += bfin-otp.o 63obj-$(CONFIG_BFIN_OTP) += bfin-otp.o
@@ -101,7 +102,6 @@ obj-$(CONFIG_TELCLOCK) += tlclk.o
101 102
102obj-$(CONFIG_MWAVE) += mwave/ 103obj-$(CONFIG_MWAVE) += mwave/
103obj-$(CONFIG_AGP) += agp/ 104obj-$(CONFIG_AGP) += agp/
104obj-$(CONFIG_DRM) += drm/
105obj-$(CONFIG_PCMCIA) += pcmcia/ 105obj-$(CONFIG_PCMCIA) += pcmcia/
106obj-$(CONFIG_IPMI_HANDLER) += ipmi/ 106obj-$(CONFIG_IPMI_HANDLER) += ipmi/
107 107
diff --git a/drivers/char/agp/agp.h b/drivers/char/agp/agp.h
index 99e6a406efb4..81e14bea54bd 100644
--- a/drivers/char/agp/agp.h
+++ b/drivers/char/agp/agp.h
@@ -99,8 +99,8 @@ struct agp_bridge_driver {
99 const void *aperture_sizes; 99 const void *aperture_sizes;
100 int num_aperture_sizes; 100 int num_aperture_sizes;
101 enum aper_size_type size_type; 101 enum aper_size_type size_type;
102 int cant_use_aperture; 102 bool cant_use_aperture;
103 int needs_scratch_page; 103 bool needs_scratch_page;
104 const struct gatt_mask *masks; 104 const struct gatt_mask *masks;
105 int (*fetch_size)(void); 105 int (*fetch_size)(void);
106 int (*configure)(void); 106 int (*configure)(void);
@@ -278,7 +278,7 @@ void agp_generic_destroy_page(void *addr, int flags);
278void agp_free_key(int key); 278void agp_free_key(int key);
279int agp_num_entries(void); 279int agp_num_entries(void);
280u32 agp_collect_device_status(struct agp_bridge_data *bridge, u32 mode, u32 command); 280u32 agp_collect_device_status(struct agp_bridge_data *bridge, u32 mode, u32 command);
281void agp_device_command(u32 command, int agp_v3); 281void agp_device_command(u32 command, bool agp_v3);
282int agp_3_5_enable(struct agp_bridge_data *bridge); 282int agp_3_5_enable(struct agp_bridge_data *bridge);
283void global_cache_flush(void); 283void global_cache_flush(void);
284void get_agp_version(struct agp_bridge_data *bridge); 284void get_agp_version(struct agp_bridge_data *bridge);
diff --git a/drivers/char/agp/alpha-agp.c b/drivers/char/agp/alpha-agp.c
index e77c17838c8a..5da89f6c6c25 100644
--- a/drivers/char/agp/alpha-agp.c
+++ b/drivers/char/agp/alpha-agp.c
@@ -80,7 +80,7 @@ static void alpha_core_agp_enable(struct agp_bridge_data *bridge, u32 mode)
80 agp->mode.bits.enable = 1; 80 agp->mode.bits.enable = 1;
81 agp->ops->configure(agp); 81 agp->ops->configure(agp);
82 82
83 agp_device_command(agp->mode.lw, 0); 83 agp_device_command(agp->mode.lw, false);
84} 84}
85 85
86static int alpha_core_agp_insert_memory(struct agp_memory *mem, off_t pg_start, 86static int alpha_core_agp_insert_memory(struct agp_memory *mem, off_t pg_start,
@@ -126,7 +126,7 @@ struct agp_bridge_driver alpha_core_agp_driver = {
126 .aperture_sizes = alpha_core_agp_sizes, 126 .aperture_sizes = alpha_core_agp_sizes,
127 .num_aperture_sizes = 1, 127 .num_aperture_sizes = 1,
128 .size_type = FIXED_APER_SIZE, 128 .size_type = FIXED_APER_SIZE,
129 .cant_use_aperture = 1, 129 .cant_use_aperture = true,
130 .masks = NULL, 130 .masks = NULL,
131 131
132 .fetch_size = alpha_core_agp_fetch_size, 132 .fetch_size = alpha_core_agp_fetch_size,
diff --git a/drivers/char/agp/amd-k7-agp.c b/drivers/char/agp/amd-k7-agp.c
index 96bdb9296b07..39a0718bc616 100644
--- a/drivers/char/agp/amd-k7-agp.c
+++ b/drivers/char/agp/amd-k7-agp.c
@@ -314,9 +314,9 @@ static int amd_insert_memory(struct agp_memory *mem, off_t pg_start, int type)
314 j++; 314 j++;
315 } 315 }
316 316
317 if (mem->is_flushed == FALSE) { 317 if (!mem->is_flushed) {
318 global_cache_flush(); 318 global_cache_flush();
319 mem->is_flushed = TRUE; 319 mem->is_flushed = true;
320 } 320 }
321 321
322 for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { 322 for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
diff --git a/drivers/char/agp/amd64-agp.c b/drivers/char/agp/amd64-agp.c
index d8200ac8f8cb..481ffe87c716 100644
--- a/drivers/char/agp/amd64-agp.c
+++ b/drivers/char/agp/amd64-agp.c
@@ -16,28 +16,9 @@
16#include <asm/page.h> /* PAGE_SIZE */ 16#include <asm/page.h> /* PAGE_SIZE */
17#include <asm/e820.h> 17#include <asm/e820.h>
18#include <asm/k8.h> 18#include <asm/k8.h>
19#include <asm/gart.h>
19#include "agp.h" 20#include "agp.h"
20 21
21/* PTE bits. */
22#define GPTE_VALID 1
23#define GPTE_COHERENT 2
24
25/* Aperture control register bits. */
26#define GARTEN (1<<0)
27#define DISGARTCPU (1<<4)
28#define DISGARTIO (1<<5)
29
30/* GART cache control register bits. */
31#define INVGART (1<<0)
32#define GARTPTEERR (1<<1)
33
34/* K8 On-cpu GART registers */
35#define AMD64_GARTAPERTURECTL 0x90
36#define AMD64_GARTAPERTUREBASE 0x94
37#define AMD64_GARTTABLEBASE 0x98
38#define AMD64_GARTCACHECTL 0x9c
39#define AMD64_GARTEN (1<<0)
40
41/* NVIDIA K8 registers */ 22/* NVIDIA K8 registers */
42#define NVIDIA_X86_64_0_APBASE 0x10 23#define NVIDIA_X86_64_0_APBASE 0x10
43#define NVIDIA_X86_64_1_APBASE1 0x50 24#define NVIDIA_X86_64_1_APBASE1 0x50
@@ -90,9 +71,9 @@ static int amd64_insert_memory(struct agp_memory *mem, off_t pg_start, int type)
90 j++; 71 j++;
91 } 72 }
92 73
93 if (mem->is_flushed == FALSE) { 74 if (!mem->is_flushed) {
94 global_cache_flush(); 75 global_cache_flush();
95 mem->is_flushed = TRUE; 76 mem->is_flushed = true;
96 } 77 }
97 78
98 for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { 79 for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
@@ -165,29 +146,18 @@ static int amd64_fetch_size(void)
165 * In a multiprocessor x86-64 system, this function gets 146 * In a multiprocessor x86-64 system, this function gets
166 * called once for each CPU. 147 * called once for each CPU.
167 */ 148 */
168static u64 amd64_configure (struct pci_dev *hammer, u64 gatt_table) 149static u64 amd64_configure(struct pci_dev *hammer, u64 gatt_table)
169{ 150{
170 u64 aperturebase; 151 u64 aperturebase;
171 u32 tmp; 152 u32 tmp;
172 u64 addr, aper_base; 153 u64 aper_base;
173 154
174 /* Address to map to */ 155 /* Address to map to */
175 pci_read_config_dword (hammer, AMD64_GARTAPERTUREBASE, &tmp); 156 pci_read_config_dword(hammer, AMD64_GARTAPERTUREBASE, &tmp);
176 aperturebase = tmp << 25; 157 aperturebase = tmp << 25;
177 aper_base = (aperturebase & PCI_BASE_ADDRESS_MEM_MASK); 158 aper_base = (aperturebase & PCI_BASE_ADDRESS_MEM_MASK);
178 159
179 /* address of the mappings table */ 160 enable_gart_translation(hammer, gatt_table);
180 addr = (u64) gatt_table;
181 addr >>= 12;
182 tmp = (u32) addr<<4;
183 tmp &= ~0xf;
184 pci_write_config_dword (hammer, AMD64_GARTTABLEBASE, tmp);
185
186 /* Enable GART translation for this hammer. */
187 pci_read_config_dword(hammer, AMD64_GARTAPERTURECTL, &tmp);
188 tmp |= GARTEN;
189 tmp &= ~(DISGARTCPU | DISGARTIO);
190 pci_write_config_dword(hammer, AMD64_GARTAPERTURECTL, tmp);
191 161
192 return aper_base; 162 return aper_base;
193} 163}
@@ -226,9 +196,9 @@ static void amd64_cleanup(void)
226 for (i = 0; i < num_k8_northbridges; i++) { 196 for (i = 0; i < num_k8_northbridges; i++) {
227 struct pci_dev *dev = k8_northbridges[i]; 197 struct pci_dev *dev = k8_northbridges[i];
228 /* disable gart translation */ 198 /* disable gart translation */
229 pci_read_config_dword (dev, AMD64_GARTAPERTURECTL, &tmp); 199 pci_read_config_dword(dev, AMD64_GARTAPERTURECTL, &tmp);
230 tmp &= ~AMD64_GARTEN; 200 tmp &= ~AMD64_GARTEN;
231 pci_write_config_dword (dev, AMD64_GARTAPERTURECTL, tmp); 201 pci_write_config_dword(dev, AMD64_GARTAPERTURECTL, tmp);
232 } 202 }
233} 203}
234 204
@@ -258,24 +228,10 @@ static const struct agp_bridge_driver amd_8151_driver = {
258}; 228};
259 229
260/* Some basic sanity checks for the aperture. */ 230/* Some basic sanity checks for the aperture. */
261static int __devinit aperture_valid(u64 aper, u32 size) 231static int __devinit agp_aperture_valid(u64 aper, u32 size)
262{ 232{
263 if (aper == 0) { 233 if (!aperture_valid(aper, size, 32*1024*1024))
264 printk(KERN_ERR PFX "No aperture\n");
265 return 0;
266 }
267 if (size < 32*1024*1024) {
268 printk(KERN_ERR PFX "Aperture too small (%d MB)\n", size>>20);
269 return 0;
270 }
271 if ((u64)aper + size > 0x100000000ULL) {
272 printk(KERN_ERR PFX "Aperture out of bounds\n");
273 return 0; 234 return 0;
274 }
275 if (e820_any_mapped(aper, aper + size, E820_RAM)) {
276 printk(KERN_ERR PFX "Aperture pointing to RAM\n");
277 return 0;
278 }
279 235
280 /* Request the Aperture. This catches cases when someone else 236 /* Request the Aperture. This catches cases when someone else
281 already put a mapping in there - happens with some very broken BIOS 237 already put a mapping in there - happens with some very broken BIOS
@@ -308,11 +264,11 @@ static __devinit int fix_northbridge(struct pci_dev *nb, struct pci_dev *agp,
308 u32 nb_order, nb_base; 264 u32 nb_order, nb_base;
309 u16 apsize; 265 u16 apsize;
310 266
311 pci_read_config_dword(nb, 0x90, &nb_order); 267 pci_read_config_dword(nb, AMD64_GARTAPERTURECTL, &nb_order);
312 nb_order = (nb_order >> 1) & 7; 268 nb_order = (nb_order >> 1) & 7;
313 pci_read_config_dword(nb, 0x94, &nb_base); 269 pci_read_config_dword(nb, AMD64_GARTAPERTUREBASE, &nb_base);
314 nb_aper = nb_base << 25; 270 nb_aper = nb_base << 25;
315 if (aperture_valid(nb_aper, (32*1024*1024)<<nb_order)) { 271 if (agp_aperture_valid(nb_aper, (32*1024*1024)<<nb_order)) {
316 return 0; 272 return 0;
317 } 273 }
318 274
@@ -331,12 +287,23 @@ static __devinit int fix_northbridge(struct pci_dev *nb, struct pci_dev *agp,
331 pci_read_config_dword(agp, 0x10, &aper_low); 287 pci_read_config_dword(agp, 0x10, &aper_low);
332 pci_read_config_dword(agp, 0x14, &aper_hi); 288 pci_read_config_dword(agp, 0x14, &aper_hi);
333 aper = (aper_low & ~((1<<22)-1)) | ((u64)aper_hi << 32); 289 aper = (aper_low & ~((1<<22)-1)) | ((u64)aper_hi << 32);
290
291 /*
292 * On some sick chips APSIZE is 0. This means it wants 4G
293 * so let double check that order, and lets trust the AMD NB settings
294 */
295 if (order >=0 && aper + (32ULL<<(20 + order)) > 0x100000000ULL) {
296 printk(KERN_INFO "Aperture size %u MB is not right, using settings from NB\n",
297 32 << order);
298 order = nb_order;
299 }
300
334 printk(KERN_INFO PFX "Aperture from AGP @ %Lx size %u MB\n", aper, 32 << order); 301 printk(KERN_INFO PFX "Aperture from AGP @ %Lx size %u MB\n", aper, 32 << order);
335 if (order < 0 || !aperture_valid(aper, (32*1024*1024)<<order)) 302 if (order < 0 || !agp_aperture_valid(aper, (32*1024*1024)<<order))
336 return -1; 303 return -1;
337 304
338 pci_write_config_dword(nb, 0x90, order << 1); 305 pci_write_config_dword(nb, AMD64_GARTAPERTURECTL, order << 1);
339 pci_write_config_dword(nb, 0x94, aper >> 25); 306 pci_write_config_dword(nb, AMD64_GARTAPERTUREBASE, aper >> 25);
340 307
341 return 0; 308 return 0;
342} 309}
diff --git a/drivers/char/agp/ati-agp.c b/drivers/char/agp/ati-agp.c
index 55c97f623242..3a4566c0d84f 100644
--- a/drivers/char/agp/ati-agp.c
+++ b/drivers/char/agp/ati-agp.c
@@ -287,10 +287,10 @@ static int ati_insert_memory(struct agp_memory * mem,
287 j++; 287 j++;
288 } 288 }
289 289
290 if (mem->is_flushed == FALSE) { 290 if (!mem->is_flushed) {
291 /*CACHE_FLUSH(); */ 291 /*CACHE_FLUSH(); */
292 global_cache_flush(); 292 global_cache_flush();
293 mem->is_flushed = TRUE; 293 mem->is_flushed = true;
294 } 294 }
295 295
296 for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { 296 for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
@@ -458,6 +458,10 @@ static struct agp_device_ids ati_agp_device_ids[] __devinitdata =
458 .chipset_name = "IGP9100/M", 458 .chipset_name = "IGP9100/M",
459 }, 459 },
460 { 460 {
461 .device_id = PCI_DEVICE_ID_ATI_RS350_133,
462 .chipset_name = "IGP9000/M",
463 },
464 {
461 .device_id = PCI_DEVICE_ID_ATI_RS350_200, 465 .device_id = PCI_DEVICE_ID_ATI_RS350_200,
462 .chipset_name = "IGP9100/M", 466 .chipset_name = "IGP9100/M",
463 }, 467 },
diff --git a/drivers/char/agp/backend.c b/drivers/char/agp/backend.c
index b1bdd015165c..1ec87104e68c 100644
--- a/drivers/char/agp/backend.c
+++ b/drivers/char/agp/backend.c
@@ -188,10 +188,10 @@ static int agp_backend_initialize(struct agp_bridge_data *bridge)
188 188
189err_out: 189err_out:
190 if (bridge->driver->needs_scratch_page) { 190 if (bridge->driver->needs_scratch_page) {
191 bridge->driver->agp_destroy_page(gart_to_virt(bridge->scratch_page_real), 191 void *va = gart_to_virt(bridge->scratch_page_real);
192 AGP_PAGE_DESTROY_UNMAP); 192
193 bridge->driver->agp_destroy_page(gart_to_virt(bridge->scratch_page_real), 193 bridge->driver->agp_destroy_page(va, AGP_PAGE_DESTROY_UNMAP);
194 AGP_PAGE_DESTROY_FREE); 194 bridge->driver->agp_destroy_page(va, AGP_PAGE_DESTROY_FREE);
195 } 195 }
196 if (got_gatt) 196 if (got_gatt)
197 bridge->driver->free_gatt_table(bridge); 197 bridge->driver->free_gatt_table(bridge);
@@ -215,10 +215,10 @@ static void agp_backend_cleanup(struct agp_bridge_data *bridge)
215 215
216 if (bridge->driver->agp_destroy_page && 216 if (bridge->driver->agp_destroy_page &&
217 bridge->driver->needs_scratch_page) { 217 bridge->driver->needs_scratch_page) {
218 bridge->driver->agp_destroy_page(gart_to_virt(bridge->scratch_page_real), 218 void *va = gart_to_virt(bridge->scratch_page_real);
219 AGP_PAGE_DESTROY_UNMAP); 219
220 bridge->driver->agp_destroy_page(gart_to_virt(bridge->scratch_page_real), 220 bridge->driver->agp_destroy_page(va, AGP_PAGE_DESTROY_UNMAP);
221 AGP_PAGE_DESTROY_FREE); 221 bridge->driver->agp_destroy_page(va, AGP_PAGE_DESTROY_FREE);
222 } 222 }
223} 223}
224 224
diff --git a/drivers/char/agp/compat_ioctl.c b/drivers/char/agp/compat_ioctl.c
index 39275794fe63..58c57cb2518c 100644
--- a/drivers/char/agp/compat_ioctl.c
+++ b/drivers/char/agp/compat_ioctl.c
@@ -214,7 +214,7 @@ long compat_agp_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
214 ret_val = -EINVAL; 214 ret_val = -EINVAL;
215 goto ioctl_out; 215 goto ioctl_out;
216 } 216 }
217 if ((agp_fe.backend_acquired != TRUE) && 217 if ((agp_fe.backend_acquired != true) &&
218 (cmd != AGPIOC_ACQUIRE32)) { 218 (cmd != AGPIOC_ACQUIRE32)) {
219 ret_val = -EBUSY; 219 ret_val = -EBUSY;
220 goto ioctl_out; 220 goto ioctl_out;
diff --git a/drivers/char/agp/efficeon-agp.c b/drivers/char/agp/efficeon-agp.c
index cac0009cebc1..8ca6f262ef85 100644
--- a/drivers/char/agp/efficeon-agp.c
+++ b/drivers/char/agp/efficeon-agp.c
@@ -249,9 +249,9 @@ static int efficeon_insert_memory(struct agp_memory * mem, off_t pg_start, int t
249 if (type != 0 || mem->type != 0) 249 if (type != 0 || mem->type != 0)
250 return -EINVAL; 250 return -EINVAL;
251 251
252 if (mem->is_flushed == FALSE) { 252 if (!mem->is_flushed) {
253 global_cache_flush(); 253 global_cache_flush();
254 mem->is_flushed = TRUE; 254 mem->is_flushed = true;
255 } 255 }
256 256
257 last_page = NULL; 257 last_page = NULL;
@@ -329,7 +329,7 @@ static const struct agp_bridge_driver efficeon_driver = {
329 .free_gatt_table = efficeon_free_gatt_table, 329 .free_gatt_table = efficeon_free_gatt_table,
330 .insert_memory = efficeon_insert_memory, 330 .insert_memory = efficeon_insert_memory,
331 .remove_memory = efficeon_remove_memory, 331 .remove_memory = efficeon_remove_memory,
332 .cant_use_aperture = 0, // 1 might be faster? 332 .cant_use_aperture = false, // true might be faster?
333 333
334 // Generic 334 // Generic
335 .alloc_by_type = agp_generic_alloc_by_type, 335 .alloc_by_type = agp_generic_alloc_by_type,
diff --git a/drivers/char/agp/frontend.c b/drivers/char/agp/frontend.c
index 857b26227d87..a96f3197e60f 100644
--- a/drivers/char/agp/frontend.c
+++ b/drivers/char/agp/frontend.c
@@ -39,6 +39,7 @@
39#include <linux/mm.h> 39#include <linux/mm.h>
40#include <linux/fs.h> 40#include <linux/fs.h>
41#include <linux/sched.h> 41#include <linux/sched.h>
42#include <linux/smp_lock.h>
42#include <asm/uaccess.h> 43#include <asm/uaccess.h>
43#include <asm/pgtable.h> 44#include <asm/pgtable.h>
44#include "agp.h" 45#include "agp.h"
@@ -395,7 +396,7 @@ static int agp_remove_controller(struct agp_controller *controller)
395 396
396 if (agp_fe.current_controller == controller) { 397 if (agp_fe.current_controller == controller) {
397 agp_fe.current_controller = NULL; 398 agp_fe.current_controller = NULL;
398 agp_fe.backend_acquired = FALSE; 399 agp_fe.backend_acquired = false;
399 agp_backend_release(agp_bridge); 400 agp_backend_release(agp_bridge);
400 } 401 }
401 kfree(controller); 402 kfree(controller);
@@ -443,7 +444,7 @@ static void agp_controller_release_current(struct agp_controller *controller,
443 } 444 }
444 445
445 agp_fe.current_controller = NULL; 446 agp_fe.current_controller = NULL;
446 agp_fe.used_by_controller = FALSE; 447 agp_fe.used_by_controller = false;
447 agp_backend_release(agp_bridge); 448 agp_backend_release(agp_bridge);
448} 449}
449 450
@@ -573,7 +574,7 @@ static int agp_mmap(struct file *file, struct vm_area_struct *vma)
573 574
574 mutex_lock(&(agp_fe.agp_mutex)); 575 mutex_lock(&(agp_fe.agp_mutex));
575 576
576 if (agp_fe.backend_acquired != TRUE) 577 if (agp_fe.backend_acquired != true)
577 goto out_eperm; 578 goto out_eperm;
578 579
579 if (!(test_bit(AGP_FF_IS_VALID, &priv->access_flags))) 580 if (!(test_bit(AGP_FF_IS_VALID, &priv->access_flags)))
@@ -677,6 +678,7 @@ static int agp_open(struct inode *inode, struct file *file)
677 struct agp_client *client; 678 struct agp_client *client;
678 int rc = -ENXIO; 679 int rc = -ENXIO;
679 680
681 lock_kernel();
680 mutex_lock(&(agp_fe.agp_mutex)); 682 mutex_lock(&(agp_fe.agp_mutex));
681 683
682 if (minor != AGPGART_MINOR) 684 if (minor != AGPGART_MINOR)
@@ -703,12 +705,14 @@ static int agp_open(struct inode *inode, struct file *file)
703 agp_insert_file_private(priv); 705 agp_insert_file_private(priv);
704 DBG("private=%p, client=%p", priv, client); 706 DBG("private=%p, client=%p", priv, client);
705 mutex_unlock(&(agp_fe.agp_mutex)); 707 mutex_unlock(&(agp_fe.agp_mutex));
708 unlock_kernel();
706 return 0; 709 return 0;
707 710
708err_out_nomem: 711err_out_nomem:
709 rc = -ENOMEM; 712 rc = -ENOMEM;
710err_out: 713err_out:
711 mutex_unlock(&(agp_fe.agp_mutex)); 714 mutex_unlock(&(agp_fe.agp_mutex));
715 unlock_kernel();
712 return rc; 716 return rc;
713} 717}
714 718
@@ -768,7 +772,7 @@ int agpioc_acquire_wrap(struct agp_file_private *priv)
768 772
769 atomic_inc(&agp_bridge->agp_in_use); 773 atomic_inc(&agp_bridge->agp_in_use);
770 774
771 agp_fe.backend_acquired = TRUE; 775 agp_fe.backend_acquired = true;
772 776
773 controller = agp_find_controller_by_pid(priv->my_pid); 777 controller = agp_find_controller_by_pid(priv->my_pid);
774 778
@@ -778,7 +782,7 @@ int agpioc_acquire_wrap(struct agp_file_private *priv)
778 controller = agp_create_controller(priv->my_pid); 782 controller = agp_create_controller(priv->my_pid);
779 783
780 if (controller == NULL) { 784 if (controller == NULL) {
781 agp_fe.backend_acquired = FALSE; 785 agp_fe.backend_acquired = false;
782 agp_backend_release(agp_bridge); 786 agp_backend_release(agp_bridge);
783 return -ENOMEM; 787 return -ENOMEM;
784 } 788 }
@@ -981,7 +985,7 @@ static long agp_ioctl(struct file *file,
981 ret_val = -EINVAL; 985 ret_val = -EINVAL;
982 goto ioctl_out; 986 goto ioctl_out;
983 } 987 }
984 if ((agp_fe.backend_acquired != TRUE) && 988 if ((agp_fe.backend_acquired != true) &&
985 (cmd != AGPIOC_ACQUIRE)) { 989 (cmd != AGPIOC_ACQUIRE)) {
986 ret_val = -EBUSY; 990 ret_val = -EBUSY;
987 goto ioctl_out; 991 goto ioctl_out;
diff --git a/drivers/char/agp/generic.c b/drivers/char/agp/generic.c
index 7fc0c99a3a58..eaa1a355bb32 100644
--- a/drivers/char/agp/generic.c
+++ b/drivers/char/agp/generic.c
@@ -96,13 +96,13 @@ EXPORT_SYMBOL(agp_flush_chipset);
96void agp_alloc_page_array(size_t size, struct agp_memory *mem) 96void agp_alloc_page_array(size_t size, struct agp_memory *mem)
97{ 97{
98 mem->memory = NULL; 98 mem->memory = NULL;
99 mem->vmalloc_flag = 0; 99 mem->vmalloc_flag = false;
100 100
101 if (size <= 2*PAGE_SIZE) 101 if (size <= 2*PAGE_SIZE)
102 mem->memory = kmalloc(size, GFP_KERNEL | __GFP_NORETRY); 102 mem->memory = kmalloc(size, GFP_KERNEL | __GFP_NORETRY);
103 if (mem->memory == NULL) { 103 if (mem->memory == NULL) {
104 mem->memory = vmalloc(size); 104 mem->memory = vmalloc(size);
105 mem->vmalloc_flag = 1; 105 mem->vmalloc_flag = true;
106 } 106 }
107} 107}
108EXPORT_SYMBOL(agp_alloc_page_array); 108EXPORT_SYMBOL(agp_alloc_page_array);
@@ -188,7 +188,7 @@ void agp_free_memory(struct agp_memory *curr)
188 if (curr == NULL) 188 if (curr == NULL)
189 return; 189 return;
190 190
191 if (curr->is_bound == TRUE) 191 if (curr->is_bound)
192 agp_unbind_memory(curr); 192 agp_unbind_memory(curr);
193 193
194 if (curr->type >= AGP_USER_TYPES) { 194 if (curr->type >= AGP_USER_TYPES) {
@@ -202,10 +202,13 @@ void agp_free_memory(struct agp_memory *curr)
202 } 202 }
203 if (curr->page_count != 0) { 203 if (curr->page_count != 0) {
204 for (i = 0; i < curr->page_count; i++) { 204 for (i = 0; i < curr->page_count; i++) {
205 curr->bridge->driver->agp_destroy_page(gart_to_virt(curr->memory[i]), AGP_PAGE_DESTROY_UNMAP); 205 curr->memory[i] = (unsigned long)gart_to_virt(curr->memory[i]);
206 curr->bridge->driver->agp_destroy_page((void *)curr->memory[i],
207 AGP_PAGE_DESTROY_UNMAP);
206 } 208 }
207 for (i = 0; i < curr->page_count; i++) { 209 for (i = 0; i < curr->page_count; i++) {
208 curr->bridge->driver->agp_destroy_page(gart_to_virt(curr->memory[i]), AGP_PAGE_DESTROY_FREE); 210 curr->bridge->driver->agp_destroy_page((void *)curr->memory[i],
211 AGP_PAGE_DESTROY_FREE);
209 } 212 }
210 } 213 }
211 agp_free_key(curr->key); 214 agp_free_key(curr->key);
@@ -411,20 +414,20 @@ int agp_bind_memory(struct agp_memory *curr, off_t pg_start)
411 if (curr == NULL) 414 if (curr == NULL)
412 return -EINVAL; 415 return -EINVAL;
413 416
414 if (curr->is_bound == TRUE) { 417 if (curr->is_bound) {
415 printk(KERN_INFO PFX "memory %p is already bound!\n", curr); 418 printk(KERN_INFO PFX "memory %p is already bound!\n", curr);
416 return -EINVAL; 419 return -EINVAL;
417 } 420 }
418 if (curr->is_flushed == FALSE) { 421 if (!curr->is_flushed) {
419 curr->bridge->driver->cache_flush(); 422 curr->bridge->driver->cache_flush();
420 curr->is_flushed = TRUE; 423 curr->is_flushed = true;
421 } 424 }
422 ret_val = curr->bridge->driver->insert_memory(curr, pg_start, curr->type); 425 ret_val = curr->bridge->driver->insert_memory(curr, pg_start, curr->type);
423 426
424 if (ret_val != 0) 427 if (ret_val != 0)
425 return ret_val; 428 return ret_val;
426 429
427 curr->is_bound = TRUE; 430 curr->is_bound = true;
428 curr->pg_start = pg_start; 431 curr->pg_start = pg_start;
429 return 0; 432 return 0;
430} 433}
@@ -446,7 +449,7 @@ int agp_unbind_memory(struct agp_memory *curr)
446 if (curr == NULL) 449 if (curr == NULL)
447 return -EINVAL; 450 return -EINVAL;
448 451
449 if (curr->is_bound != TRUE) { 452 if (!curr->is_bound) {
450 printk(KERN_INFO PFX "memory %p was not bound!\n", curr); 453 printk(KERN_INFO PFX "memory %p was not bound!\n", curr);
451 return -EINVAL; 454 return -EINVAL;
452 } 455 }
@@ -456,7 +459,7 @@ int agp_unbind_memory(struct agp_memory *curr)
456 if (ret_val != 0) 459 if (ret_val != 0)
457 return ret_val; 460 return ret_val;
458 461
459 curr->is_bound = FALSE; 462 curr->is_bound = false;
460 curr->pg_start = 0; 463 curr->pg_start = 0;
461 return 0; 464 return 0;
462} 465}
@@ -754,7 +757,7 @@ u32 agp_collect_device_status(struct agp_bridge_data *bridge, u32 requested_mode
754EXPORT_SYMBOL(agp_collect_device_status); 757EXPORT_SYMBOL(agp_collect_device_status);
755 758
756 759
757void agp_device_command(u32 bridge_agpstat, int agp_v3) 760void agp_device_command(u32 bridge_agpstat, bool agp_v3)
758{ 761{
759 struct pci_dev *device = NULL; 762 struct pci_dev *device = NULL;
760 int mode; 763 int mode;
@@ -818,7 +821,7 @@ void agp_generic_enable(struct agp_bridge_data *bridge, u32 requested_mode)
818 /* If we have 3.5, we can do the isoch stuff. */ 821 /* If we have 3.5, we can do the isoch stuff. */
819 if (bridge->minor_version >= 5) 822 if (bridge->minor_version >= 5)
820 agp_3_5_enable(bridge); 823 agp_3_5_enable(bridge);
821 agp_device_command(bridge_agpstat, TRUE); 824 agp_device_command(bridge_agpstat, true);
822 return; 825 return;
823 } else { 826 } else {
824 /* Disable calibration cycle in RX91<1> when not in AGP3.0 mode of operation.*/ 827 /* Disable calibration cycle in RX91<1> when not in AGP3.0 mode of operation.*/
@@ -835,7 +838,7 @@ void agp_generic_enable(struct agp_bridge_data *bridge, u32 requested_mode)
835 } 838 }
836 839
837 /* AGP v<3 */ 840 /* AGP v<3 */
838 agp_device_command(bridge_agpstat, FALSE); 841 agp_device_command(bridge_agpstat, false);
839} 842}
840EXPORT_SYMBOL(agp_generic_enable); 843EXPORT_SYMBOL(agp_generic_enable);
841 844
@@ -1083,9 +1086,9 @@ int agp_generic_insert_memory(struct agp_memory * mem, off_t pg_start, int type)
1083 j++; 1086 j++;
1084 } 1087 }
1085 1088
1086 if (mem->is_flushed == FALSE) { 1089 if (!mem->is_flushed) {
1087 bridge->driver->cache_flush(); 1090 bridge->driver->cache_flush();
1088 mem->is_flushed = TRUE; 1091 mem->is_flushed = true;
1089 } 1092 }
1090 1093
1091 for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { 1094 for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
@@ -1246,7 +1249,7 @@ static void ipi_handler(void *null)
1246 1249
1247void global_cache_flush(void) 1250void global_cache_flush(void)
1248{ 1251{
1249 if (on_each_cpu(ipi_handler, NULL, 1, 1) != 0) 1252 if (on_each_cpu(ipi_handler, NULL, 1) != 0)
1250 panic(PFX "timed out waiting for the other CPUs!\n"); 1253 panic(PFX "timed out waiting for the other CPUs!\n");
1251} 1254}
1252EXPORT_SYMBOL(global_cache_flush); 1255EXPORT_SYMBOL(global_cache_flush);
diff --git a/drivers/char/agp/hp-agp.c b/drivers/char/agp/hp-agp.c
index cbb0444467ba..80d7317f85c9 100644
--- a/drivers/char/agp/hp-agp.c
+++ b/drivers/char/agp/hp-agp.c
@@ -353,9 +353,9 @@ hp_zx1_insert_memory (struct agp_memory *mem, off_t pg_start, int type)
353 j++; 353 j++;
354 } 354 }
355 355
356 if (mem->is_flushed == FALSE) { 356 if (!mem->is_flushed) {
357 global_cache_flush(); 357 global_cache_flush();
358 mem->is_flushed = TRUE; 358 mem->is_flushed = true;
359 } 359 }
360 360
361 for (i = 0, j = io_pg_start; i < mem->page_count; i++) { 361 for (i = 0, j = io_pg_start; i < mem->page_count; i++) {
@@ -437,7 +437,7 @@ const struct agp_bridge_driver hp_zx1_driver = {
437 .agp_alloc_page = agp_generic_alloc_page, 437 .agp_alloc_page = agp_generic_alloc_page,
438 .agp_destroy_page = agp_generic_destroy_page, 438 .agp_destroy_page = agp_generic_destroy_page,
439 .agp_type_to_mask_type = agp_generic_type_to_mask_type, 439 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
440 .cant_use_aperture = 1, 440 .cant_use_aperture = true,
441}; 441};
442 442
443static int __init 443static int __init
diff --git a/drivers/char/agp/i460-agp.c b/drivers/char/agp/i460-agp.c
index 76f581c85a7d..e587eebebc67 100644
--- a/drivers/char/agp/i460-agp.c
+++ b/drivers/char/agp/i460-agp.c
@@ -580,7 +580,7 @@ const struct agp_bridge_driver intel_i460_driver = {
580 .alloc_by_type = agp_generic_alloc_by_type, 580 .alloc_by_type = agp_generic_alloc_by_type,
581 .free_by_type = agp_generic_free_by_type, 581 .free_by_type = agp_generic_free_by_type,
582 .agp_type_to_mask_type = agp_generic_type_to_mask_type, 582 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
583 .cant_use_aperture = 1, 583 .cant_use_aperture = true,
584}; 584};
585 585
586static int __devinit agp_intel_i460_probe(struct pci_dev *pdev, 586static int __devinit agp_intel_i460_probe(struct pci_dev *pdev,
diff --git a/drivers/char/agp/intel-agp.c b/drivers/char/agp/intel-agp.c
index eeea50a1d22a..df702642ab8f 100644
--- a/drivers/char/agp/intel-agp.c
+++ b/drivers/char/agp/intel-agp.c
@@ -34,6 +34,12 @@
34#define PCI_DEVICE_ID_INTEL_Q33_IG 0x29D2 34#define PCI_DEVICE_ID_INTEL_Q33_IG 0x29D2
35#define PCI_DEVICE_ID_INTEL_IGD_HB 0x2A40 35#define PCI_DEVICE_ID_INTEL_IGD_HB 0x2A40
36#define PCI_DEVICE_ID_INTEL_IGD_IG 0x2A42 36#define PCI_DEVICE_ID_INTEL_IGD_IG 0x2A42
37#define PCI_DEVICE_ID_INTEL_IGD_E_HB 0x2E00
38#define PCI_DEVICE_ID_INTEL_IGD_E_IG 0x2E02
39#define PCI_DEVICE_ID_INTEL_Q45_HB 0x2E10
40#define PCI_DEVICE_ID_INTEL_Q45_IG 0x2E12
41#define PCI_DEVICE_ID_INTEL_G45_HB 0x2E20
42#define PCI_DEVICE_ID_INTEL_G45_IG 0x2E22
37 43
38/* cover 915 and 945 variants */ 44/* cover 915 and 945 variants */
39#define IS_I915 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_E7221_HB || \ 45#define IS_I915 (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_E7221_HB || \
@@ -55,6 +61,10 @@
55 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q35_HB || \ 61 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q35_HB || \
56 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q33_HB) 62 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q33_HB)
57 63
64#define IS_G4X (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGD_E_HB || \
65 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_Q45_HB || \
66 agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_G45_HB)
67
58extern int agp_memory_reserved; 68extern int agp_memory_reserved;
59 69
60 70
@@ -80,8 +90,13 @@ extern int agp_memory_reserved;
80#define I915_PTEADDR 0x1C 90#define I915_PTEADDR 0x1C
81#define I915_GMCH_GMS_STOLEN_48M (0x6 << 4) 91#define I915_GMCH_GMS_STOLEN_48M (0x6 << 4)
82#define I915_GMCH_GMS_STOLEN_64M (0x7 << 4) 92#define I915_GMCH_GMS_STOLEN_64M (0x7 << 4)
83#define G33_GMCH_GMS_STOLEN_128M (0x8 << 4) 93#define G33_GMCH_GMS_STOLEN_128M (0x8 << 4)
84#define G33_GMCH_GMS_STOLEN_256M (0x9 << 4) 94#define G33_GMCH_GMS_STOLEN_256M (0x9 << 4)
95#define INTEL_GMCH_GMS_STOLEN_96M (0xa << 4)
96#define INTEL_GMCH_GMS_STOLEN_160M (0xb << 4)
97#define INTEL_GMCH_GMS_STOLEN_224M (0xc << 4)
98#define INTEL_GMCH_GMS_STOLEN_352M (0xd << 4)
99
85#define I915_IFPADDR 0x60 100#define I915_IFPADDR 0x60
86 101
87/* Intel 965G registers */ 102/* Intel 965G registers */
@@ -325,7 +340,7 @@ static int intel_i810_insert_entries(struct agp_memory *mem, off_t pg_start,
325out: 340out:
326 ret = 0; 341 ret = 0;
327out_err: 342out_err:
328 mem->is_flushed = 1; 343 mem->is_flushed = true;
329 return ret; 344 return ret;
330} 345}
331 346
@@ -418,9 +433,11 @@ static void intel_i810_free_by_type(struct agp_memory *curr)
418 if (curr->page_count == 4) 433 if (curr->page_count == 4)
419 i8xx_destroy_pages(gart_to_virt(curr->memory[0])); 434 i8xx_destroy_pages(gart_to_virt(curr->memory[0]));
420 else { 435 else {
421 agp_bridge->driver->agp_destroy_page(gart_to_virt(curr->memory[0]), 436 void *va = gart_to_virt(curr->memory[0]);
437
438 agp_bridge->driver->agp_destroy_page(va,
422 AGP_PAGE_DESTROY_UNMAP); 439 AGP_PAGE_DESTROY_UNMAP);
423 agp_bridge->driver->agp_destroy_page(gart_to_virt(curr->memory[0]), 440 agp_bridge->driver->agp_destroy_page(va,
424 AGP_PAGE_DESTROY_FREE); 441 AGP_PAGE_DESTROY_FREE);
425 } 442 }
426 agp_free_page_array(curr); 443 agp_free_page_array(curr);
@@ -504,6 +521,10 @@ static void intel_i830_init_gtt_entries(void)
504 size = 512; 521 size = 512;
505 } 522 }
506 size += 4; 523 size += 4;
524 } else if (IS_G4X) {
525 /* On 4 series hardware, GTT stolen is separate from graphics
526 * stolen, ignore it in stolen gtt entries counting */
527 size = 0;
507 } else { 528 } else {
508 /* On previous hardware, the GTT size was just what was 529 /* On previous hardware, the GTT size was just what was
509 * required to map the aperture. 530 * required to map the aperture.
@@ -552,30 +573,54 @@ static void intel_i830_init_gtt_entries(void)
552 break; 573 break;
553 case I915_GMCH_GMS_STOLEN_48M: 574 case I915_GMCH_GMS_STOLEN_48M:
554 /* Check it's really I915G */ 575 /* Check it's really I915G */
555 if (IS_I915 || IS_I965 || IS_G33) 576 if (IS_I915 || IS_I965 || IS_G33 || IS_G4X)
556 gtt_entries = MB(48) - KB(size); 577 gtt_entries = MB(48) - KB(size);
557 else 578 else
558 gtt_entries = 0; 579 gtt_entries = 0;
559 break; 580 break;
560 case I915_GMCH_GMS_STOLEN_64M: 581 case I915_GMCH_GMS_STOLEN_64M:
561 /* Check it's really I915G */ 582 /* Check it's really I915G */
562 if (IS_I915 || IS_I965 || IS_G33) 583 if (IS_I915 || IS_I965 || IS_G33 || IS_G4X)
563 gtt_entries = MB(64) - KB(size); 584 gtt_entries = MB(64) - KB(size);
564 else 585 else
565 gtt_entries = 0; 586 gtt_entries = 0;
566 break; 587 break;
567 case G33_GMCH_GMS_STOLEN_128M: 588 case G33_GMCH_GMS_STOLEN_128M:
568 if (IS_G33) 589 if (IS_G33 || IS_I965 || IS_G4X)
569 gtt_entries = MB(128) - KB(size); 590 gtt_entries = MB(128) - KB(size);
570 else 591 else
571 gtt_entries = 0; 592 gtt_entries = 0;
572 break; 593 break;
573 case G33_GMCH_GMS_STOLEN_256M: 594 case G33_GMCH_GMS_STOLEN_256M:
574 if (IS_G33) 595 if (IS_G33 || IS_I965 || IS_G4X)
575 gtt_entries = MB(256) - KB(size); 596 gtt_entries = MB(256) - KB(size);
576 else 597 else
577 gtt_entries = 0; 598 gtt_entries = 0;
578 break; 599 break;
600 case INTEL_GMCH_GMS_STOLEN_96M:
601 if (IS_I965 || IS_G4X)
602 gtt_entries = MB(96) - KB(size);
603 else
604 gtt_entries = 0;
605 break;
606 case INTEL_GMCH_GMS_STOLEN_160M:
607 if (IS_I965 || IS_G4X)
608 gtt_entries = MB(160) - KB(size);
609 else
610 gtt_entries = 0;
611 break;
612 case INTEL_GMCH_GMS_STOLEN_224M:
613 if (IS_I965 || IS_G4X)
614 gtt_entries = MB(224) - KB(size);
615 else
616 gtt_entries = 0;
617 break;
618 case INTEL_GMCH_GMS_STOLEN_352M:
619 if (IS_I965 || IS_G4X)
620 gtt_entries = MB(352) - KB(size);
621 else
622 gtt_entries = 0;
623 break;
579 default: 624 default:
580 gtt_entries = 0; 625 gtt_entries = 0;
581 break; 626 break;
@@ -793,7 +838,7 @@ static int intel_i830_insert_entries(struct agp_memory *mem, off_t pg_start,
793out: 838out:
794 ret = 0; 839 ret = 0;
795out_err: 840out_err:
796 mem->is_flushed = 1; 841 mem->is_flushed = true;
797 return ret; 842 return ret;
798} 843}
799 844
@@ -903,7 +948,7 @@ static void intel_i9xx_setup_flush(void)
903 intel_private.ifp_resource.flags = IORESOURCE_MEM; 948 intel_private.ifp_resource.flags = IORESOURCE_MEM;
904 949
905 /* Setup chipset flush for 915 */ 950 /* Setup chipset flush for 915 */
906 if (IS_I965 || IS_G33) { 951 if (IS_I965 || IS_G33 || IS_G4X) {
907 intel_i965_g33_setup_chipset_flush(); 952 intel_i965_g33_setup_chipset_flush();
908 } else { 953 } else {
909 intel_i915_setup_chipset_flush(); 954 intel_i915_setup_chipset_flush();
@@ -1020,7 +1065,7 @@ static int intel_i915_insert_entries(struct agp_memory *mem, off_t pg_start,
1020 out: 1065 out:
1021 ret = 0; 1066 ret = 0;
1022 out_err: 1067 out_err:
1023 mem->is_flushed = 1; 1068 mem->is_flushed = true;
1024 return ret; 1069 return ret;
1025} 1070}
1026 1071
@@ -1134,53 +1179,64 @@ static unsigned long intel_i965_mask_memory(struct agp_bridge_data *bridge,
1134 return addr | bridge->driver->masks[type].mask; 1179 return addr | bridge->driver->masks[type].mask;
1135} 1180}
1136 1181
1182static void intel_i965_get_gtt_range(int *gtt_offset, int *gtt_size)
1183{
1184 switch (agp_bridge->dev->device) {
1185 case PCI_DEVICE_ID_INTEL_IGD_HB:
1186 case PCI_DEVICE_ID_INTEL_IGD_E_HB:
1187 case PCI_DEVICE_ID_INTEL_Q45_HB:
1188 case PCI_DEVICE_ID_INTEL_G45_HB:
1189 *gtt_offset = *gtt_size = MB(2);
1190 break;
1191 default:
1192 *gtt_offset = *gtt_size = KB(512);
1193 }
1194}
1195
1137/* The intel i965 automatically initializes the agp aperture during POST. 1196/* The intel i965 automatically initializes the agp aperture during POST.
1138 * Use the memory already set aside for in the GTT. 1197 * Use the memory already set aside for in the GTT.
1139 */ 1198 */
1140static int intel_i965_create_gatt_table(struct agp_bridge_data *bridge) 1199static int intel_i965_create_gatt_table(struct agp_bridge_data *bridge)
1141{ 1200{
1142 int page_order; 1201 int page_order;
1143 struct aper_size_info_fixed *size; 1202 struct aper_size_info_fixed *size;
1144 int num_entries; 1203 int num_entries;
1145 u32 temp; 1204 u32 temp;
1146 int gtt_offset, gtt_size; 1205 int gtt_offset, gtt_size;
1147 1206
1148 size = agp_bridge->current_size; 1207 size = agp_bridge->current_size;
1149 page_order = size->page_order; 1208 page_order = size->page_order;
1150 num_entries = size->num_entries; 1209 num_entries = size->num_entries;
1151 agp_bridge->gatt_table_real = NULL; 1210 agp_bridge->gatt_table_real = NULL;
1152 1211
1153 pci_read_config_dword(intel_private.pcidev, I915_MMADDR, &temp); 1212 pci_read_config_dword(intel_private.pcidev, I915_MMADDR, &temp);
1154 1213
1155 temp &= 0xfff00000; 1214 temp &= 0xfff00000;
1156 1215
1157 if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_IGD_HB) 1216 intel_i965_get_gtt_range(&gtt_offset, &gtt_size);
1158 gtt_offset = gtt_size = MB(2);
1159 else
1160 gtt_offset = gtt_size = KB(512);
1161 1217
1162 intel_private.gtt = ioremap((temp + gtt_offset) , gtt_size); 1218 intel_private.gtt = ioremap((temp + gtt_offset) , gtt_size);
1163 1219
1164 if (!intel_private.gtt) 1220 if (!intel_private.gtt)
1165 return -ENOMEM; 1221 return -ENOMEM;
1166 1222
1167 intel_private.registers = ioremap(temp, 128 * 4096); 1223 intel_private.registers = ioremap(temp, 128 * 4096);
1168 if (!intel_private.registers) { 1224 if (!intel_private.registers) {
1169 iounmap(intel_private.gtt); 1225 iounmap(intel_private.gtt);
1170 return -ENOMEM; 1226 return -ENOMEM;
1171 } 1227 }
1172 1228
1173 temp = readl(intel_private.registers+I810_PGETBL_CTL) & 0xfffff000; 1229 temp = readl(intel_private.registers+I810_PGETBL_CTL) & 0xfffff000;
1174 global_cache_flush(); /* FIXME: ? */ 1230 global_cache_flush(); /* FIXME: ? */
1175 1231
1176 /* we have to call this as early as possible after the MMIO base address is known */ 1232 /* we have to call this as early as possible after the MMIO base address is known */
1177 intel_i830_init_gtt_entries(); 1233 intel_i830_init_gtt_entries();
1178 1234
1179 agp_bridge->gatt_table = NULL; 1235 agp_bridge->gatt_table = NULL;
1180 1236
1181 agp_bridge->gatt_bus_addr = temp; 1237 agp_bridge->gatt_bus_addr = temp;
1182 1238
1183 return 0; 1239 return 0;
1184} 1240}
1185 1241
1186 1242
@@ -1656,7 +1712,7 @@ static const struct agp_bridge_driver intel_810_driver = {
1656 .aperture_sizes = intel_i810_sizes, 1712 .aperture_sizes = intel_i810_sizes,
1657 .size_type = FIXED_APER_SIZE, 1713 .size_type = FIXED_APER_SIZE,
1658 .num_aperture_sizes = 2, 1714 .num_aperture_sizes = 2,
1659 .needs_scratch_page = TRUE, 1715 .needs_scratch_page = true,
1660 .configure = intel_i810_configure, 1716 .configure = intel_i810_configure,
1661 .fetch_size = intel_i810_fetch_size, 1717 .fetch_size = intel_i810_fetch_size,
1662 .cleanup = intel_i810_cleanup, 1718 .cleanup = intel_i810_cleanup,
@@ -1697,7 +1753,7 @@ static const struct agp_bridge_driver intel_815_driver = {
1697 .free_by_type = agp_generic_free_by_type, 1753 .free_by_type = agp_generic_free_by_type,
1698 .agp_alloc_page = agp_generic_alloc_page, 1754 .agp_alloc_page = agp_generic_alloc_page,
1699 .agp_destroy_page = agp_generic_destroy_page, 1755 .agp_destroy_page = agp_generic_destroy_page,
1700 .agp_type_to_mask_type = agp_generic_type_to_mask_type, 1756 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
1701}; 1757};
1702 1758
1703static const struct agp_bridge_driver intel_830_driver = { 1759static const struct agp_bridge_driver intel_830_driver = {
@@ -1705,7 +1761,7 @@ static const struct agp_bridge_driver intel_830_driver = {
1705 .aperture_sizes = intel_i830_sizes, 1761 .aperture_sizes = intel_i830_sizes,
1706 .size_type = FIXED_APER_SIZE, 1762 .size_type = FIXED_APER_SIZE,
1707 .num_aperture_sizes = 4, 1763 .num_aperture_sizes = 4,
1708 .needs_scratch_page = TRUE, 1764 .needs_scratch_page = true,
1709 .configure = intel_i830_configure, 1765 .configure = intel_i830_configure,
1710 .fetch_size = intel_i830_fetch_size, 1766 .fetch_size = intel_i830_fetch_size,
1711 .cleanup = intel_i830_cleanup, 1767 .cleanup = intel_i830_cleanup,
@@ -1876,7 +1932,7 @@ static const struct agp_bridge_driver intel_915_driver = {
1876 .aperture_sizes = intel_i830_sizes, 1932 .aperture_sizes = intel_i830_sizes,
1877 .size_type = FIXED_APER_SIZE, 1933 .size_type = FIXED_APER_SIZE,
1878 .num_aperture_sizes = 4, 1934 .num_aperture_sizes = 4,
1879 .needs_scratch_page = TRUE, 1935 .needs_scratch_page = true,
1880 .configure = intel_i915_configure, 1936 .configure = intel_i915_configure,
1881 .fetch_size = intel_i9xx_fetch_size, 1937 .fetch_size = intel_i9xx_fetch_size,
1882 .cleanup = intel_i915_cleanup, 1938 .cleanup = intel_i915_cleanup,
@@ -1898,28 +1954,28 @@ static const struct agp_bridge_driver intel_915_driver = {
1898}; 1954};
1899 1955
1900static const struct agp_bridge_driver intel_i965_driver = { 1956static const struct agp_bridge_driver intel_i965_driver = {
1901 .owner = THIS_MODULE, 1957 .owner = THIS_MODULE,
1902 .aperture_sizes = intel_i830_sizes, 1958 .aperture_sizes = intel_i830_sizes,
1903 .size_type = FIXED_APER_SIZE, 1959 .size_type = FIXED_APER_SIZE,
1904 .num_aperture_sizes = 4, 1960 .num_aperture_sizes = 4,
1905 .needs_scratch_page = TRUE, 1961 .needs_scratch_page = true,
1906 .configure = intel_i915_configure, 1962 .configure = intel_i915_configure,
1907 .fetch_size = intel_i9xx_fetch_size, 1963 .fetch_size = intel_i9xx_fetch_size,
1908 .cleanup = intel_i915_cleanup, 1964 .cleanup = intel_i915_cleanup,
1909 .tlb_flush = intel_i810_tlbflush, 1965 .tlb_flush = intel_i810_tlbflush,
1910 .mask_memory = intel_i965_mask_memory, 1966 .mask_memory = intel_i965_mask_memory,
1911 .masks = intel_i810_masks, 1967 .masks = intel_i810_masks,
1912 .agp_enable = intel_i810_agp_enable, 1968 .agp_enable = intel_i810_agp_enable,
1913 .cache_flush = global_cache_flush, 1969 .cache_flush = global_cache_flush,
1914 .create_gatt_table = intel_i965_create_gatt_table, 1970 .create_gatt_table = intel_i965_create_gatt_table,
1915 .free_gatt_table = intel_i830_free_gatt_table, 1971 .free_gatt_table = intel_i830_free_gatt_table,
1916 .insert_memory = intel_i915_insert_entries, 1972 .insert_memory = intel_i915_insert_entries,
1917 .remove_memory = intel_i915_remove_entries, 1973 .remove_memory = intel_i915_remove_entries,
1918 .alloc_by_type = intel_i830_alloc_by_type, 1974 .alloc_by_type = intel_i830_alloc_by_type,
1919 .free_by_type = intel_i810_free_by_type, 1975 .free_by_type = intel_i810_free_by_type,
1920 .agp_alloc_page = agp_generic_alloc_page, 1976 .agp_alloc_page = agp_generic_alloc_page,
1921 .agp_destroy_page = agp_generic_destroy_page, 1977 .agp_destroy_page = agp_generic_destroy_page,
1922 .agp_type_to_mask_type = intel_i830_type_to_mask_type, 1978 .agp_type_to_mask_type = intel_i830_type_to_mask_type,
1923 .chipset_flush = intel_i915_chipset_flush, 1979 .chipset_flush = intel_i915_chipset_flush,
1924}; 1980};
1925 1981
@@ -1948,28 +2004,28 @@ static const struct agp_bridge_driver intel_7505_driver = {
1948}; 2004};
1949 2005
1950static const struct agp_bridge_driver intel_g33_driver = { 2006static const struct agp_bridge_driver intel_g33_driver = {
1951 .owner = THIS_MODULE, 2007 .owner = THIS_MODULE,
1952 .aperture_sizes = intel_i830_sizes, 2008 .aperture_sizes = intel_i830_sizes,
1953 .size_type = FIXED_APER_SIZE, 2009 .size_type = FIXED_APER_SIZE,
1954 .num_aperture_sizes = 4, 2010 .num_aperture_sizes = 4,
1955 .needs_scratch_page = TRUE, 2011 .needs_scratch_page = true,
1956 .configure = intel_i915_configure, 2012 .configure = intel_i915_configure,
1957 .fetch_size = intel_i9xx_fetch_size, 2013 .fetch_size = intel_i9xx_fetch_size,
1958 .cleanup = intel_i915_cleanup, 2014 .cleanup = intel_i915_cleanup,
1959 .tlb_flush = intel_i810_tlbflush, 2015 .tlb_flush = intel_i810_tlbflush,
1960 .mask_memory = intel_i965_mask_memory, 2016 .mask_memory = intel_i965_mask_memory,
1961 .masks = intel_i810_masks, 2017 .masks = intel_i810_masks,
1962 .agp_enable = intel_i810_agp_enable, 2018 .agp_enable = intel_i810_agp_enable,
1963 .cache_flush = global_cache_flush, 2019 .cache_flush = global_cache_flush,
1964 .create_gatt_table = intel_i915_create_gatt_table, 2020 .create_gatt_table = intel_i915_create_gatt_table,
1965 .free_gatt_table = intel_i830_free_gatt_table, 2021 .free_gatt_table = intel_i830_free_gatt_table,
1966 .insert_memory = intel_i915_insert_entries, 2022 .insert_memory = intel_i915_insert_entries,
1967 .remove_memory = intel_i915_remove_entries, 2023 .remove_memory = intel_i915_remove_entries,
1968 .alloc_by_type = intel_i830_alloc_by_type, 2024 .alloc_by_type = intel_i830_alloc_by_type,
1969 .free_by_type = intel_i810_free_by_type, 2025 .free_by_type = intel_i810_free_by_type,
1970 .agp_alloc_page = agp_generic_alloc_page, 2026 .agp_alloc_page = agp_generic_alloc_page,
1971 .agp_destroy_page = agp_generic_destroy_page, 2027 .agp_destroy_page = agp_generic_destroy_page,
1972 .agp_type_to_mask_type = intel_i830_type_to_mask_type, 2028 .agp_type_to_mask_type = intel_i830_type_to_mask_type,
1973 .chipset_flush = intel_i915_chipset_flush, 2029 .chipset_flush = intel_i915_chipset_flush,
1974}; 2030};
1975 2031
@@ -2063,6 +2119,12 @@ static const struct intel_driver_description {
2063 NULL, &intel_g33_driver }, 2119 NULL, &intel_g33_driver },
2064 { PCI_DEVICE_ID_INTEL_IGD_HB, PCI_DEVICE_ID_INTEL_IGD_IG, 0, 2120 { PCI_DEVICE_ID_INTEL_IGD_HB, PCI_DEVICE_ID_INTEL_IGD_IG, 0,
2065 "Intel Integrated Graphics Device", NULL, &intel_i965_driver }, 2121 "Intel Integrated Graphics Device", NULL, &intel_i965_driver },
2122 { PCI_DEVICE_ID_INTEL_IGD_E_HB, PCI_DEVICE_ID_INTEL_IGD_E_IG, 0,
2123 "Intel Integrated Graphics Device", NULL, &intel_i965_driver },
2124 { PCI_DEVICE_ID_INTEL_Q45_HB, PCI_DEVICE_ID_INTEL_Q45_IG, 0,
2125 "Q45/Q43", NULL, &intel_i965_driver },
2126 { PCI_DEVICE_ID_INTEL_G45_HB, PCI_DEVICE_ID_INTEL_G45_IG, 0,
2127 "G45/G43", NULL, &intel_i965_driver },
2066 { 0, 0, 0, NULL, NULL, NULL } 2128 { 0, 0, 0, NULL, NULL, NULL }
2067}; 2129};
2068 2130
@@ -2254,6 +2316,9 @@ static struct pci_device_id agp_intel_pci_table[] = {
2254 ID(PCI_DEVICE_ID_INTEL_Q35_HB), 2316 ID(PCI_DEVICE_ID_INTEL_Q35_HB),
2255 ID(PCI_DEVICE_ID_INTEL_Q33_HB), 2317 ID(PCI_DEVICE_ID_INTEL_Q33_HB),
2256 ID(PCI_DEVICE_ID_INTEL_IGD_HB), 2318 ID(PCI_DEVICE_ID_INTEL_IGD_HB),
2319 ID(PCI_DEVICE_ID_INTEL_IGD_E_HB),
2320 ID(PCI_DEVICE_ID_INTEL_Q45_HB),
2321 ID(PCI_DEVICE_ID_INTEL_G45_HB),
2257 { } 2322 { }
2258}; 2323};
2259 2324
diff --git a/drivers/char/agp/nvidia-agp.c b/drivers/char/agp/nvidia-agp.c
index 225ed2a53d45..eaceb61ba2dc 100644
--- a/drivers/char/agp/nvidia-agp.c
+++ b/drivers/char/agp/nvidia-agp.c
@@ -214,9 +214,9 @@ static int nvidia_insert_memory(struct agp_memory *mem, off_t pg_start, int type
214 return -EBUSY; 214 return -EBUSY;
215 } 215 }
216 216
217 if (mem->is_flushed == FALSE) { 217 if (!mem->is_flushed) {
218 global_cache_flush(); 218 global_cache_flush();
219 mem->is_flushed = TRUE; 219 mem->is_flushed = true;
220 } 220 }
221 for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { 221 for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
222 writel(agp_bridge->driver->mask_memory(agp_bridge, 222 writel(agp_bridge->driver->mask_memory(agp_bridge,
diff --git a/drivers/char/agp/parisc-agp.c b/drivers/char/agp/parisc-agp.c
index 2939e3570f9d..8c42dcc5958c 100644
--- a/drivers/char/agp/parisc-agp.c
+++ b/drivers/char/agp/parisc-agp.c
@@ -141,9 +141,9 @@ parisc_agp_insert_memory(struct agp_memory *mem, off_t pg_start, int type)
141 j++; 141 j++;
142 } 142 }
143 143
144 if (mem->is_flushed == FALSE) { 144 if (!mem->is_flushed) {
145 global_cache_flush(); 145 global_cache_flush();
146 mem->is_flushed = TRUE; 146 mem->is_flushed = true;
147 } 147 }
148 148
149 for (i = 0, j = io_pg_start; i < mem->page_count; i++) { 149 for (i = 0, j = io_pg_start; i < mem->page_count; i++) {
@@ -226,7 +226,7 @@ static const struct agp_bridge_driver parisc_agp_driver = {
226 .agp_alloc_page = agp_generic_alloc_page, 226 .agp_alloc_page = agp_generic_alloc_page,
227 .agp_destroy_page = agp_generic_destroy_page, 227 .agp_destroy_page = agp_generic_destroy_page,
228 .agp_type_to_mask_type = agp_generic_type_to_mask_type, 228 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
229 .cant_use_aperture = 1, 229 .cant_use_aperture = true,
230}; 230};
231 231
232static int __init 232static int __init
diff --git a/drivers/char/agp/sgi-agp.c b/drivers/char/agp/sgi-agp.c
index 98cf8abb3e57..b972d83bb1b2 100644
--- a/drivers/char/agp/sgi-agp.c
+++ b/drivers/char/agp/sgi-agp.c
@@ -182,9 +182,9 @@ static int sgi_tioca_insert_memory(struct agp_memory *mem, off_t pg_start,
182 j++; 182 j++;
183 } 183 }
184 184
185 if (mem->is_flushed == FALSE) { 185 if (!mem->is_flushed) {
186 bridge->driver->cache_flush(); 186 bridge->driver->cache_flush();
187 mem->is_flushed = TRUE; 187 mem->is_flushed = true;
188 } 188 }
189 189
190 for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { 190 for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
@@ -264,8 +264,8 @@ const struct agp_bridge_driver sgi_tioca_driver = {
264 .agp_alloc_page = sgi_tioca_alloc_page, 264 .agp_alloc_page = sgi_tioca_alloc_page,
265 .agp_destroy_page = agp_generic_destroy_page, 265 .agp_destroy_page = agp_generic_destroy_page,
266 .agp_type_to_mask_type = agp_generic_type_to_mask_type, 266 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
267 .cant_use_aperture = 1, 267 .cant_use_aperture = true,
268 .needs_scratch_page = 0, 268 .needs_scratch_page = false,
269 .num_aperture_sizes = 1, 269 .num_aperture_sizes = 1,
270}; 270};
271 271
diff --git a/drivers/char/agp/sworks-agp.c b/drivers/char/agp/sworks-agp.c
index e08934e58f32..0e054c134490 100644
--- a/drivers/char/agp/sworks-agp.c
+++ b/drivers/char/agp/sworks-agp.c
@@ -339,9 +339,9 @@ static int serverworks_insert_memory(struct agp_memory *mem,
339 j++; 339 j++;
340 } 340 }
341 341
342 if (mem->is_flushed == FALSE) { 342 if (!mem->is_flushed) {
343 global_cache_flush(); 343 global_cache_flush();
344 mem->is_flushed = TRUE; 344 mem->is_flushed = true;
345 } 345 }
346 346
347 for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { 347 for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
@@ -412,7 +412,7 @@ static void serverworks_agp_enable(struct agp_bridge_data *bridge, u32 mode)
412 bridge->capndx + PCI_AGP_COMMAND, 412 bridge->capndx + PCI_AGP_COMMAND,
413 command); 413 command);
414 414
415 agp_device_command(command, 0); 415 agp_device_command(command, false);
416} 416}
417 417
418static const struct agp_bridge_driver sworks_driver = { 418static const struct agp_bridge_driver sworks_driver = {
diff --git a/drivers/char/agp/uninorth-agp.c b/drivers/char/agp/uninorth-agp.c
index 42c0a600b1ac..d2fa3cfca02a 100644
--- a/drivers/char/agp/uninorth-agp.c
+++ b/drivers/char/agp/uninorth-agp.c
@@ -281,10 +281,10 @@ static void uninorth_agp_enable(struct agp_bridge_data *bridge, u32 mode)
281 281
282 if (uninorth_rev >= 0x30) { 282 if (uninorth_rev >= 0x30) {
283 /* This is an AGP V3 */ 283 /* This is an AGP V3 */
284 agp_device_command(command, (status & AGPSTAT_MODE_3_0)); 284 agp_device_command(command, (status & AGPSTAT_MODE_3_0) != 0);
285 } else { 285 } else {
286 /* AGP V2 */ 286 /* AGP V2 */
287 agp_device_command(command, 0); 287 agp_device_command(command, false);
288 } 288 }
289 289
290 uninorth_tlbflush(NULL); 290 uninorth_tlbflush(NULL);
@@ -511,7 +511,7 @@ const struct agp_bridge_driver uninorth_agp_driver = {
511 .agp_alloc_page = agp_generic_alloc_page, 511 .agp_alloc_page = agp_generic_alloc_page,
512 .agp_destroy_page = agp_generic_destroy_page, 512 .agp_destroy_page = agp_generic_destroy_page,
513 .agp_type_to_mask_type = agp_generic_type_to_mask_type, 513 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
514 .cant_use_aperture = 1, 514 .cant_use_aperture = true,
515}; 515};
516 516
517const struct agp_bridge_driver u3_agp_driver = { 517const struct agp_bridge_driver u3_agp_driver = {
@@ -536,8 +536,8 @@ const struct agp_bridge_driver u3_agp_driver = {
536 .agp_alloc_page = agp_generic_alloc_page, 536 .agp_alloc_page = agp_generic_alloc_page,
537 .agp_destroy_page = agp_generic_destroy_page, 537 .agp_destroy_page = agp_generic_destroy_page,
538 .agp_type_to_mask_type = agp_generic_type_to_mask_type, 538 .agp_type_to_mask_type = agp_generic_type_to_mask_type,
539 .cant_use_aperture = 1, 539 .cant_use_aperture = true,
540 .needs_scratch_page = 1, 540 .needs_scratch_page = true,
541}; 541};
542 542
543static struct agp_device_ids uninorth_agp_device_ids[] __devinitdata = { 543static struct agp_device_ids uninorth_agp_device_ids[] __devinitdata = {
diff --git a/drivers/char/agp/via-agp.c b/drivers/char/agp/via-agp.c
index 0ecc54d327bc..7b36476dff41 100644
--- a/drivers/char/agp/via-agp.c
+++ b/drivers/char/agp/via-agp.c
@@ -389,11 +389,20 @@ static struct agp_device_ids via_agp_device_ids[] __devinitdata =
389 .device_id = PCI_DEVICE_ID_VIA_VT3324, 389 .device_id = PCI_DEVICE_ID_VIA_VT3324,
390 .chipset_name = "CX700", 390 .chipset_name = "CX700",
391 }, 391 },
392 /* VT3336 */ 392 /* VT3336 - this is a chipset for AMD Athlon/K8 CPU. Due to K8's unique
393 * architecture, the AGP resource and behavior are different from
394 * the traditional AGP which resides only in chipset. AGP is used
395 * by 3D driver which wasn't available for the VT3336 and VT3364
396 * generation until now. Unfortunately, by testing, VT3364 works
397 * but VT3336 doesn't. - explaination from via, just leave this as
398 * as a placeholder to avoid future patches adding it back in.
399 */
400#if 0
393 { 401 {
394 .device_id = PCI_DEVICE_ID_VIA_VT3336, 402 .device_id = PCI_DEVICE_ID_VIA_VT3336,
395 .chipset_name = "VT3336", 403 .chipset_name = "VT3336",
396 }, 404 },
405#endif
397 /* P4M890 */ 406 /* P4M890 */
398 { 407 {
399 .device_id = PCI_DEVICE_ID_VIA_P4M890, 408 .device_id = PCI_DEVICE_ID_VIA_P4M890,
@@ -546,8 +555,8 @@ static const struct pci_device_id agp_via_pci_table[] = {
546 ID(PCI_DEVICE_ID_VIA_3296_0), 555 ID(PCI_DEVICE_ID_VIA_3296_0),
547 ID(PCI_DEVICE_ID_VIA_P4M800CE), 556 ID(PCI_DEVICE_ID_VIA_P4M800CE),
548 ID(PCI_DEVICE_ID_VIA_VT3324), 557 ID(PCI_DEVICE_ID_VIA_VT3324),
549 ID(PCI_DEVICE_ID_VIA_VT3336),
550 ID(PCI_DEVICE_ID_VIA_P4M890), 558 ID(PCI_DEVICE_ID_VIA_P4M890),
559 ID(PCI_DEVICE_ID_VIA_VT3364),
551 { } 560 { }
552}; 561};
553 562
diff --git a/drivers/char/apm-emulation.c b/drivers/char/apm-emulation.c
index cdd876dbb2b0..aaca40283be9 100644
--- a/drivers/char/apm-emulation.c
+++ b/drivers/char/apm-emulation.c
@@ -13,6 +13,7 @@
13#include <linux/module.h> 13#include <linux/module.h>
14#include <linux/poll.h> 14#include <linux/poll.h>
15#include <linux/slab.h> 15#include <linux/slab.h>
16#include <linux/smp_lock.h>
16#include <linux/proc_fs.h> 17#include <linux/proc_fs.h>
17#include <linux/seq_file.h> 18#include <linux/seq_file.h>
18#include <linux/miscdevice.h> 19#include <linux/miscdevice.h>
@@ -58,6 +59,55 @@ struct apm_queue {
58}; 59};
59 60
60/* 61/*
62 * thread states (for threads using a writable /dev/apm_bios fd):
63 *
64 * SUSPEND_NONE: nothing happening
65 * SUSPEND_PENDING: suspend event queued for thread and pending to be read
66 * SUSPEND_READ: suspend event read, pending acknowledgement
67 * SUSPEND_ACKED: acknowledgement received from thread (via ioctl),
68 * waiting for resume
69 * SUSPEND_ACKTO: acknowledgement timeout
70 * SUSPEND_DONE: thread had acked suspend and is now notified of
71 * resume
72 *
73 * SUSPEND_WAIT: this thread invoked suspend and is waiting for resume
74 *
75 * A thread migrates in one of three paths:
76 * NONE -1-> PENDING -2-> READ -3-> ACKED -4-> DONE -5-> NONE
77 * -6-> ACKTO -7-> NONE
78 * NONE -8-> WAIT -9-> NONE
79 *
80 * While in PENDING or READ, the thread is accounted for in the
81 * suspend_acks_pending counter.
82 *
83 * The transitions are invoked as follows:
84 * 1: suspend event is signalled from the core PM code
85 * 2: the suspend event is read from the fd by the userspace thread
86 * 3: userspace thread issues the APM_IOC_SUSPEND ioctl (as ack)
87 * 4: core PM code signals that we have resumed
88 * 5: APM_IOC_SUSPEND ioctl returns
89 *
90 * 6: the notifier invoked from the core PM code timed out waiting
91 * for all relevant threds to enter ACKED state and puts those
92 * that haven't into ACKTO
93 * 7: those threads issue APM_IOC_SUSPEND ioctl too late,
94 * get an error
95 *
96 * 8: userspace thread issues the APM_IOC_SUSPEND ioctl (to suspend),
97 * ioctl code invokes pm_suspend()
98 * 9: pm_suspend() returns indicating resume
99 */
100enum apm_suspend_state {
101 SUSPEND_NONE,
102 SUSPEND_PENDING,
103 SUSPEND_READ,
104 SUSPEND_ACKED,
105 SUSPEND_ACKTO,
106 SUSPEND_WAIT,
107 SUSPEND_DONE,
108};
109
110/*
61 * The per-file APM data 111 * The per-file APM data
62 */ 112 */
63struct apm_user { 113struct apm_user {
@@ -68,13 +118,7 @@ struct apm_user {
68 unsigned int reader: 1; 118 unsigned int reader: 1;
69 119
70 int suspend_result; 120 int suspend_result;
71 unsigned int suspend_state; 121 enum apm_suspend_state suspend_state;
72#define SUSPEND_NONE 0 /* no suspend pending */
73#define SUSPEND_PENDING 1 /* suspend pending read */
74#define SUSPEND_READ 2 /* suspend read, pending ack */
75#define SUSPEND_ACKED 3 /* suspend acked */
76#define SUSPEND_WAIT 4 /* waiting for suspend */
77#define SUSPEND_DONE 5 /* suspend completed */
78 122
79 struct apm_queue queue; 123 struct apm_queue queue;
80}; 124};
@@ -82,7 +126,8 @@ struct apm_user {
82/* 126/*
83 * Local variables 127 * Local variables
84 */ 128 */
85static int suspends_pending; 129static atomic_t suspend_acks_pending = ATOMIC_INIT(0);
130static atomic_t userspace_notification_inhibit = ATOMIC_INIT(0);
86static int apm_disabled; 131static int apm_disabled;
87static struct task_struct *kapmd_tsk; 132static struct task_struct *kapmd_tsk;
88 133
@@ -165,78 +210,6 @@ static void queue_event(apm_event_t event)
165 wake_up_interruptible(&apm_waitqueue); 210 wake_up_interruptible(&apm_waitqueue);
166} 211}
167 212
168/*
169 * queue_suspend_event - queue an APM suspend event.
170 *
171 * Check that we're in a state where we can suspend. If not,
172 * return -EBUSY. Otherwise, queue an event to all "writer"
173 * users. If there are no "writer" users, return '1' to
174 * indicate that we can immediately suspend.
175 */
176static int queue_suspend_event(apm_event_t event, struct apm_user *sender)
177{
178 struct apm_user *as;
179 int ret = 1;
180
181 mutex_lock(&state_lock);
182 down_read(&user_list_lock);
183
184 /*
185 * If a thread is still processing, we can't suspend, so reject
186 * the request.
187 */
188 list_for_each_entry(as, &apm_user_list, list) {
189 if (as != sender && as->reader && as->writer && as->suser &&
190 as->suspend_state != SUSPEND_NONE) {
191 ret = -EBUSY;
192 goto out;
193 }
194 }
195
196 list_for_each_entry(as, &apm_user_list, list) {
197 if (as != sender && as->reader && as->writer && as->suser) {
198 as->suspend_state = SUSPEND_PENDING;
199 suspends_pending++;
200 queue_add_event(&as->queue, event);
201 ret = 0;
202 }
203 }
204 out:
205 up_read(&user_list_lock);
206 mutex_unlock(&state_lock);
207 wake_up_interruptible(&apm_waitqueue);
208 return ret;
209}
210
211static void apm_suspend(void)
212{
213 struct apm_user *as;
214 int err = pm_suspend(PM_SUSPEND_MEM);
215
216 /*
217 * Anyone on the APM queues will think we're still suspended.
218 * Send a message so everyone knows we're now awake again.
219 */
220 queue_event(APM_NORMAL_RESUME);
221
222 /*
223 * Finally, wake up anyone who is sleeping on the suspend.
224 */
225 mutex_lock(&state_lock);
226 down_read(&user_list_lock);
227 list_for_each_entry(as, &apm_user_list, list) {
228 if (as->suspend_state == SUSPEND_WAIT ||
229 as->suspend_state == SUSPEND_ACKED) {
230 as->suspend_result = err;
231 as->suspend_state = SUSPEND_DONE;
232 }
233 }
234 up_read(&user_list_lock);
235 mutex_unlock(&state_lock);
236
237 wake_up(&apm_suspend_waitqueue);
238}
239
240static ssize_t apm_read(struct file *fp, char __user *buf, size_t count, loff_t *ppos) 213static ssize_t apm_read(struct file *fp, char __user *buf, size_t count, loff_t *ppos)
241{ 214{
242 struct apm_user *as = fp->private_data; 215 struct apm_user *as = fp->private_data;
@@ -307,25 +280,22 @@ apm_ioctl(struct inode * inode, struct file *filp, u_int cmd, u_long arg)
307 280
308 as->suspend_result = -EINTR; 281 as->suspend_result = -EINTR;
309 282
310 if (as->suspend_state == SUSPEND_READ) { 283 switch (as->suspend_state) {
311 int pending; 284 case SUSPEND_READ:
312
313 /* 285 /*
314 * If we read a suspend command from /dev/apm_bios, 286 * If we read a suspend command from /dev/apm_bios,
315 * then the corresponding APM_IOC_SUSPEND ioctl is 287 * then the corresponding APM_IOC_SUSPEND ioctl is
316 * interpreted as an acknowledge. 288 * interpreted as an acknowledge.
317 */ 289 */
318 as->suspend_state = SUSPEND_ACKED; 290 as->suspend_state = SUSPEND_ACKED;
319 suspends_pending--; 291 atomic_dec(&suspend_acks_pending);
320 pending = suspends_pending == 0;
321 mutex_unlock(&state_lock); 292 mutex_unlock(&state_lock);
322 293
323 /* 294 /*
324 * If there are no further acknowledges required, 295 * suspend_acks_pending changed, the notifier needs to
325 * suspend the system. 296 * be woken up for this
326 */ 297 */
327 if (pending) 298 wake_up(&apm_suspend_waitqueue);
328 apm_suspend();
329 299
330 /* 300 /*
331 * Wait for the suspend/resume to complete. If there 301 * Wait for the suspend/resume to complete. If there
@@ -341,35 +311,21 @@ apm_ioctl(struct inode * inode, struct file *filp, u_int cmd, u_long arg)
341 * try_to_freeze() in freezer_count() will not trigger 311 * try_to_freeze() in freezer_count() will not trigger
342 */ 312 */
343 freezer_count(); 313 freezer_count();
344 } else { 314 break;
315 case SUSPEND_ACKTO:
316 as->suspend_result = -ETIMEDOUT;
317 mutex_unlock(&state_lock);
318 break;
319 default:
345 as->suspend_state = SUSPEND_WAIT; 320 as->suspend_state = SUSPEND_WAIT;
346 mutex_unlock(&state_lock); 321 mutex_unlock(&state_lock);
347 322
348 /* 323 /*
349 * Otherwise it is a request to suspend the system. 324 * Otherwise it is a request to suspend the system.
350 * Queue an event for all readers, and expect an 325 * Just invoke pm_suspend(), we'll handle it from
351 * acknowledge from all writers who haven't already 326 * there via the notifier.
352 * acknowledged.
353 */
354 err = queue_suspend_event(APM_USER_SUSPEND, as);
355 if (err < 0) {
356 /*
357 * Avoid taking the lock here - this
358 * should be fine.
359 */
360 as->suspend_state = SUSPEND_NONE;
361 break;
362 }
363
364 if (err > 0)
365 apm_suspend();
366
367 /*
368 * Wait for the suspend/resume to complete. If there
369 * are pending acknowledges, we wait here for them.
370 */ 327 */
371 wait_event_freezable(apm_suspend_waitqueue, 328 as->suspend_result = pm_suspend(PM_SUSPEND_MEM);
372 as->suspend_state == SUSPEND_DONE);
373 } 329 }
374 330
375 mutex_lock(&state_lock); 331 mutex_lock(&state_lock);
@@ -385,7 +341,6 @@ apm_ioctl(struct inode * inode, struct file *filp, u_int cmd, u_long arg)
385static int apm_release(struct inode * inode, struct file * filp) 341static int apm_release(struct inode * inode, struct file * filp)
386{ 342{
387 struct apm_user *as = filp->private_data; 343 struct apm_user *as = filp->private_data;
388 int pending = 0;
389 344
390 filp->private_data = NULL; 345 filp->private_data = NULL;
391 346
@@ -395,18 +350,15 @@ static int apm_release(struct inode * inode, struct file * filp)
395 350
396 /* 351 /*
397 * We are now unhooked from the chain. As far as new 352 * We are now unhooked from the chain. As far as new
398 * events are concerned, we no longer exist. However, we 353 * events are concerned, we no longer exist.
399 * need to balance suspends_pending, which means the
400 * possibility of sleeping.
401 */ 354 */
402 mutex_lock(&state_lock); 355 mutex_lock(&state_lock);
403 if (as->suspend_state != SUSPEND_NONE) { 356 if (as->suspend_state == SUSPEND_PENDING ||
404 suspends_pending -= 1; 357 as->suspend_state == SUSPEND_READ)
405 pending = suspends_pending == 0; 358 atomic_dec(&suspend_acks_pending);
406 }
407 mutex_unlock(&state_lock); 359 mutex_unlock(&state_lock);
408 if (pending) 360
409 apm_suspend(); 361 wake_up(&apm_suspend_waitqueue);
410 362
411 kfree(as); 363 kfree(as);
412 return 0; 364 return 0;
@@ -416,6 +368,7 @@ static int apm_open(struct inode * inode, struct file * filp)
416{ 368{
417 struct apm_user *as; 369 struct apm_user *as;
418 370
371 lock_kernel();
419 as = kzalloc(sizeof(*as), GFP_KERNEL); 372 as = kzalloc(sizeof(*as), GFP_KERNEL);
420 if (as) { 373 if (as) {
421 /* 374 /*
@@ -435,6 +388,7 @@ static int apm_open(struct inode * inode, struct file * filp)
435 388
436 filp->private_data = as; 389 filp->private_data = as;
437 } 390 }
391 unlock_kernel();
438 392
439 return as ? 0 : -ENOMEM; 393 return as ? 0 : -ENOMEM;
440} 394}
@@ -542,7 +496,6 @@ static int kapmd(void *arg)
542{ 496{
543 do { 497 do {
544 apm_event_t event; 498 apm_event_t event;
545 int ret;
546 499
547 wait_event_interruptible(kapmd_wait, 500 wait_event_interruptible(kapmd_wait,
548 !queue_empty(&kapmd_queue) || kthread_should_stop()); 501 !queue_empty(&kapmd_queue) || kthread_should_stop());
@@ -567,20 +520,13 @@ static int kapmd(void *arg)
567 520
568 case APM_USER_SUSPEND: 521 case APM_USER_SUSPEND:
569 case APM_SYS_SUSPEND: 522 case APM_SYS_SUSPEND:
570 ret = queue_suspend_event(event, NULL); 523 pm_suspend(PM_SUSPEND_MEM);
571 if (ret < 0) {
572 /*
573 * We were busy. Try again in 50ms.
574 */
575 queue_add_event(&kapmd_queue, event);
576 msleep(50);
577 }
578 if (ret > 0)
579 apm_suspend();
580 break; 524 break;
581 525
582 case APM_CRITICAL_SUSPEND: 526 case APM_CRITICAL_SUSPEND:
583 apm_suspend(); 527 atomic_inc(&userspace_notification_inhibit);
528 pm_suspend(PM_SUSPEND_MEM);
529 atomic_dec(&userspace_notification_inhibit);
584 break; 530 break;
585 } 531 }
586 } while (1); 532 } while (1);
@@ -588,6 +534,120 @@ static int kapmd(void *arg)
588 return 0; 534 return 0;
589} 535}
590 536
537static int apm_suspend_notifier(struct notifier_block *nb,
538 unsigned long event,
539 void *dummy)
540{
541 struct apm_user *as;
542 int err;
543
544 /* short-cut emergency suspends */
545 if (atomic_read(&userspace_notification_inhibit))
546 return NOTIFY_DONE;
547
548 switch (event) {
549 case PM_SUSPEND_PREPARE:
550 /*
551 * Queue an event to all "writer" users that we want
552 * to suspend and need their ack.
553 */
554 mutex_lock(&state_lock);
555 down_read(&user_list_lock);
556
557 list_for_each_entry(as, &apm_user_list, list) {
558 if (as->suspend_state != SUSPEND_WAIT && as->reader &&
559 as->writer && as->suser) {
560 as->suspend_state = SUSPEND_PENDING;
561 atomic_inc(&suspend_acks_pending);
562 queue_add_event(&as->queue, APM_USER_SUSPEND);
563 }
564 }
565
566 up_read(&user_list_lock);
567 mutex_unlock(&state_lock);
568 wake_up_interruptible(&apm_waitqueue);
569
570 /*
571 * Wait for the the suspend_acks_pending variable to drop to
572 * zero, meaning everybody acked the suspend event (or the
573 * process was killed.)
574 *
575 * If the app won't answer within a short while we assume it
576 * locked up and ignore it.
577 */
578 err = wait_event_interruptible_timeout(
579 apm_suspend_waitqueue,
580 atomic_read(&suspend_acks_pending) == 0,
581 5*HZ);
582
583 /* timed out */
584 if (err == 0) {
585 /*
586 * Move anybody who timed out to "ack timeout" state.
587 *
588 * We could time out and the userspace does the ACK
589 * right after we time out but before we enter the
590 * locked section here, but that's fine.
591 */
592 mutex_lock(&state_lock);
593 down_read(&user_list_lock);
594 list_for_each_entry(as, &apm_user_list, list) {
595 if (as->suspend_state == SUSPEND_PENDING ||
596 as->suspend_state == SUSPEND_READ) {
597 as->suspend_state = SUSPEND_ACKTO;
598 atomic_dec(&suspend_acks_pending);
599 }
600 }
601 up_read(&user_list_lock);
602 mutex_unlock(&state_lock);
603 }
604
605 /* let suspend proceed */
606 if (err >= 0)
607 return NOTIFY_OK;
608
609 /* interrupted by signal */
610 return NOTIFY_BAD;
611
612 case PM_POST_SUSPEND:
613 /*
614 * Anyone on the APM queues will think we're still suspended.
615 * Send a message so everyone knows we're now awake again.
616 */
617 queue_event(APM_NORMAL_RESUME);
618
619 /*
620 * Finally, wake up anyone who is sleeping on the suspend.
621 */
622 mutex_lock(&state_lock);
623 down_read(&user_list_lock);
624 list_for_each_entry(as, &apm_user_list, list) {
625 if (as->suspend_state == SUSPEND_ACKED) {
626 /*
627 * TODO: maybe grab error code, needs core
628 * changes to push the error to the notifier
629 * chain (could use the second parameter if
630 * implemented)
631 */
632 as->suspend_result = 0;
633 as->suspend_state = SUSPEND_DONE;
634 }
635 }
636 up_read(&user_list_lock);
637 mutex_unlock(&state_lock);
638
639 wake_up(&apm_suspend_waitqueue);
640 return NOTIFY_OK;
641
642 default:
643 return NOTIFY_DONE;
644 }
645}
646
647static struct notifier_block apm_notif_block = {
648 .notifier_call = apm_suspend_notifier,
649};
650
591static int __init apm_init(void) 651static int __init apm_init(void)
592{ 652{
593 int ret; 653 int ret;
@@ -601,7 +661,7 @@ static int __init apm_init(void)
601 if (IS_ERR(kapmd_tsk)) { 661 if (IS_ERR(kapmd_tsk)) {
602 ret = PTR_ERR(kapmd_tsk); 662 ret = PTR_ERR(kapmd_tsk);
603 kapmd_tsk = NULL; 663 kapmd_tsk = NULL;
604 return ret; 664 goto out;
605 } 665 }
606 wake_up_process(kapmd_tsk); 666 wake_up_process(kapmd_tsk);
607 667
@@ -610,16 +670,27 @@ static int __init apm_init(void)
610#endif 670#endif
611 671
612 ret = misc_register(&apm_device); 672 ret = misc_register(&apm_device);
613 if (ret != 0) { 673 if (ret)
614 remove_proc_entry("apm", NULL); 674 goto out_stop;
615 kthread_stop(kapmd_tsk);
616 }
617 675
676 ret = register_pm_notifier(&apm_notif_block);
677 if (ret)
678 goto out_unregister;
679
680 return 0;
681
682 out_unregister:
683 misc_deregister(&apm_device);
684 out_stop:
685 remove_proc_entry("apm", NULL);
686 kthread_stop(kapmd_tsk);
687 out:
618 return ret; 688 return ret;
619} 689}
620 690
621static void __exit apm_exit(void) 691static void __exit apm_exit(void)
622{ 692{
693 unregister_pm_notifier(&apm_notif_block);
623 misc_deregister(&apm_device); 694 misc_deregister(&apm_device);
624 remove_proc_entry("apm", NULL); 695 remove_proc_entry("apm", NULL);
625 696
diff --git a/drivers/char/briq_panel.c b/drivers/char/briq_panel.c
index b6f2639f903d..d8cff909001c 100644
--- a/drivers/char/briq_panel.c
+++ b/drivers/char/briq_panel.c
@@ -6,6 +6,7 @@
6 6
7#include <linux/module.h> 7#include <linux/module.h>
8 8
9#include <linux/smp_lock.h>
9#include <linux/types.h> 10#include <linux/types.h>
10#include <linux/errno.h> 11#include <linux/errno.h>
11#include <linux/tty.h> 12#include <linux/tty.h>
@@ -67,11 +68,15 @@ static void set_led(char state)
67 68
68static int briq_panel_open(struct inode *ino, struct file *filep) 69static int briq_panel_open(struct inode *ino, struct file *filep)
69{ 70{
70 /* enforce single access */ 71 lock_kernel();
71 if (vfd_is_open) 72 /* enforce single access, vfd_is_open is protected by BKL */
73 if (vfd_is_open) {
74 unlock_kernel();
72 return -EBUSY; 75 return -EBUSY;
76 }
73 vfd_is_open = 1; 77 vfd_is_open = 1;
74 78
79 unlock_kernel();
75 return 0; 80 return 0;
76} 81}
77 82
diff --git a/drivers/char/bsr.c b/drivers/char/bsr.c
new file mode 100644
index 000000000000..b650b4e48e50
--- /dev/null
+++ b/drivers/char/bsr.c
@@ -0,0 +1,312 @@
1/* IBM POWER Barrier Synchronization Register Driver
2 *
3 * Copyright IBM Corporation 2008
4 *
5 * Author: Sonny Rao <sonnyrao@us.ibm.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22#include <linux/kernel.h>
23#include <linux/of.h>
24#include <linux/of_device.h>
25#include <linux/of_platform.h>
26#include <linux/module.h>
27#include <linux/cdev.h>
28#include <linux/list.h>
29#include <linux/mm.h>
30#include <asm/io.h>
31
32/*
33 This driver exposes a special register which can be used for fast
34 synchronization across a large SMP machine. The hardware is exposed
35 as an array of bytes where each process will write to one of the bytes to
36 indicate it has finished the current stage and this update is broadcast to
37 all processors without having to bounce a cacheline between them. In
38 POWER5 and POWER6 there is one of these registers per SMP, but it is
39 presented in two forms; first, it is given as a whole and then as a number
40 of smaller registers which alias to parts of the single whole register.
41 This can potentially allow multiple groups of processes to each have their
42 own private synchronization device.
43
44 Note that this hardware *must* be written to using *only* single byte writes.
45 It may be read using 1, 2, 4, or 8 byte loads which must be aligned since
46 this region is treated as cache-inhibited processes should also use a
47 full sync before and after writing to the BSR to ensure all stores and
48 the BSR update have made it to all chips in the system
49*/
50
51/* This is arbitrary number, up to Power6 it's been 17 or fewer */
52#define BSR_MAX_DEVS (32)
53
54struct bsr_dev {
55 u64 bsr_addr; /* Real address */
56 u64 bsr_len; /* length of mem region we can map */
57 unsigned bsr_bytes; /* size of the BSR reg itself */
58 unsigned bsr_stride; /* interval at which BSR repeats in the page */
59 unsigned bsr_type; /* maps to enum below */
60 unsigned bsr_num; /* bsr id number for its type */
61 int bsr_minor;
62
63 dev_t bsr_dev;
64 struct cdev bsr_cdev;
65 struct device *bsr_device;
66 char bsr_name[32];
67
68};
69
70static unsigned num_bsr_devs;
71static struct bsr_dev *bsr_devs;
72static struct class *bsr_class;
73static int bsr_major;
74
75enum {
76 BSR_8 = 0,
77 BSR_16 = 1,
78 BSR_64 = 2,
79 BSR_128 = 3,
80 BSR_UNKNOWN = 4,
81 BSR_MAX = 5,
82};
83
84static unsigned bsr_types[BSR_MAX];
85
86static ssize_t
87bsr_size_show(struct device *dev, struct device_attribute *attr, char *buf)
88{
89 struct bsr_dev *bsr_dev = dev_get_drvdata(dev);
90 return sprintf(buf, "%u\n", bsr_dev->bsr_bytes);
91}
92
93static ssize_t
94bsr_stride_show(struct device *dev, struct device_attribute *attr, char *buf)
95{
96 struct bsr_dev *bsr_dev = dev_get_drvdata(dev);
97 return sprintf(buf, "%u\n", bsr_dev->bsr_stride);
98}
99
100static ssize_t
101bsr_len_show(struct device *dev, struct device_attribute *attr, char *buf)
102{
103 struct bsr_dev *bsr_dev = dev_get_drvdata(dev);
104 return sprintf(buf, "%lu\n", bsr_dev->bsr_len);
105}
106
107static struct device_attribute bsr_dev_attrs[] = {
108 __ATTR(bsr_size, S_IRUGO, bsr_size_show, NULL),
109 __ATTR(bsr_stride, S_IRUGO, bsr_stride_show, NULL),
110 __ATTR(bsr_length, S_IRUGO, bsr_len_show, NULL),
111 __ATTR_NULL
112};
113
114static int bsr_mmap(struct file *filp, struct vm_area_struct *vma)
115{
116 unsigned long size = vma->vm_end - vma->vm_start;
117 struct bsr_dev *dev = filp->private_data;
118
119 if (size > dev->bsr_len || (size & (PAGE_SIZE-1)))
120 return -EINVAL;
121
122 vma->vm_flags |= (VM_IO | VM_DONTEXPAND);
123 vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
124
125 if (io_remap_pfn_range(vma, vma->vm_start, dev->bsr_addr >> PAGE_SHIFT,
126 size, vma->vm_page_prot))
127 return -EAGAIN;
128
129 return 0;
130}
131
132static int bsr_open(struct inode * inode, struct file * filp)
133{
134 struct cdev *cdev = inode->i_cdev;
135 struct bsr_dev *dev = container_of(cdev, struct bsr_dev, bsr_cdev);
136
137 filp->private_data = dev;
138 return 0;
139}
140
141const static struct file_operations bsr_fops = {
142 .owner = THIS_MODULE,
143 .mmap = bsr_mmap,
144 .open = bsr_open,
145};
146
147static void bsr_cleanup_devs(void)
148{
149 int i;
150 for (i=0 ; i < num_bsr_devs; i++) {
151 struct bsr_dev *cur = bsr_devs + i;
152 if (cur->bsr_device) {
153 cdev_del(&cur->bsr_cdev);
154 device_del(cur->bsr_device);
155 }
156 }
157
158 kfree(bsr_devs);
159}
160
161static int bsr_create_devs(struct device_node *bn)
162{
163 int bsr_stride_len, bsr_bytes_len;
164 const u32 *bsr_stride;
165 const u32 *bsr_bytes;
166 unsigned i;
167
168 bsr_stride = of_get_property(bn, "ibm,lock-stride", &bsr_stride_len);
169 bsr_bytes = of_get_property(bn, "ibm,#lock-bytes", &bsr_bytes_len);
170
171 if (!bsr_stride || !bsr_bytes ||
172 (bsr_stride_len != bsr_bytes_len)) {
173 printk(KERN_ERR "bsr of-node has missing/incorrect property\n");
174 return -ENODEV;
175 }
176
177 num_bsr_devs = bsr_bytes_len / sizeof(u32);
178
179 /* only a warning, its informational since we'll fail and exit */
180 WARN_ON(num_bsr_devs > BSR_MAX_DEVS);
181
182 bsr_devs = kzalloc(sizeof(struct bsr_dev) * num_bsr_devs, GFP_KERNEL);
183 if (!bsr_devs)
184 return -ENOMEM;
185
186 for (i = 0 ; i < num_bsr_devs; i++) {
187 struct bsr_dev *cur = bsr_devs + i;
188 struct resource res;
189 int result;
190
191 result = of_address_to_resource(bn, i, &res);
192 if (result < 0) {
193 printk(KERN_ERR "bsr of-node has invalid reg property\n");
194 goto out_err;
195 }
196
197 cur->bsr_minor = i;
198 cur->bsr_addr = res.start;
199 cur->bsr_len = res.end - res.start + 1;
200 cur->bsr_bytes = bsr_bytes[i];
201 cur->bsr_stride = bsr_stride[i];
202 cur->bsr_dev = MKDEV(bsr_major, i);
203
204 switch(cur->bsr_bytes) {
205 case 8:
206 cur->bsr_type = BSR_8;
207 break;
208 case 16:
209 cur->bsr_type = BSR_16;
210 break;
211 case 64:
212 cur->bsr_type = BSR_64;
213 break;
214 case 128:
215 cur->bsr_type = BSR_128;
216 break;
217 default:
218 cur->bsr_type = BSR_UNKNOWN;
219 printk(KERN_INFO "unknown BSR size %d\n",cur->bsr_bytes);
220 }
221
222 cur->bsr_num = bsr_types[cur->bsr_type];
223 bsr_types[cur->bsr_type] = cur->bsr_num + 1;
224 snprintf(cur->bsr_name, 32, "bsr%d_%d",
225 cur->bsr_bytes, cur->bsr_num);
226
227 cdev_init(&cur->bsr_cdev, &bsr_fops);
228 result = cdev_add(&cur->bsr_cdev, cur->bsr_dev, 1);
229 if (result)
230 goto out_err;
231
232 cur->bsr_device = device_create_drvdata(bsr_class, NULL,
233 cur->bsr_dev,
234 cur, cur->bsr_name);
235 if (!cur->bsr_device) {
236 printk(KERN_ERR "device_create failed for %s\n",
237 cur->bsr_name);
238 cdev_del(&cur->bsr_cdev);
239 goto out_err;
240 }
241 }
242
243 return 0;
244
245 out_err:
246
247 bsr_cleanup_devs();
248 return -ENODEV;
249}
250
251static int __init bsr_init(void)
252{
253 struct device_node *np;
254 dev_t bsr_dev = MKDEV(bsr_major, 0);
255 int ret = -ENODEV;
256 int result;
257
258 np = of_find_compatible_node(NULL, "ibm,bsr", "ibm,bsr");
259 if (!np)
260 goto out_err;
261
262 bsr_class = class_create(THIS_MODULE, "bsr");
263 if (IS_ERR(bsr_class)) {
264 printk(KERN_ERR "class_create() failed for bsr_class\n");
265 goto out_err_1;
266 }
267 bsr_class->dev_attrs = bsr_dev_attrs;
268
269 result = alloc_chrdev_region(&bsr_dev, 0, BSR_MAX_DEVS, "bsr");
270 bsr_major = MAJOR(bsr_dev);
271 if (result < 0) {
272 printk(KERN_ERR "alloc_chrdev_region() failed for bsr\n");
273 goto out_err_2;
274 }
275
276 if ((ret = bsr_create_devs(np)) < 0)
277 goto out_err_3;
278
279 of_node_put(np);
280
281 return 0;
282
283 out_err_3:
284 unregister_chrdev_region(bsr_dev, BSR_MAX_DEVS);
285
286 out_err_2:
287 class_destroy(bsr_class);
288
289 out_err_1:
290 of_node_put(np);
291
292 out_err:
293
294 return ret;
295}
296
297static void __exit bsr_exit(void)
298{
299
300 bsr_cleanup_devs();
301
302 if (bsr_class)
303 class_destroy(bsr_class);
304
305 if (bsr_major)
306 unregister_chrdev_region(MKDEV(bsr_major, 0), BSR_MAX_DEVS);
307}
308
309module_init(bsr_init);
310module_exit(bsr_exit);
311MODULE_LICENSE("GPL");
312MODULE_AUTHOR("Sonny Rao <sonnyrao@us.ibm.com>");
diff --git a/drivers/char/cs5535_gpio.c b/drivers/char/cs5535_gpio.c
index c0a4a0bb509e..04ba906b4880 100644
--- a/drivers/char/cs5535_gpio.c
+++ b/drivers/char/cs5535_gpio.c
@@ -17,6 +17,7 @@
17#include <linux/cdev.h> 17#include <linux/cdev.h>
18#include <linux/ioport.h> 18#include <linux/ioport.h>
19#include <linux/pci.h> 19#include <linux/pci.h>
20#include <linux/smp_lock.h>
20#include <asm/uaccess.h> 21#include <asm/uaccess.h>
21#include <asm/io.h> 22#include <asm/io.h>
22 23
@@ -157,6 +158,7 @@ static int cs5535_gpio_open(struct inode *inode, struct file *file)
157{ 158{
158 u32 m = iminor(inode); 159 u32 m = iminor(inode);
159 160
161 cycle_kernel_lock();
160 /* the mask says which pins are usable by this driver */ 162 /* the mask says which pins are usable by this driver */
161 if ((mask & (1 << m)) == 0) 163 if ((mask & (1 << m)) == 0)
162 return -EINVAL; 164 return -EINVAL;
diff --git a/drivers/char/cyclades.c b/drivers/char/cyclades.c
index ef73e72daedc..e991dc85f2fb 100644
--- a/drivers/char/cyclades.c
+++ b/drivers/char/cyclades.c
@@ -762,7 +762,7 @@ static int cy_next_channel; /* next minor available */
762/* 762/*
763 * This is used to look up the divisor speeds and the timeouts 763 * This is used to look up the divisor speeds and the timeouts
764 * We're normally limited to 15 distinct baud rates. The extra 764 * We're normally limited to 15 distinct baud rates. The extra
765 * are accessed via settings in info->flags. 765 * are accessed via settings in info->port.flags.
766 * 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 766 * 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
767 * 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 767 * 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
768 * HI VHI 768 * HI VHI
@@ -1003,7 +1003,7 @@ static void cyy_chip_rx(struct cyclades_card *cinfo, int chip,
1003 cy_writeb(base_addr + (CyCAR << index), save_xir); 1003 cy_writeb(base_addr + (CyCAR << index), save_xir);
1004 1004
1005 /* if there is nowhere to put the data, discard it */ 1005 /* if there is nowhere to put the data, discard it */
1006 if (info->tty == NULL) { 1006 if (info->port.tty == NULL) {
1007 if ((readb(base_addr + (CyRIVR << index)) & CyIVRMask) == 1007 if ((readb(base_addr + (CyRIVR << index)) & CyIVRMask) ==
1008 CyIVRRxEx) { /* exception */ 1008 CyIVRRxEx) { /* exception */
1009 data = readb(base_addr + (CyRDSR << index)); 1009 data = readb(base_addr + (CyRDSR << index));
@@ -1015,7 +1015,7 @@ static void cyy_chip_rx(struct cyclades_card *cinfo, int chip,
1015 goto end; 1015 goto end;
1016 } 1016 }
1017 /* there is an open port for this data */ 1017 /* there is an open port for this data */
1018 tty = info->tty; 1018 tty = info->port.tty;
1019 if ((readb(base_addr + (CyRIVR << index)) & CyIVRMask) == 1019 if ((readb(base_addr + (CyRIVR << index)) & CyIVRMask) ==
1020 CyIVRRxEx) { /* exception */ 1020 CyIVRRxEx) { /* exception */
1021 data = readb(base_addr + (CyRDSR << index)); 1021 data = readb(base_addr + (CyRDSR << index));
@@ -1041,7 +1041,7 @@ static void cyy_chip_rx(struct cyclades_card *cinfo, int chip,
1041 readb(base_addr + (CyRDSR << 1041 readb(base_addr + (CyRDSR <<
1042 index)), TTY_BREAK); 1042 index)), TTY_BREAK);
1043 info->icount.rx++; 1043 info->icount.rx++;
1044 if (info->flags & ASYNC_SAK) 1044 if (info->port.flags & ASYNC_SAK)
1045 do_SAK(tty); 1045 do_SAK(tty);
1046 } else if (data & CyFRAME) { 1046 } else if (data & CyFRAME) {
1047 tty_insert_flip_char(tty, 1047 tty_insert_flip_char(tty,
@@ -1145,7 +1145,7 @@ static void cyy_chip_tx(struct cyclades_card *cinfo, unsigned int chip,
1145 goto end; 1145 goto end;
1146 } 1146 }
1147 info = &cinfo->ports[channel + chip * 4]; 1147 info = &cinfo->ports[channel + chip * 4];
1148 if (info->tty == NULL) { 1148 if (info->port.tty == NULL) {
1149 cy_writeb(base_addr + (CySRER << index), 1149 cy_writeb(base_addr + (CySRER << index),
1150 readb(base_addr + (CySRER << index)) & ~CyTxRdy); 1150 readb(base_addr + (CySRER << index)) & ~CyTxRdy);
1151 goto end; 1151 goto end;
@@ -1190,13 +1190,13 @@ static void cyy_chip_tx(struct cyclades_card *cinfo, unsigned int chip,
1190 } 1190 }
1191 goto done; 1191 goto done;
1192 } 1192 }
1193 if (info->xmit_buf == NULL) { 1193 if (info->port.xmit_buf == NULL) {
1194 cy_writeb(base_addr + (CySRER << index), 1194 cy_writeb(base_addr + (CySRER << index),
1195 readb(base_addr + (CySRER << index)) & 1195 readb(base_addr + (CySRER << index)) &
1196 ~CyTxRdy); 1196 ~CyTxRdy);
1197 goto done; 1197 goto done;
1198 } 1198 }
1199 if (info->tty->stopped || info->tty->hw_stopped) { 1199 if (info->port.tty->stopped || info->port.tty->hw_stopped) {
1200 cy_writeb(base_addr + (CySRER << index), 1200 cy_writeb(base_addr + (CySRER << index),
1201 readb(base_addr + (CySRER << index)) & 1201 readb(base_addr + (CySRER << index)) &
1202 ~CyTxRdy); 1202 ~CyTxRdy);
@@ -1211,7 +1211,7 @@ static void cyy_chip_tx(struct cyclades_card *cinfo, unsigned int chip,
1211 * character. This is necessary because there may not be room 1211 * character. This is necessary because there may not be room
1212 * for the two chars needed to send a NULL.) 1212 * for the two chars needed to send a NULL.)
1213 */ 1213 */
1214 outch = info->xmit_buf[info->xmit_tail]; 1214 outch = info->port.xmit_buf[info->xmit_tail];
1215 if (outch) { 1215 if (outch) {
1216 info->xmit_cnt--; 1216 info->xmit_cnt--;
1217 info->xmit_tail = (info->xmit_tail + 1) & 1217 info->xmit_tail = (info->xmit_tail + 1) &
@@ -1232,7 +1232,7 @@ static void cyy_chip_tx(struct cyclades_card *cinfo, unsigned int chip,
1232 } 1232 }
1233 1233
1234done: 1234done:
1235 tty_wakeup(info->tty); 1235 tty_wakeup(info->port.tty);
1236end: 1236end:
1237 /* end of service */ 1237 /* end of service */
1238 cy_writeb(base_addr + (CyTIR << index), save_xir & 0x3f); 1238 cy_writeb(base_addr + (CyTIR << index), save_xir & 0x3f);
@@ -1256,7 +1256,7 @@ static void cyy_chip_modem(struct cyclades_card *cinfo, int chip,
1256 mdm_change = readb(base_addr + (CyMISR << index)); 1256 mdm_change = readb(base_addr + (CyMISR << index));
1257 mdm_status = readb(base_addr + (CyMSVR1 << index)); 1257 mdm_status = readb(base_addr + (CyMSVR1 << index));
1258 1258
1259 if (!info->tty) 1259 if (!info->port.tty)
1260 goto end; 1260 goto end;
1261 1261
1262 if (mdm_change & CyANY_DELTA) { 1262 if (mdm_change & CyANY_DELTA) {
@@ -1273,29 +1273,29 @@ static void cyy_chip_modem(struct cyclades_card *cinfo, int chip,
1273 wake_up_interruptible(&info->delta_msr_wait); 1273 wake_up_interruptible(&info->delta_msr_wait);
1274 } 1274 }
1275 1275
1276 if ((mdm_change & CyDCD) && (info->flags & ASYNC_CHECK_CD)) { 1276 if ((mdm_change & CyDCD) && (info->port.flags & ASYNC_CHECK_CD)) {
1277 if (!(mdm_status & CyDCD)) { 1277 if (!(mdm_status & CyDCD)) {
1278 tty_hangup(info->tty); 1278 tty_hangup(info->port.tty);
1279 info->flags &= ~ASYNC_NORMAL_ACTIVE; 1279 info->port.flags &= ~ASYNC_NORMAL_ACTIVE;
1280 } 1280 }
1281 wake_up_interruptible(&info->open_wait); 1281 wake_up_interruptible(&info->port.open_wait);
1282 } 1282 }
1283 if ((mdm_change & CyCTS) && (info->flags & ASYNC_CTS_FLOW)) { 1283 if ((mdm_change & CyCTS) && (info->port.flags & ASYNC_CTS_FLOW)) {
1284 if (info->tty->hw_stopped) { 1284 if (info->port.tty->hw_stopped) {
1285 if (mdm_status & CyCTS) { 1285 if (mdm_status & CyCTS) {
1286 /* cy_start isn't used 1286 /* cy_start isn't used
1287 because... !!! */ 1287 because... !!! */
1288 info->tty->hw_stopped = 0; 1288 info->port.tty->hw_stopped = 0;
1289 cy_writeb(base_addr + (CySRER << index), 1289 cy_writeb(base_addr + (CySRER << index),
1290 readb(base_addr + (CySRER << index)) | 1290 readb(base_addr + (CySRER << index)) |
1291 CyTxRdy); 1291 CyTxRdy);
1292 tty_wakeup(info->tty); 1292 tty_wakeup(info->port.tty);
1293 } 1293 }
1294 } else { 1294 } else {
1295 if (!(mdm_status & CyCTS)) { 1295 if (!(mdm_status & CyCTS)) {
1296 /* cy_stop isn't used 1296 /* cy_stop isn't used
1297 because ... !!! */ 1297 because ... !!! */
1298 info->tty->hw_stopped = 1; 1298 info->port.tty->hw_stopped = 1;
1299 cy_writeb(base_addr + (CySRER << index), 1299 cy_writeb(base_addr + (CySRER << index),
1300 readb(base_addr + (CySRER << index)) & 1300 readb(base_addr + (CySRER << index)) &
1301 ~CyTxRdy); 1301 ~CyTxRdy);
@@ -1449,7 +1449,7 @@ static void cyz_handle_rx(struct cyclades_port *info,
1449 struct BUF_CTRL __iomem *buf_ctrl) 1449 struct BUF_CTRL __iomem *buf_ctrl)
1450{ 1450{
1451 struct cyclades_card *cinfo = info->card; 1451 struct cyclades_card *cinfo = info->card;
1452 struct tty_struct *tty = info->tty; 1452 struct tty_struct *tty = info->port.tty;
1453 unsigned int char_count; 1453 unsigned int char_count;
1454 int len; 1454 int len;
1455#ifdef BLOCKMOVE 1455#ifdef BLOCKMOVE
@@ -1542,7 +1542,7 @@ static void cyz_handle_tx(struct cyclades_port *info,
1542 struct BUF_CTRL __iomem *buf_ctrl) 1542 struct BUF_CTRL __iomem *buf_ctrl)
1543{ 1543{
1544 struct cyclades_card *cinfo = info->card; 1544 struct cyclades_card *cinfo = info->card;
1545 struct tty_struct *tty = info->tty; 1545 struct tty_struct *tty = info->port.tty;
1546 u8 data; 1546 u8 data;
1547 unsigned int char_count; 1547 unsigned int char_count;
1548#ifdef BLOCKMOVE 1548#ifdef BLOCKMOVE
@@ -1585,7 +1585,7 @@ static void cyz_handle_tx(struct cyclades_port *info,
1585 1585
1586 memcpy_toio((char *)(cinfo->base_addr + tx_bufaddr + 1586 memcpy_toio((char *)(cinfo->base_addr + tx_bufaddr +
1587 tx_put), 1587 tx_put),
1588 &info->xmit_buf[info->xmit_tail], 1588 &info->port.xmit_buf[info->xmit_tail],
1589 small_count); 1589 small_count);
1590 1590
1591 tx_put = (tx_put + small_count) & (tx_bufsize - 1); 1591 tx_put = (tx_put + small_count) & (tx_bufsize - 1);
@@ -1597,7 +1597,7 @@ static void cyz_handle_tx(struct cyclades_port *info,
1597 } 1597 }
1598#else 1598#else
1599 while (info->xmit_cnt && char_count) { 1599 while (info->xmit_cnt && char_count) {
1600 data = info->xmit_buf[info->xmit_tail]; 1600 data = info->port.xmit_buf[info->xmit_tail];
1601 info->xmit_cnt--; 1601 info->xmit_cnt--;
1602 info->xmit_tail = (info->xmit_tail + 1) & 1602 info->xmit_tail = (info->xmit_tail + 1) &
1603 (SERIAL_XMIT_SIZE - 1); 1603 (SERIAL_XMIT_SIZE - 1);
@@ -1642,7 +1642,7 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo)
1642 special_count = 0; 1642 special_count = 0;
1643 delta_count = 0; 1643 delta_count = 0;
1644 info = &cinfo->ports[channel]; 1644 info = &cinfo->ports[channel];
1645 tty = info->tty; 1645 tty = info->port.tty;
1646 if (tty == NULL) 1646 if (tty == NULL)
1647 continue; 1647 continue;
1648 1648
@@ -1668,15 +1668,15 @@ static void cyz_handle_cmd(struct cyclades_card *cinfo)
1668 case C_CM_MDCD: 1668 case C_CM_MDCD:
1669 info->icount.dcd++; 1669 info->icount.dcd++;
1670 delta_count++; 1670 delta_count++;
1671 if (info->flags & ASYNC_CHECK_CD) { 1671 if (info->port.flags & ASYNC_CHECK_CD) {
1672 if ((fw_ver > 241 ? ((u_long) param) : 1672 if ((fw_ver > 241 ? ((u_long) param) :
1673 readl(&ch_ctrl->rs_status)) & 1673 readl(&ch_ctrl->rs_status)) &
1674 C_RS_DCD) { 1674 C_RS_DCD) {
1675 wake_up_interruptible(&info->open_wait); 1675 wake_up_interruptible(&info->port.open_wait);
1676 } else { 1676 } else {
1677 tty_hangup(info->tty); 1677 tty_hangup(info->port.tty);
1678 wake_up_interruptible(&info->open_wait); 1678 wake_up_interruptible(&info->port.open_wait);
1679 info->flags &= ~ASYNC_NORMAL_ACTIVE; 1679 info->port.flags &= ~ASYNC_NORMAL_ACTIVE;
1680 } 1680 }
1681 } 1681 }
1682 break; 1682 break;
@@ -1814,7 +1814,7 @@ static void cyz_poll(unsigned long arg)
1814 1814
1815 for (port = 0; port < cinfo->nports; port++) { 1815 for (port = 0; port < cinfo->nports; port++) {
1816 info = &cinfo->ports[port]; 1816 info = &cinfo->ports[port];
1817 tty = info->tty; 1817 tty = info->port.tty;
1818 buf_ctrl = &(zfw_ctrl->buf_ctrl[port]); 1818 buf_ctrl = &(zfw_ctrl->buf_ctrl[port]);
1819 1819
1820 if (!info->throttle) 1820 if (!info->throttle)
@@ -1853,22 +1853,22 @@ static int startup(struct cyclades_port *info)
1853 1853
1854 spin_lock_irqsave(&card->card_lock, flags); 1854 spin_lock_irqsave(&card->card_lock, flags);
1855 1855
1856 if (info->flags & ASYNC_INITIALIZED) { 1856 if (info->port.flags & ASYNC_INITIALIZED) {
1857 free_page(page); 1857 free_page(page);
1858 goto errout; 1858 goto errout;
1859 } 1859 }
1860 1860
1861 if (!info->type) { 1861 if (!info->type) {
1862 if (info->tty) 1862 if (info->port.tty)
1863 set_bit(TTY_IO_ERROR, &info->tty->flags); 1863 set_bit(TTY_IO_ERROR, &info->port.tty->flags);
1864 free_page(page); 1864 free_page(page);
1865 goto errout; 1865 goto errout;
1866 } 1866 }
1867 1867
1868 if (info->xmit_buf) 1868 if (info->port.xmit_buf)
1869 free_page(page); 1869 free_page(page);
1870 else 1870 else
1871 info->xmit_buf = (unsigned char *)page; 1871 info->port.xmit_buf = (unsigned char *)page;
1872 1872
1873 spin_unlock_irqrestore(&card->card_lock, flags); 1873 spin_unlock_irqrestore(&card->card_lock, flags);
1874 1874
@@ -1909,10 +1909,10 @@ static int startup(struct cyclades_port *info)
1909 1909
1910 cy_writeb(base_addr + (CySRER << index), 1910 cy_writeb(base_addr + (CySRER << index),
1911 readb(base_addr + (CySRER << index)) | CyRxData); 1911 readb(base_addr + (CySRER << index)) | CyRxData);
1912 info->flags |= ASYNC_INITIALIZED; 1912 info->port.flags |= ASYNC_INITIALIZED;
1913 1913
1914 if (info->tty) 1914 if (info->port.tty)
1915 clear_bit(TTY_IO_ERROR, &info->tty->flags); 1915 clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
1916 info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; 1916 info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
1917 info->breakon = info->breakoff = 0; 1917 info->breakon = info->breakoff = 0;
1918 memset((char *)&info->idle_stats, 0, sizeof(info->idle_stats)); 1918 memset((char *)&info->idle_stats, 0, sizeof(info->idle_stats));
@@ -1994,9 +1994,9 @@ static int startup(struct cyclades_port *info)
1994 1994
1995 /* enable send, recv, modem !!! */ 1995 /* enable send, recv, modem !!! */
1996 1996
1997 info->flags |= ASYNC_INITIALIZED; 1997 info->port.flags |= ASYNC_INITIALIZED;
1998 if (info->tty) 1998 if (info->port.tty)
1999 clear_bit(TTY_IO_ERROR, &info->tty->flags); 1999 clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
2000 info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; 2000 info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
2001 info->breakon = info->breakoff = 0; 2001 info->breakon = info->breakoff = 0;
2002 memset((char *)&info->idle_stats, 0, sizeof(info->idle_stats)); 2002 memset((char *)&info->idle_stats, 0, sizeof(info->idle_stats));
@@ -2065,7 +2065,7 @@ static void shutdown(struct cyclades_port *info)
2065 void __iomem *base_addr; 2065 void __iomem *base_addr;
2066 int chip, channel, index; 2066 int chip, channel, index;
2067 2067
2068 if (!(info->flags & ASYNC_INITIALIZED)) 2068 if (!(info->port.flags & ASYNC_INITIALIZED))
2069 return; 2069 return;
2070 2070
2071 card = info->card; 2071 card = info->card;
@@ -2087,14 +2087,14 @@ static void shutdown(struct cyclades_port *info)
2087 /* Clear delta_msr_wait queue to avoid mem leaks. */ 2087 /* Clear delta_msr_wait queue to avoid mem leaks. */
2088 wake_up_interruptible(&info->delta_msr_wait); 2088 wake_up_interruptible(&info->delta_msr_wait);
2089 2089
2090 if (info->xmit_buf) { 2090 if (info->port.xmit_buf) {
2091 unsigned char *temp; 2091 unsigned char *temp;
2092 temp = info->xmit_buf; 2092 temp = info->port.xmit_buf;
2093 info->xmit_buf = NULL; 2093 info->port.xmit_buf = NULL;
2094 free_page((unsigned long)temp); 2094 free_page((unsigned long)temp);
2095 } 2095 }
2096 cy_writeb(base_addr + (CyCAR << index), (u_char) channel); 2096 cy_writeb(base_addr + (CyCAR << index), (u_char) channel);
2097 if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) { 2097 if (!info->port.tty || (info->port.tty->termios->c_cflag & HUPCL)) {
2098 cy_writeb(base_addr + (CyMSVR1 << index), ~CyRTS); 2098 cy_writeb(base_addr + (CyMSVR1 << index), ~CyRTS);
2099 cy_writeb(base_addr + (CyMSVR2 << index), ~CyDTR); 2099 cy_writeb(base_addr + (CyMSVR2 << index), ~CyDTR);
2100#ifdef CY_DEBUG_DTR 2100#ifdef CY_DEBUG_DTR
@@ -2108,9 +2108,9 @@ static void shutdown(struct cyclades_port *info)
2108 /* it may be appropriate to clear _XMIT at 2108 /* it may be appropriate to clear _XMIT at
2109 some later date (after testing)!!! */ 2109 some later date (after testing)!!! */
2110 2110
2111 if (info->tty) 2111 if (info->port.tty)
2112 set_bit(TTY_IO_ERROR, &info->tty->flags); 2112 set_bit(TTY_IO_ERROR, &info->port.tty->flags);
2113 info->flags &= ~ASYNC_INITIALIZED; 2113 info->port.flags &= ~ASYNC_INITIALIZED;
2114 spin_unlock_irqrestore(&card->card_lock, flags); 2114 spin_unlock_irqrestore(&card->card_lock, flags);
2115 } else { 2115 } else {
2116 struct FIRM_ID __iomem *firm_id; 2116 struct FIRM_ID __iomem *firm_id;
@@ -2136,14 +2136,14 @@ static void shutdown(struct cyclades_port *info)
2136 2136
2137 spin_lock_irqsave(&card->card_lock, flags); 2137 spin_lock_irqsave(&card->card_lock, flags);
2138 2138
2139 if (info->xmit_buf) { 2139 if (info->port.xmit_buf) {
2140 unsigned char *temp; 2140 unsigned char *temp;
2141 temp = info->xmit_buf; 2141 temp = info->port.xmit_buf;
2142 info->xmit_buf = NULL; 2142 info->port.xmit_buf = NULL;
2143 free_page((unsigned long)temp); 2143 free_page((unsigned long)temp);
2144 } 2144 }
2145 2145
2146 if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) { 2146 if (!info->port.tty || (info->port.tty->termios->c_cflag & HUPCL)) {
2147 cy_writel(&ch_ctrl[channel].rs_control, 2147 cy_writel(&ch_ctrl[channel].rs_control,
2148 (__u32)(readl(&ch_ctrl[channel].rs_control) & 2148 (__u32)(readl(&ch_ctrl[channel].rs_control) &
2149 ~(C_RS_RTS | C_RS_DTR))); 2149 ~(C_RS_RTS | C_RS_DTR)));
@@ -2158,9 +2158,9 @@ static void shutdown(struct cyclades_port *info)
2158#endif 2158#endif
2159 } 2159 }
2160 2160
2161 if (info->tty) 2161 if (info->port.tty)
2162 set_bit(TTY_IO_ERROR, &info->tty->flags); 2162 set_bit(TTY_IO_ERROR, &info->port.tty->flags);
2163 info->flags &= ~ASYNC_INITIALIZED; 2163 info->port.flags &= ~ASYNC_INITIALIZED;
2164 2164
2165 spin_unlock_irqrestore(&card->card_lock, flags); 2165 spin_unlock_irqrestore(&card->card_lock, flags);
2166 } 2166 }
@@ -2194,10 +2194,10 @@ block_til_ready(struct tty_struct *tty, struct file *filp,
2194 * If the device is in the middle of being closed, then block 2194 * If the device is in the middle of being closed, then block
2195 * until it's done, and then try again. 2195 * until it's done, and then try again.
2196 */ 2196 */
2197 if (tty_hung_up_p(filp) || (info->flags & ASYNC_CLOSING)) { 2197 if (tty_hung_up_p(filp) || (info->port.flags & ASYNC_CLOSING)) {
2198 wait_event_interruptible(info->close_wait, 2198 wait_event_interruptible(info->port.close_wait,
2199 !(info->flags & ASYNC_CLOSING)); 2199 !(info->port.flags & ASYNC_CLOSING));
2200 return (info->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN: -ERESTARTSYS; 2200 return (info->port.flags & ASYNC_HUP_NOTIFY) ? -EAGAIN: -ERESTARTSYS;
2201 } 2201 }
2202 2202
2203 /* 2203 /*
@@ -2206,32 +2206,32 @@ block_til_ready(struct tty_struct *tty, struct file *filp,
2206 */ 2206 */
2207 if ((filp->f_flags & O_NONBLOCK) || 2207 if ((filp->f_flags & O_NONBLOCK) ||
2208 (tty->flags & (1 << TTY_IO_ERROR))) { 2208 (tty->flags & (1 << TTY_IO_ERROR))) {
2209 info->flags |= ASYNC_NORMAL_ACTIVE; 2209 info->port.flags |= ASYNC_NORMAL_ACTIVE;
2210 return 0; 2210 return 0;
2211 } 2211 }
2212 2212
2213 /* 2213 /*
2214 * Block waiting for the carrier detect and the line to become 2214 * Block waiting for the carrier detect and the line to become
2215 * free (i.e., not in use by the callout). While we are in 2215 * free (i.e., not in use by the callout). While we are in
2216 * this loop, info->count is dropped by one, so that 2216 * this loop, info->port.count is dropped by one, so that
2217 * cy_close() knows when to free things. We restore it upon 2217 * cy_close() knows when to free things. We restore it upon
2218 * exit, either normal or abnormal. 2218 * exit, either normal or abnormal.
2219 */ 2219 */
2220 retval = 0; 2220 retval = 0;
2221 add_wait_queue(&info->open_wait, &wait); 2221 add_wait_queue(&info->port.open_wait, &wait);
2222#ifdef CY_DEBUG_OPEN 2222#ifdef CY_DEBUG_OPEN
2223 printk(KERN_DEBUG "cyc block_til_ready before block: ttyC%d, " 2223 printk(KERN_DEBUG "cyc block_til_ready before block: ttyC%d, "
2224 "count = %d\n", info->line, info->count); 2224 "count = %d\n", info->line, info->port.count);
2225#endif 2225#endif
2226 spin_lock_irqsave(&cinfo->card_lock, flags); 2226 spin_lock_irqsave(&cinfo->card_lock, flags);
2227 if (!tty_hung_up_p(filp)) 2227 if (!tty_hung_up_p(filp))
2228 info->count--; 2228 info->port.count--;
2229 spin_unlock_irqrestore(&cinfo->card_lock, flags); 2229 spin_unlock_irqrestore(&cinfo->card_lock, flags);
2230#ifdef CY_DEBUG_COUNT 2230#ifdef CY_DEBUG_COUNT
2231 printk(KERN_DEBUG "cyc block_til_ready: (%d): decrementing count to " 2231 printk(KERN_DEBUG "cyc block_til_ready: (%d): decrementing count to "
2232 "%d\n", current->pid, info->count); 2232 "%d\n", current->pid, info->port.count);
2233#endif 2233#endif
2234 info->blocked_open++; 2234 info->port.blocked_open++;
2235 2235
2236 if (!IS_CYC_Z(*cinfo)) { 2236 if (!IS_CYC_Z(*cinfo)) {
2237 chip = channel >> 2; 2237 chip = channel >> 2;
@@ -2260,8 +2260,8 @@ block_til_ready(struct tty_struct *tty, struct file *filp,
2260 2260
2261 set_current_state(TASK_INTERRUPTIBLE); 2261 set_current_state(TASK_INTERRUPTIBLE);
2262 if (tty_hung_up_p(filp) || 2262 if (tty_hung_up_p(filp) ||
2263 !(info->flags & ASYNC_INITIALIZED)) { 2263 !(info->port.flags & ASYNC_INITIALIZED)) {
2264 retval = ((info->flags & ASYNC_HUP_NOTIFY) ? 2264 retval = ((info->port.flags & ASYNC_HUP_NOTIFY) ?
2265 -EAGAIN : -ERESTARTSYS); 2265 -EAGAIN : -ERESTARTSYS);
2266 break; 2266 break;
2267 } 2267 }
@@ -2269,7 +2269,7 @@ block_til_ready(struct tty_struct *tty, struct file *filp,
2269 spin_lock_irqsave(&cinfo->card_lock, flags); 2269 spin_lock_irqsave(&cinfo->card_lock, flags);
2270 cy_writeb(base_addr + (CyCAR << index), 2270 cy_writeb(base_addr + (CyCAR << index),
2271 (u_char) channel); 2271 (u_char) channel);
2272 if (!(info->flags & ASYNC_CLOSING) && (C_CLOCAL(tty) || 2272 if (!(info->port.flags & ASYNC_CLOSING) && (C_CLOCAL(tty) ||
2273 (readb(base_addr + 2273 (readb(base_addr +
2274 (CyMSVR1 << index)) & CyDCD))) { 2274 (CyMSVR1 << index)) & CyDCD))) {
2275 spin_unlock_irqrestore(&cinfo->card_lock, flags); 2275 spin_unlock_irqrestore(&cinfo->card_lock, flags);
@@ -2284,7 +2284,7 @@ block_til_ready(struct tty_struct *tty, struct file *filp,
2284#ifdef CY_DEBUG_OPEN 2284#ifdef CY_DEBUG_OPEN
2285 printk(KERN_DEBUG "cyc block_til_ready blocking: " 2285 printk(KERN_DEBUG "cyc block_til_ready blocking: "
2286 "ttyC%d, count = %d\n", 2286 "ttyC%d, count = %d\n",
2287 info->line, info->count); 2287 info->line, info->port.count);
2288#endif 2288#endif
2289 schedule(); 2289 schedule();
2290 } 2290 }
@@ -2298,7 +2298,7 @@ block_til_ready(struct tty_struct *tty, struct file *filp,
2298 firm_id = base_addr + ID_ADDRESS; 2298 firm_id = base_addr + ID_ADDRESS;
2299 if (!ISZLOADED(*cinfo)) { 2299 if (!ISZLOADED(*cinfo)) {
2300 __set_current_state(TASK_RUNNING); 2300 __set_current_state(TASK_RUNNING);
2301 remove_wait_queue(&info->open_wait, &wait); 2301 remove_wait_queue(&info->port.open_wait, &wait);
2302 return -EINVAL; 2302 return -EINVAL;
2303 } 2303 }
2304 2304
@@ -2327,12 +2327,12 @@ block_til_ready(struct tty_struct *tty, struct file *filp,
2327 2327
2328 set_current_state(TASK_INTERRUPTIBLE); 2328 set_current_state(TASK_INTERRUPTIBLE);
2329 if (tty_hung_up_p(filp) || 2329 if (tty_hung_up_p(filp) ||
2330 !(info->flags & ASYNC_INITIALIZED)) { 2330 !(info->port.flags & ASYNC_INITIALIZED)) {
2331 retval = ((info->flags & ASYNC_HUP_NOTIFY) ? 2331 retval = ((info->port.flags & ASYNC_HUP_NOTIFY) ?
2332 -EAGAIN : -ERESTARTSYS); 2332 -EAGAIN : -ERESTARTSYS);
2333 break; 2333 break;
2334 } 2334 }
2335 if (!(info->flags & ASYNC_CLOSING) && (C_CLOCAL(tty) || 2335 if (!(info->port.flags & ASYNC_CLOSING) && (C_CLOCAL(tty) ||
2336 (readl(&ch_ctrl[channel].rs_status) & 2336 (readl(&ch_ctrl[channel].rs_status) &
2337 C_RS_DCD))) { 2337 C_RS_DCD))) {
2338 break; 2338 break;
@@ -2344,28 +2344,28 @@ block_til_ready(struct tty_struct *tty, struct file *filp,
2344#ifdef CY_DEBUG_OPEN 2344#ifdef CY_DEBUG_OPEN
2345 printk(KERN_DEBUG "cyc block_til_ready blocking: " 2345 printk(KERN_DEBUG "cyc block_til_ready blocking: "
2346 "ttyC%d, count = %d\n", 2346 "ttyC%d, count = %d\n",
2347 info->line, info->count); 2347 info->line, info->port.count);
2348#endif 2348#endif
2349 schedule(); 2349 schedule();
2350 } 2350 }
2351 } 2351 }
2352 __set_current_state(TASK_RUNNING); 2352 __set_current_state(TASK_RUNNING);
2353 remove_wait_queue(&info->open_wait, &wait); 2353 remove_wait_queue(&info->port.open_wait, &wait);
2354 if (!tty_hung_up_p(filp)) { 2354 if (!tty_hung_up_p(filp)) {
2355 info->count++; 2355 info->port.count++;
2356#ifdef CY_DEBUG_COUNT 2356#ifdef CY_DEBUG_COUNT
2357 printk(KERN_DEBUG "cyc:block_til_ready (%d): incrementing " 2357 printk(KERN_DEBUG "cyc:block_til_ready (%d): incrementing "
2358 "count to %d\n", current->pid, info->count); 2358 "count to %d\n", current->pid, info->port.count);
2359#endif 2359#endif
2360 } 2360 }
2361 info->blocked_open--; 2361 info->port.blocked_open--;
2362#ifdef CY_DEBUG_OPEN 2362#ifdef CY_DEBUG_OPEN
2363 printk(KERN_DEBUG "cyc:block_til_ready after blocking: ttyC%d, " 2363 printk(KERN_DEBUG "cyc:block_til_ready after blocking: ttyC%d, "
2364 "count = %d\n", info->line, info->count); 2364 "count = %d\n", info->line, info->port.count);
2365#endif 2365#endif
2366 if (retval) 2366 if (retval)
2367 return retval; 2367 return retval;
2368 info->flags |= ASYNC_NORMAL_ACTIVE; 2368 info->port.flags |= ASYNC_NORMAL_ACTIVE;
2369 return 0; 2369 return 0;
2370} /* block_til_ready */ 2370} /* block_til_ready */
2371 2371
@@ -2456,27 +2456,27 @@ static int cy_open(struct tty_struct *tty, struct file *filp)
2456 printk(KERN_DEBUG "cyc:cy_open ttyC%d\n", info->line); 2456 printk(KERN_DEBUG "cyc:cy_open ttyC%d\n", info->line);
2457#endif 2457#endif
2458 tty->driver_data = info; 2458 tty->driver_data = info;
2459 info->tty = tty; 2459 info->port.tty = tty;
2460 if (serial_paranoia_check(info, tty->name, "cy_open")) 2460 if (serial_paranoia_check(info, tty->name, "cy_open"))
2461 return -ENODEV; 2461 return -ENODEV;
2462 2462
2463#ifdef CY_DEBUG_OPEN 2463#ifdef CY_DEBUG_OPEN
2464 printk(KERN_DEBUG "cyc:cy_open ttyC%d, count = %d\n", info->line, 2464 printk(KERN_DEBUG "cyc:cy_open ttyC%d, count = %d\n", info->line,
2465 info->count); 2465 info->port.count);
2466#endif 2466#endif
2467 info->count++; 2467 info->port.count++;
2468#ifdef CY_DEBUG_COUNT 2468#ifdef CY_DEBUG_COUNT
2469 printk(KERN_DEBUG "cyc:cy_open (%d): incrementing count to %d\n", 2469 printk(KERN_DEBUG "cyc:cy_open (%d): incrementing count to %d\n",
2470 current->pid, info->count); 2470 current->pid, info->port.count);
2471#endif 2471#endif
2472 2472
2473 /* 2473 /*
2474 * If the port is the middle of closing, bail out now 2474 * If the port is the middle of closing, bail out now
2475 */ 2475 */
2476 if (tty_hung_up_p(filp) || (info->flags & ASYNC_CLOSING)) { 2476 if (tty_hung_up_p(filp) || (info->port.flags & ASYNC_CLOSING)) {
2477 wait_event_interruptible(info->close_wait, 2477 wait_event_interruptible(info->port.close_wait,
2478 !(info->flags & ASYNC_CLOSING)); 2478 !(info->port.flags & ASYNC_CLOSING));
2479 return (info->flags & ASYNC_HUP_NOTIFY) ? -EAGAIN: -ERESTARTSYS; 2479 return (info->port.flags & ASYNC_HUP_NOTIFY) ? -EAGAIN: -ERESTARTSYS;
2480 } 2480 }
2481 2481
2482 /* 2482 /*
@@ -2641,9 +2641,9 @@ static void cy_close(struct tty_struct *tty, struct file *filp)
2641 } 2641 }
2642#ifdef CY_DEBUG_OPEN 2642#ifdef CY_DEBUG_OPEN
2643 printk(KERN_DEBUG "cyc:cy_close ttyC%d, count = %d\n", info->line, 2643 printk(KERN_DEBUG "cyc:cy_close ttyC%d, count = %d\n", info->line,
2644 info->count); 2644 info->port.count);
2645#endif 2645#endif
2646 if ((tty->count == 1) && (info->count != 1)) { 2646 if ((tty->count == 1) && (info->port.count != 1)) {
2647 /* 2647 /*
2648 * Uh, oh. tty->count is 1, which means that the tty 2648 * Uh, oh. tty->count is 1, which means that the tty
2649 * structure will be freed. Info->count should always 2649 * structure will be freed. Info->count should always
@@ -2652,24 +2652,24 @@ static void cy_close(struct tty_struct *tty, struct file *filp)
2652 * serial port won't be shutdown. 2652 * serial port won't be shutdown.
2653 */ 2653 */
2654 printk(KERN_ERR "cyc:cy_close: bad serial port count; " 2654 printk(KERN_ERR "cyc:cy_close: bad serial port count; "
2655 "tty->count is 1, info->count is %d\n", info->count); 2655 "tty->count is 1, info->port.count is %d\n", info->port.count);
2656 info->count = 1; 2656 info->port.count = 1;
2657 } 2657 }
2658#ifdef CY_DEBUG_COUNT 2658#ifdef CY_DEBUG_COUNT
2659 printk(KERN_DEBUG "cyc:cy_close at (%d): decrementing count to %d\n", 2659 printk(KERN_DEBUG "cyc:cy_close at (%d): decrementing count to %d\n",
2660 current->pid, info->count - 1); 2660 current->pid, info->port.count - 1);
2661#endif 2661#endif
2662 if (--info->count < 0) { 2662 if (--info->port.count < 0) {
2663#ifdef CY_DEBUG_COUNT 2663#ifdef CY_DEBUG_COUNT
2664 printk(KERN_DEBUG "cyc:cyc_close setting count to 0\n"); 2664 printk(KERN_DEBUG "cyc:cyc_close setting count to 0\n");
2665#endif 2665#endif
2666 info->count = 0; 2666 info->port.count = 0;
2667 } 2667 }
2668 if (info->count) { 2668 if (info->port.count) {
2669 spin_unlock_irqrestore(&card->card_lock, flags); 2669 spin_unlock_irqrestore(&card->card_lock, flags);
2670 return; 2670 return;
2671 } 2671 }
2672 info->flags |= ASYNC_CLOSING; 2672 info->port.flags |= ASYNC_CLOSING;
2673 2673
2674 /* 2674 /*
2675 * Now we wait for the transmit buffer to clear; and we notify 2675 * Now we wait for the transmit buffer to clear; and we notify
@@ -2677,8 +2677,8 @@ static void cy_close(struct tty_struct *tty, struct file *filp)
2677 */ 2677 */
2678 tty->closing = 1; 2678 tty->closing = 1;
2679 spin_unlock_irqrestore(&card->card_lock, flags); 2679 spin_unlock_irqrestore(&card->card_lock, flags);
2680 if (info->closing_wait != CY_CLOSING_WAIT_NONE) 2680 if (info->port.closing_wait != CY_CLOSING_WAIT_NONE)
2681 tty_wait_until_sent(tty, info->closing_wait); 2681 tty_wait_until_sent(tty, info->port.closing_wait);
2682 2682
2683 spin_lock_irqsave(&card->card_lock, flags); 2683 spin_lock_irqsave(&card->card_lock, flags);
2684 2684
@@ -2692,7 +2692,7 @@ static void cy_close(struct tty_struct *tty, struct file *filp)
2692 cy_writeb(base_addr + (CyCAR << index), (u_char) channel); 2692 cy_writeb(base_addr + (CyCAR << index), (u_char) channel);
2693 cy_writeb(base_addr + (CySRER << index), 2693 cy_writeb(base_addr + (CySRER << index),
2694 readb(base_addr + (CySRER << index)) & ~CyRxData); 2694 readb(base_addr + (CySRER << index)) & ~CyRxData);
2695 if (info->flags & ASYNC_INITIALIZED) { 2695 if (info->port.flags & ASYNC_INITIALIZED) {
2696 /* Waiting for on-board buffers to be empty before 2696 /* Waiting for on-board buffers to be empty before
2697 closing the port */ 2697 closing the port */
2698 spin_unlock_irqrestore(&card->card_lock, flags); 2698 spin_unlock_irqrestore(&card->card_lock, flags);
@@ -2731,18 +2731,18 @@ static void cy_close(struct tty_struct *tty, struct file *filp)
2731 spin_lock_irqsave(&card->card_lock, flags); 2731 spin_lock_irqsave(&card->card_lock, flags);
2732 2732
2733 tty->closing = 0; 2733 tty->closing = 0;
2734 info->tty = NULL; 2734 info->port.tty = NULL;
2735 if (info->blocked_open) { 2735 if (info->port.blocked_open) {
2736 spin_unlock_irqrestore(&card->card_lock, flags); 2736 spin_unlock_irqrestore(&card->card_lock, flags);
2737 if (info->close_delay) { 2737 if (info->port.close_delay) {
2738 msleep_interruptible(jiffies_to_msecs 2738 msleep_interruptible(jiffies_to_msecs
2739 (info->close_delay)); 2739 (info->port.close_delay));
2740 } 2740 }
2741 wake_up_interruptible(&info->open_wait); 2741 wake_up_interruptible(&info->port.open_wait);
2742 spin_lock_irqsave(&card->card_lock, flags); 2742 spin_lock_irqsave(&card->card_lock, flags);
2743 } 2743 }
2744 info->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING); 2744 info->port.flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
2745 wake_up_interruptible(&info->close_wait); 2745 wake_up_interruptible(&info->port.close_wait);
2746 2746
2747#ifdef CY_DEBUG_OTHER 2747#ifdef CY_DEBUG_OTHER
2748 printk(KERN_DEBUG "cyc:cy_close done\n"); 2748 printk(KERN_DEBUG "cyc:cy_close done\n");
@@ -2777,7 +2777,7 @@ static int cy_write(struct tty_struct *tty, const unsigned char *buf, int count)
2777 if (serial_paranoia_check(info, tty->name, "cy_write")) 2777 if (serial_paranoia_check(info, tty->name, "cy_write"))
2778 return 0; 2778 return 0;
2779 2779
2780 if (!info->xmit_buf) 2780 if (!info->port.xmit_buf)
2781 return 0; 2781 return 0;
2782 2782
2783 spin_lock_irqsave(&info->card->card_lock, flags); 2783 spin_lock_irqsave(&info->card->card_lock, flags);
@@ -2788,7 +2788,7 @@ static int cy_write(struct tty_struct *tty, const unsigned char *buf, int count)
2788 if (c <= 0) 2788 if (c <= 0)
2789 break; 2789 break;
2790 2790
2791 memcpy(info->xmit_buf + info->xmit_head, buf, c); 2791 memcpy(info->port.xmit_buf + info->xmit_head, buf, c);
2792 info->xmit_head = (info->xmit_head + c) & 2792 info->xmit_head = (info->xmit_head + c) &
2793 (SERIAL_XMIT_SIZE - 1); 2793 (SERIAL_XMIT_SIZE - 1);
2794 info->xmit_cnt += c; 2794 info->xmit_cnt += c;
@@ -2826,7 +2826,7 @@ static int cy_put_char(struct tty_struct *tty, unsigned char ch)
2826 if (serial_paranoia_check(info, tty->name, "cy_put_char")) 2826 if (serial_paranoia_check(info, tty->name, "cy_put_char"))
2827 return 0; 2827 return 0;
2828 2828
2829 if (!info->xmit_buf) 2829 if (!info->port.xmit_buf)
2830 return 0; 2830 return 0;
2831 2831
2832 spin_lock_irqsave(&info->card->card_lock, flags); 2832 spin_lock_irqsave(&info->card->card_lock, flags);
@@ -2835,7 +2835,7 @@ static int cy_put_char(struct tty_struct *tty, unsigned char ch)
2835 return 0; 2835 return 0;
2836 } 2836 }
2837 2837
2838 info->xmit_buf[info->xmit_head++] = ch; 2838 info->port.xmit_buf[info->xmit_head++] = ch;
2839 info->xmit_head &= SERIAL_XMIT_SIZE - 1; 2839 info->xmit_head &= SERIAL_XMIT_SIZE - 1;
2840 info->xmit_cnt++; 2840 info->xmit_cnt++;
2841 info->idle_stats.xmit_bytes++; 2841 info->idle_stats.xmit_bytes++;
@@ -2860,7 +2860,7 @@ static void cy_flush_chars(struct tty_struct *tty)
2860 return; 2860 return;
2861 2861
2862 if (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || 2862 if (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
2863 !info->xmit_buf) 2863 !info->port.xmit_buf)
2864 return; 2864 return;
2865 2865
2866 start_xmit(info); 2866 start_xmit(info);
@@ -2988,27 +2988,27 @@ static void set_line_char(struct cyclades_port *info)
2988 int baud, baud_rate = 0; 2988 int baud, baud_rate = 0;
2989 int i; 2989 int i;
2990 2990
2991 if (!info->tty || !info->tty->termios) 2991 if (!info->port.tty || !info->port.tty->termios)
2992 return; 2992 return;
2993 2993
2994 if (info->line == -1) 2994 if (info->line == -1)
2995 return; 2995 return;
2996 2996
2997 cflag = info->tty->termios->c_cflag; 2997 cflag = info->port.tty->termios->c_cflag;
2998 iflag = info->tty->termios->c_iflag; 2998 iflag = info->port.tty->termios->c_iflag;
2999 2999
3000 /* 3000 /*
3001 * Set up the tty->alt_speed kludge 3001 * Set up the tty->alt_speed kludge
3002 */ 3002 */
3003 if (info->tty) { 3003 if (info->port.tty) {
3004 if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) 3004 if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
3005 info->tty->alt_speed = 57600; 3005 info->port.tty->alt_speed = 57600;
3006 if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) 3006 if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
3007 info->tty->alt_speed = 115200; 3007 info->port.tty->alt_speed = 115200;
3008 if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) 3008 if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
3009 info->tty->alt_speed = 230400; 3009 info->port.tty->alt_speed = 230400;
3010 if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) 3010 if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
3011 info->tty->alt_speed = 460800; 3011 info->port.tty->alt_speed = 460800;
3012 } 3012 }
3013 3013
3014 card = info->card; 3014 card = info->card;
@@ -3020,8 +3020,8 @@ static void set_line_char(struct cyclades_port *info)
3020 index = card->bus_index; 3020 index = card->bus_index;
3021 3021
3022 /* baud rate */ 3022 /* baud rate */
3023 baud = tty_get_baud_rate(info->tty); 3023 baud = tty_get_baud_rate(info->port.tty);
3024 if (baud == 38400 && (info->flags & ASYNC_SPD_MASK) == 3024 if (baud == 38400 && (info->port.flags & ASYNC_SPD_MASK) ==
3025 ASYNC_SPD_CUST) { 3025 ASYNC_SPD_CUST) {
3026 if (info->custom_divisor) 3026 if (info->custom_divisor)
3027 baud_rate = info->baud / info->custom_divisor; 3027 baud_rate = info->baud / info->custom_divisor;
@@ -3038,7 +3038,7 @@ static void set_line_char(struct cyclades_port *info)
3038 if (i == 20) 3038 if (i == 20)
3039 i = 19; /* CD1400_MAX_SPEED */ 3039 i = 19; /* CD1400_MAX_SPEED */
3040 3040
3041 if (baud == 38400 && (info->flags & ASYNC_SPD_MASK) == 3041 if (baud == 38400 && (info->port.flags & ASYNC_SPD_MASK) ==
3042 ASYNC_SPD_CUST) { 3042 ASYNC_SPD_CUST) {
3043 cyy_baud_calc(info, baud_rate); 3043 cyy_baud_calc(info, baud_rate);
3044 } else { 3044 } else {
@@ -3059,7 +3059,7 @@ static void set_line_char(struct cyclades_port *info)
3059 /* get it right for 134.5 baud */ 3059 /* get it right for 134.5 baud */
3060 info->timeout = (info->xmit_fifo_size * HZ * 30 / 269) + 3060 info->timeout = (info->xmit_fifo_size * HZ * 30 / 269) +
3061 2; 3061 2;
3062 } else if (baud == 38400 && (info->flags & ASYNC_SPD_MASK) == 3062 } else if (baud == 38400 && (info->port.flags & ASYNC_SPD_MASK) ==
3063 ASYNC_SPD_CUST) { 3063 ASYNC_SPD_CUST) {
3064 info->timeout = (info->xmit_fifo_size * HZ * 15 / 3064 info->timeout = (info->xmit_fifo_size * HZ * 15 /
3065 baud_rate) + 2; 3065 baud_rate) + 2;
@@ -3108,16 +3108,16 @@ static void set_line_char(struct cyclades_port *info)
3108 3108
3109 /* CTS flow control flag */ 3109 /* CTS flow control flag */
3110 if (cflag & CRTSCTS) { 3110 if (cflag & CRTSCTS) {
3111 info->flags |= ASYNC_CTS_FLOW; 3111 info->port.flags |= ASYNC_CTS_FLOW;
3112 info->cor2 |= CyCtsAE; 3112 info->cor2 |= CyCtsAE;
3113 } else { 3113 } else {
3114 info->flags &= ~ASYNC_CTS_FLOW; 3114 info->port.flags &= ~ASYNC_CTS_FLOW;
3115 info->cor2 &= ~CyCtsAE; 3115 info->cor2 &= ~CyCtsAE;
3116 } 3116 }
3117 if (cflag & CLOCAL) 3117 if (cflag & CLOCAL)
3118 info->flags &= ~ASYNC_CHECK_CD; 3118 info->port.flags &= ~ASYNC_CHECK_CD;
3119 else 3119 else
3120 info->flags |= ASYNC_CHECK_CD; 3120 info->port.flags |= ASYNC_CHECK_CD;
3121 3121
3122 /*********************************************** 3122 /***********************************************
3123 The hardware option, CyRtsAO, presents RTS when 3123 The hardware option, CyRtsAO, presents RTS when
@@ -3146,8 +3146,8 @@ static void set_line_char(struct cyclades_port *info)
3146 /* set line characteristics according configuration */ 3146 /* set line characteristics according configuration */
3147 3147
3148 cy_writeb(base_addr + (CySCHR1 << index), 3148 cy_writeb(base_addr + (CySCHR1 << index),
3149 START_CHAR(info->tty)); 3149 START_CHAR(info->port.tty));
3150 cy_writeb(base_addr + (CySCHR2 << index), STOP_CHAR(info->tty)); 3150 cy_writeb(base_addr + (CySCHR2 << index), STOP_CHAR(info->port.tty));
3151 cy_writeb(base_addr + (CyCOR1 << index), info->cor1); 3151 cy_writeb(base_addr + (CyCOR1 << index), info->cor1);
3152 cy_writeb(base_addr + (CyCOR2 << index), info->cor2); 3152 cy_writeb(base_addr + (CyCOR2 << index), info->cor2);
3153 cy_writeb(base_addr + (CyCOR3 << index), info->cor3); 3153 cy_writeb(base_addr + (CyCOR3 << index), info->cor3);
@@ -3163,7 +3163,7 @@ static void set_line_char(struct cyclades_port *info)
3163 (info->default_timeout ? info->default_timeout : 0x02)); 3163 (info->default_timeout ? info->default_timeout : 0x02));
3164 /* 10ms rx timeout */ 3164 /* 10ms rx timeout */
3165 3165
3166 if (C_CLOCAL(info->tty)) { 3166 if (C_CLOCAL(info->port.tty)) {
3167 /* without modem intr */ 3167 /* without modem intr */
3168 cy_writeb(base_addr + (CySRER << index), 3168 cy_writeb(base_addr + (CySRER << index),
3169 readb(base_addr + (CySRER << index)) | CyMdmCh); 3169 readb(base_addr + (CySRER << index)) | CyMdmCh);
@@ -3226,8 +3226,8 @@ static void set_line_char(struct cyclades_port *info)
3226#endif 3226#endif
3227 } 3227 }
3228 3228
3229 if (info->tty) 3229 if (info->port.tty)
3230 clear_bit(TTY_IO_ERROR, &info->tty->flags); 3230 clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
3231 spin_unlock_irqrestore(&card->card_lock, flags); 3231 spin_unlock_irqrestore(&card->card_lock, flags);
3232 3232
3233 } else { 3233 } else {
@@ -3250,8 +3250,8 @@ static void set_line_char(struct cyclades_port *info)
3250 buf_ctrl = &zfw_ctrl->buf_ctrl[channel]; 3250 buf_ctrl = &zfw_ctrl->buf_ctrl[channel];
3251 3251
3252 /* baud rate */ 3252 /* baud rate */
3253 baud = tty_get_baud_rate(info->tty); 3253 baud = tty_get_baud_rate(info->port.tty);
3254 if (baud == 38400 && (info->flags & ASYNC_SPD_MASK) == 3254 if (baud == 38400 && (info->port.flags & ASYNC_SPD_MASK) ==
3255 ASYNC_SPD_CUST) { 3255 ASYNC_SPD_CUST) {
3256 if (info->custom_divisor) 3256 if (info->custom_divisor)
3257 baud_rate = info->baud / info->custom_divisor; 3257 baud_rate = info->baud / info->custom_divisor;
@@ -3266,7 +3266,7 @@ static void set_line_char(struct cyclades_port *info)
3266 /* get it right for 134.5 baud */ 3266 /* get it right for 134.5 baud */
3267 info->timeout = (info->xmit_fifo_size * HZ * 30 / 269) + 3267 info->timeout = (info->xmit_fifo_size * HZ * 30 / 269) +
3268 2; 3268 2;
3269 } else if (baud == 38400 && (info->flags & ASYNC_SPD_MASK) == 3269 } else if (baud == 38400 && (info->port.flags & ASYNC_SPD_MASK) ==
3270 ASYNC_SPD_CUST) { 3270 ASYNC_SPD_CUST) {
3271 info->timeout = (info->xmit_fifo_size * HZ * 15 / 3271 info->timeout = (info->xmit_fifo_size * HZ * 15 /
3272 baud_rate) + 2; 3272 baud_rate) + 2;
@@ -3318,7 +3318,7 @@ static void set_line_char(struct cyclades_port *info)
3318 } 3318 }
3319 /* As the HW flow control is done in firmware, the driver 3319 /* As the HW flow control is done in firmware, the driver
3320 doesn't need to care about it */ 3320 doesn't need to care about it */
3321 info->flags &= ~ASYNC_CTS_FLOW; 3321 info->port.flags &= ~ASYNC_CTS_FLOW;
3322 3322
3323 /* XON/XOFF/XANY flow control flags */ 3323 /* XON/XOFF/XANY flow control flags */
3324 sw_flow = 0; 3324 sw_flow = 0;
@@ -3337,9 +3337,9 @@ static void set_line_char(struct cyclades_port *info)
3337 3337
3338 /* CD sensitivity */ 3338 /* CD sensitivity */
3339 if (cflag & CLOCAL) 3339 if (cflag & CLOCAL)
3340 info->flags &= ~ASYNC_CHECK_CD; 3340 info->port.flags &= ~ASYNC_CHECK_CD;
3341 else 3341 else
3342 info->flags |= ASYNC_CHECK_CD; 3342 info->port.flags |= ASYNC_CHECK_CD;
3343 3343
3344 if (baud == 0) { /* baud rate is zero, turn off line */ 3344 if (baud == 0) { /* baud rate is zero, turn off line */
3345 cy_writel(&ch_ctrl->rs_control, 3345 cy_writel(&ch_ctrl->rs_control,
@@ -3361,8 +3361,8 @@ static void set_line_char(struct cyclades_port *info)
3361 "was %x\n", info->line, retval); 3361 "was %x\n", info->line, retval);
3362 } 3362 }
3363 3363
3364 if (info->tty) 3364 if (info->port.tty)
3365 clear_bit(TTY_IO_ERROR, &info->tty->flags); 3365 clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
3366 } 3366 }
3367} /* set_line_char */ 3367} /* set_line_char */
3368 3368
@@ -3381,9 +3381,9 @@ get_serial_info(struct cyclades_port *info,
3381 tmp.port = (info->card - cy_card) * 0x100 + info->line - 3381 tmp.port = (info->card - cy_card) * 0x100 + info->line -
3382 cinfo->first_line; 3382 cinfo->first_line;
3383 tmp.irq = cinfo->irq; 3383 tmp.irq = cinfo->irq;
3384 tmp.flags = info->flags; 3384 tmp.flags = info->port.flags;
3385 tmp.close_delay = info->close_delay; 3385 tmp.close_delay = info->port.close_delay;
3386 tmp.closing_wait = info->closing_wait; 3386 tmp.closing_wait = info->port.closing_wait;
3387 tmp.baud_base = info->baud; 3387 tmp.baud_base = info->baud;
3388 tmp.custom_divisor = info->custom_divisor; 3388 tmp.custom_divisor = info->custom_divisor;
3389 tmp.hub6 = 0; /*!!! */ 3389 tmp.hub6 = 0; /*!!! */
@@ -3402,13 +3402,13 @@ set_serial_info(struct cyclades_port *info,
3402 old_info = *info; 3402 old_info = *info;
3403 3403
3404 if (!capable(CAP_SYS_ADMIN)) { 3404 if (!capable(CAP_SYS_ADMIN)) {
3405 if (new_serial.close_delay != info->close_delay || 3405 if (new_serial.close_delay != info->port.close_delay ||
3406 new_serial.baud_base != info->baud || 3406 new_serial.baud_base != info->baud ||
3407 (new_serial.flags & ASYNC_FLAGS & 3407 (new_serial.flags & ASYNC_FLAGS &
3408 ~ASYNC_USR_MASK) != 3408 ~ASYNC_USR_MASK) !=
3409 (info->flags & ASYNC_FLAGS & ~ASYNC_USR_MASK)) 3409 (info->port.flags & ASYNC_FLAGS & ~ASYNC_USR_MASK))
3410 return -EPERM; 3410 return -EPERM;
3411 info->flags = (info->flags & ~ASYNC_USR_MASK) | 3411 info->port.flags = (info->port.flags & ~ASYNC_USR_MASK) |
3412 (new_serial.flags & ASYNC_USR_MASK); 3412 (new_serial.flags & ASYNC_USR_MASK);
3413 info->baud = new_serial.baud_base; 3413 info->baud = new_serial.baud_base;
3414 info->custom_divisor = new_serial.custom_divisor; 3414 info->custom_divisor = new_serial.custom_divisor;
@@ -3422,13 +3422,13 @@ set_serial_info(struct cyclades_port *info,
3422 3422
3423 info->baud = new_serial.baud_base; 3423 info->baud = new_serial.baud_base;
3424 info->custom_divisor = new_serial.custom_divisor; 3424 info->custom_divisor = new_serial.custom_divisor;
3425 info->flags = (info->flags & ~ASYNC_FLAGS) | 3425 info->port.flags = (info->port.flags & ~ASYNC_FLAGS) |
3426 (new_serial.flags & ASYNC_FLAGS); 3426 (new_serial.flags & ASYNC_FLAGS);
3427 info->close_delay = new_serial.close_delay * HZ / 100; 3427 info->port.close_delay = new_serial.close_delay * HZ / 100;
3428 info->closing_wait = new_serial.closing_wait * HZ / 100; 3428 info->port.closing_wait = new_serial.closing_wait * HZ / 100;
3429 3429
3430check_and_exit: 3430check_and_exit:
3431 if (info->flags & ASYNC_INITIALIZED) { 3431 if (info->port.flags & ASYNC_INITIALIZED) {
3432 set_line_char(info); 3432 set_line_char(info);
3433 return 0; 3433 return 0;
3434 } else { 3434 } else {
@@ -3971,11 +3971,11 @@ cy_ioctl(struct tty_struct *tty, struct file *file,
3971 break; 3971 break;
3972#endif /* CONFIG_CYZ_INTR */ 3972#endif /* CONFIG_CYZ_INTR */
3973 case CYSETWAIT: 3973 case CYSETWAIT:
3974 info->closing_wait = (unsigned short)arg * HZ / 100; 3974 info->port.closing_wait = (unsigned short)arg * HZ / 100;
3975 ret_val = 0; 3975 ret_val = 0;
3976 break; 3976 break;
3977 case CYGETWAIT: 3977 case CYGETWAIT:
3978 ret_val = info->closing_wait / (HZ / 100); 3978 ret_val = info->port.closing_wait / (HZ / 100);
3979 break; 3979 break;
3980 case TIOCGSERIAL: 3980 case TIOCGSERIAL:
3981 ret_val = get_serial_info(info, argp); 3981 ret_val = get_serial_info(info, argp);
@@ -4097,7 +4097,7 @@ static void cy_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
4097 */ 4097 */
4098 if (!(old_termios->c_cflag & CLOCAL) && 4098 if (!(old_termios->c_cflag & CLOCAL) &&
4099 (tty->termios->c_cflag & CLOCAL)) 4099 (tty->termios->c_cflag & CLOCAL))
4100 wake_up_interruptible(&info->open_wait); 4100 wake_up_interruptible(&info->port.open_wait);
4101#endif 4101#endif
4102} /* cy_set_termios */ 4102} /* cy_set_termios */
4103 4103
@@ -4326,14 +4326,14 @@ static void cy_hangup(struct tty_struct *tty)
4326 4326
4327 cy_flush_buffer(tty); 4327 cy_flush_buffer(tty);
4328 shutdown(info); 4328 shutdown(info);
4329 info->count = 0; 4329 info->port.count = 0;
4330#ifdef CY_DEBUG_COUNT 4330#ifdef CY_DEBUG_COUNT
4331 printk(KERN_DEBUG "cyc:cy_hangup (%d): setting count to 0\n", 4331 printk(KERN_DEBUG "cyc:cy_hangup (%d): setting count to 0\n",
4332 current->pid); 4332 current->pid);
4333#endif 4333#endif
4334 info->tty = NULL; 4334 info->port.tty = NULL;
4335 info->flags &= ~ASYNC_NORMAL_ACTIVE; 4335 info->port.flags &= ~ASYNC_NORMAL_ACTIVE;
4336 wake_up_interruptible(&info->open_wait); 4336 wake_up_interruptible(&info->port.open_wait);
4337} /* cy_hangup */ 4337} /* cy_hangup */
4338 4338
4339/* 4339/*
@@ -4376,15 +4376,14 @@ static int __devinit cy_init_card(struct cyclades_card *cinfo)
4376 for (port = cinfo->first_line; port < cinfo->first_line + nports; 4376 for (port = cinfo->first_line; port < cinfo->first_line + nports;
4377 port++) { 4377 port++) {
4378 info = &cinfo->ports[port - cinfo->first_line]; 4378 info = &cinfo->ports[port - cinfo->first_line];
4379 tty_port_init(&info->port);
4379 info->magic = CYCLADES_MAGIC; 4380 info->magic = CYCLADES_MAGIC;
4380 info->card = cinfo; 4381 info->card = cinfo;
4381 info->line = port; 4382 info->line = port;
4382 info->flags = STD_COM_FLAGS;
4383 info->closing_wait = CLOSING_WAIT_DELAY;
4384 info->close_delay = 5 * HZ / 10;
4385 4383
4386 init_waitqueue_head(&info->open_wait); 4384 info->port.closing_wait = CLOSING_WAIT_DELAY;
4387 init_waitqueue_head(&info->close_wait); 4385 info->port.close_delay = 5 * HZ / 10;
4386 info->port.flags = STD_COM_FLAGS;
4388 init_completion(&info->shutdown_wait); 4387 init_completion(&info->shutdown_wait);
4389 init_waitqueue_head(&info->delta_msr_wait); 4388 init_waitqueue_head(&info->delta_msr_wait);
4390 4389
@@ -4668,7 +4667,7 @@ static inline int __devinit cyc_isfwstr(const char *str, unsigned int size)
4668 return 0; 4667 return 0;
4669} 4668}
4670 4669
4671static inline void __devinit cyz_fpga_copy(void __iomem *fpga, u8 *data, 4670static inline void __devinit cyz_fpga_copy(void __iomem *fpga, const u8 *data,
4672 unsigned int size) 4671 unsigned int size)
4673{ 4672{
4674 for (; size > 0; size--) { 4673 for (; size > 0; size--) {
@@ -4701,10 +4700,10 @@ static int __devinit __cyz_load_fw(const struct firmware *fw,
4701 const char *name, const u32 mailbox, void __iomem *base, 4700 const char *name, const u32 mailbox, void __iomem *base,
4702 void __iomem *fpga) 4701 void __iomem *fpga)
4703{ 4702{
4704 void *ptr = fw->data; 4703 const void *ptr = fw->data;
4705 struct zfile_header *h = ptr; 4704 const struct zfile_header *h = ptr;
4706 struct zfile_config *c, *cs; 4705 const struct zfile_config *c, *cs;
4707 struct zfile_block *b, *bs; 4706 const struct zfile_block *b, *bs;
4708 unsigned int a, tmp, len = fw->size; 4707 unsigned int a, tmp, len = fw->size;
4709#define BAD_FW KERN_ERR "Bad firmware: " 4708#define BAD_FW KERN_ERR "Bad firmware: "
4710 if (len < sizeof(*h)) { 4709 if (len < sizeof(*h)) {
@@ -5237,7 +5236,7 @@ cyclades_get_proc_info(char *buf, char **start, off_t offset, int length,
5237 for (j = 0; j < cy_card[i].nports; j++) { 5236 for (j = 0; j < cy_card[i].nports; j++) {
5238 info = &cy_card[i].ports[j]; 5237 info = &cy_card[i].ports[j];
5239 5238
5240 if (info->count) 5239 if (info->port.count)
5241 size = sprintf(buf + len, "%3d %8lu %10lu %8lu " 5240 size = sprintf(buf + len, "%3d %8lu %10lu %8lu "
5242 "%10lu %8lu %9lu %6ld\n", info->line, 5241 "%10lu %8lu %9lu %6ld\n", info->line,
5243 (cur_jifs - info->idle_stats.in_use) / 5242 (cur_jifs - info->idle_stats.in_use) /
@@ -5246,7 +5245,8 @@ cyclades_get_proc_info(char *buf, char **start, off_t offset, int length,
5246 HZ, info->idle_stats.recv_bytes, 5245 HZ, info->idle_stats.recv_bytes,
5247 (cur_jifs - info->idle_stats.recv_idle)/ 5246 (cur_jifs - info->idle_stats.recv_idle)/
5248 HZ, info->idle_stats.overruns, 5247 HZ, info->idle_stats.overruns,
5249 (long)info->tty->ldisc.num); 5248 /* FIXME: double check locking */
5249 (long)info->port.tty->ldisc.ops->num);
5250 else 5250 else
5251 size = sprintf(buf + len, "%3d %8lu %10lu %8lu " 5251 size = sprintf(buf + len, "%3d %8lu %10lu %8lu "
5252 "%10lu %8lu %9lu %6ld\n", 5252 "%10lu %8lu %9lu %6ld\n",
diff --git a/drivers/char/drm/Kconfig b/drivers/char/drm/Kconfig
deleted file mode 100644
index 610d6fd5bb50..000000000000
--- a/drivers/char/drm/Kconfig
+++ /dev/null
@@ -1,107 +0,0 @@
1#
2# Drm device configuration
3#
4# This driver provides support for the
5# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
6#
7menuconfig DRM
8 tristate "Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)"
9 depends on (AGP || AGP=n) && PCI && !EMULATED_CMPXCHG
10 help
11 Kernel-level support for the Direct Rendering Infrastructure (DRI)
12 introduced in XFree86 4.0. If you say Y here, you need to select
13 the module that's right for your graphics card from the list below.
14 These modules provide support for synchronization, security, and
15 DMA transfers. Please see <http://dri.sourceforge.net/> for more
16 details. You should also select and configure AGP
17 (/dev/agpgart) support.
18
19config DRM_TDFX
20 tristate "3dfx Banshee/Voodoo3+"
21 depends on DRM && PCI
22 help
23 Choose this option if you have a 3dfx Banshee or Voodoo3 (or later),
24 graphics card. If M is selected, the module will be called tdfx.
25
26config DRM_R128
27 tristate "ATI Rage 128"
28 depends on DRM && PCI
29 help
30 Choose this option if you have an ATI Rage 128 graphics card. If M
31 is selected, the module will be called r128. AGP support for
32 this card is strongly suggested (unless you have a PCI version).
33
34config DRM_RADEON
35 tristate "ATI Radeon"
36 depends on DRM && PCI
37 help
38 Choose this option if you have an ATI Radeon graphics card. There
39 are both PCI and AGP versions. You don't need to choose this to
40 run the Radeon in plain VGA mode.
41
42 If M is selected, the module will be called radeon.
43
44config DRM_I810
45 tristate "Intel I810"
46 depends on DRM && AGP && AGP_INTEL
47 help
48 Choose this option if you have an Intel I810 graphics card. If M is
49 selected, the module will be called i810. AGP support is required
50 for this driver to work.
51
52choice
53 prompt "Intel 830M, 845G, 852GM, 855GM, 865G"
54 depends on DRM && AGP && AGP_INTEL
55 optional
56
57config DRM_I830
58 tristate "i830 driver"
59 help
60 Choose this option if you have a system that has Intel 830M, 845G,
61 852GM, 855GM or 865G integrated graphics. If M is selected, the
62 module will be called i830. AGP support is required for this driver
63 to work. This driver is used by the older X releases X.org 6.7 and
64 XFree86 4.3. If unsure, build this and i915 as modules and the X server
65 will load the correct one.
66
67config DRM_I915
68 tristate "i915 driver"
69 help
70 Choose this option if you have a system that has Intel 830M, 845G,
71 852GM, 855GM 865G or 915G integrated graphics. If M is selected, the
72 module will be called i915. AGP support is required for this driver
73 to work. This driver is used by the Intel driver in X.org 6.8 and
74 XFree86 4.4 and above. If unsure, build this and i830 as modules and
75 the X server will load the correct one.
76
77endchoice
78
79config DRM_MGA
80 tristate "Matrox g200/g400"
81 depends on DRM
82 help
83 Choose this option if you have a Matrox G200, G400 or G450 graphics
84 card. If M is selected, the module will be called mga. AGP
85 support is required for this driver to work.
86
87config DRM_SIS
88 tristate "SiS video cards"
89 depends on DRM && AGP
90 help
91 Choose this option if you have a SiS 630 or compatible video
92 chipset. If M is selected the module will be called sis. AGP
93 support is required for this driver to work.
94
95config DRM_VIA
96 tristate "Via unichrome video cards"
97 depends on DRM
98 help
99 Choose this option if you have a Via unichrome or compatible video
100 chipset. If M is selected the module will be called via.
101
102config DRM_SAVAGE
103 tristate "Savage video cards"
104 depends on DRM
105 help
106 Choose this option if you have a Savage3D/4/SuperSavage/Pro/Twister
107 chipset. If M is selected the module will be called savage.
diff --git a/drivers/char/drm/Makefile b/drivers/char/drm/Makefile
deleted file mode 100644
index 1283ded88ead..000000000000
--- a/drivers/char/drm/Makefile
+++ /dev/null
@@ -1,40 +0,0 @@
1#
2# Makefile for the drm device driver. This driver provides support for the
3# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
4
5drm-objs := drm_auth.o drm_bufs.o drm_context.o drm_dma.o drm_drawable.o \
6 drm_drv.o drm_fops.o drm_ioctl.o drm_irq.o \
7 drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \
8 drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \
9 drm_sysfs.o drm_hashtab.o drm_sman.o drm_mm.o
10
11tdfx-objs := tdfx_drv.o
12r128-objs := r128_drv.o r128_cce.o r128_state.o r128_irq.o
13mga-objs := mga_drv.o mga_dma.o mga_state.o mga_warp.o mga_irq.o
14i810-objs := i810_drv.o i810_dma.o
15i830-objs := i830_drv.o i830_dma.o i830_irq.o
16i915-objs := i915_drv.o i915_dma.o i915_irq.o i915_mem.o
17radeon-objs := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o r300_cmdbuf.o
18sis-objs := sis_drv.o sis_mm.o
19savage-objs := savage_drv.o savage_bci.o savage_state.o
20via-objs := via_irq.o via_drv.o via_map.o via_mm.o via_dma.o via_verifier.o via_video.o via_dmablit.o
21
22ifeq ($(CONFIG_COMPAT),y)
23drm-objs += drm_ioc32.o
24radeon-objs += radeon_ioc32.o
25mga-objs += mga_ioc32.o
26r128-objs += r128_ioc32.o
27i915-objs += i915_ioc32.o
28endif
29
30obj-$(CONFIG_DRM) += drm.o
31obj-$(CONFIG_DRM_TDFX) += tdfx.o
32obj-$(CONFIG_DRM_R128) += r128.o
33obj-$(CONFIG_DRM_RADEON)+= radeon.o
34obj-$(CONFIG_DRM_MGA) += mga.o
35obj-$(CONFIG_DRM_I810) += i810.o
36obj-$(CONFIG_DRM_I830) += i830.o
37obj-$(CONFIG_DRM_I915) += i915.o
38obj-$(CONFIG_DRM_SIS) += sis.o
39obj-$(CONFIG_DRM_SAVAGE)+= savage.o
40obj-$(CONFIG_DRM_VIA) +=via.o
diff --git a/drivers/char/drm/README.drm b/drivers/char/drm/README.drm
deleted file mode 100644
index b5b332722581..000000000000
--- a/drivers/char/drm/README.drm
+++ /dev/null
@@ -1,43 +0,0 @@
1************************************************************
2* For the very latest on DRI development, please see: *
3* http://dri.freedesktop.org/ *
4************************************************************
5
6The Direct Rendering Manager (drm) is a device-independent kernel-level
7device driver that provides support for the XFree86 Direct Rendering
8Infrastructure (DRI).
9
10The DRM supports the Direct Rendering Infrastructure (DRI) in four major
11ways:
12
13 1. The DRM provides synchronized access to the graphics hardware via
14 the use of an optimized two-tiered lock.
15
16 2. The DRM enforces the DRI security policy for access to the graphics
17 hardware by only allowing authenticated X11 clients access to
18 restricted regions of memory.
19
20 3. The DRM provides a generic DMA engine, complete with multiple
21 queues and the ability to detect the need for an OpenGL context
22 switch.
23
24 4. The DRM is extensible via the use of small device-specific modules
25 that rely extensively on the API exported by the DRM module.
26
27
28Documentation on the DRI is available from:
29 http://dri.freedesktop.org/wiki/Documentation
30 http://sourceforge.net/project/showfiles.php?group_id=387
31 http://dri.sourceforge.net/doc/
32
33For specific information about kernel-level support, see:
34
35 The Direct Rendering Manager, Kernel Support for the Direct Rendering
36 Infrastructure
37 http://dri.sourceforge.net/doc/drm_low_level.html
38
39 Hardware Locking for the Direct Rendering Infrastructure
40 http://dri.sourceforge.net/doc/hardware_locking_low_level.html
41
42 A Security Analysis of the Direct Rendering Infrastructure
43 http://dri.sourceforge.net/doc/security_low_level.html
diff --git a/drivers/char/drm/ati_pcigart.c b/drivers/char/drm/ati_pcigart.c
deleted file mode 100644
index b710426bab3e..000000000000
--- a/drivers/char/drm/ati_pcigart.c
+++ /dev/null
@@ -1,183 +0,0 @@
1/**
2 * \file ati_pcigart.c
3 * ATI PCI GART support
4 *
5 * \author Gareth Hughes <gareth@valinux.com>
6 */
7
8/*
9 * Created: Wed Dec 13 21:52:19 2000 by gareth@valinux.com
10 *
11 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
12 * All Rights Reserved.
13 *
14 * Permission is hereby granted, free of charge, to any person obtaining a
15 * copy of this software and associated documentation files (the "Software"),
16 * to deal in the Software without restriction, including without limitation
17 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
18 * and/or sell copies of the Software, and to permit persons to whom the
19 * Software is furnished to do so, subject to the following conditions:
20 *
21 * The above copyright notice and this permission notice (including the next
22 * paragraph) shall be included in all copies or substantial portions of the
23 * Software.
24 *
25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
28 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
29 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
30 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
31 * DEALINGS IN THE SOFTWARE.
32 */
33
34#include "drmP.h"
35
36# define ATI_PCIGART_PAGE_SIZE 4096 /**< PCI GART page size */
37
38static int drm_ati_alloc_pcigart_table(struct drm_device *dev,
39 struct drm_ati_pcigart_info *gart_info)
40{
41 gart_info->table_handle = drm_pci_alloc(dev, gart_info->table_size,
42 PAGE_SIZE,
43 gart_info->table_mask);
44 if (gart_info->table_handle == NULL)
45 return -ENOMEM;
46
47 return 0;
48}
49
50static void drm_ati_free_pcigart_table(struct drm_device *dev,
51 struct drm_ati_pcigart_info *gart_info)
52{
53 drm_pci_free(dev, gart_info->table_handle);
54 gart_info->table_handle = NULL;
55}
56
57int drm_ati_pcigart_cleanup(struct drm_device *dev, struct drm_ati_pcigart_info *gart_info)
58{
59 struct drm_sg_mem *entry = dev->sg;
60 unsigned long pages;
61 int i;
62 int max_pages;
63
64 /* we need to support large memory configurations */
65 if (!entry) {
66 DRM_ERROR("no scatter/gather memory!\n");
67 return 0;
68 }
69
70 if (gart_info->bus_addr) {
71
72 max_pages = (gart_info->table_size / sizeof(u32));
73 pages = (entry->pages <= max_pages)
74 ? entry->pages : max_pages;
75
76 for (i = 0; i < pages; i++) {
77 if (!entry->busaddr[i])
78 break;
79 pci_unmap_single(dev->pdev, entry->busaddr[i],
80 PAGE_SIZE, PCI_DMA_TODEVICE);
81 }
82
83 if (gart_info->gart_table_location == DRM_ATI_GART_MAIN)
84 gart_info->bus_addr = 0;
85 }
86
87 if (gart_info->gart_table_location == DRM_ATI_GART_MAIN &&
88 gart_info->table_handle) {
89 drm_ati_free_pcigart_table(dev, gart_info);
90 }
91
92 return 1;
93}
94EXPORT_SYMBOL(drm_ati_pcigart_cleanup);
95
96int drm_ati_pcigart_init(struct drm_device *dev, struct drm_ati_pcigart_info *gart_info)
97{
98 struct drm_sg_mem *entry = dev->sg;
99 void *address = NULL;
100 unsigned long pages;
101 u32 *pci_gart, page_base;
102 dma_addr_t bus_address = 0;
103 int i, j, ret = 0;
104 int max_pages;
105
106 if (!entry) {
107 DRM_ERROR("no scatter/gather memory!\n");
108 goto done;
109 }
110
111 if (gart_info->gart_table_location == DRM_ATI_GART_MAIN) {
112 DRM_DEBUG("PCI: no table in VRAM: using normal RAM\n");
113
114 ret = drm_ati_alloc_pcigart_table(dev, gart_info);
115 if (ret) {
116 DRM_ERROR("cannot allocate PCI GART page!\n");
117 goto done;
118 }
119
120 address = gart_info->table_handle->vaddr;
121 bus_address = gart_info->table_handle->busaddr;
122 } else {
123 address = gart_info->addr;
124 bus_address = gart_info->bus_addr;
125 DRM_DEBUG("PCI: Gart Table: VRAM %08LX mapped at %08lX\n",
126 (unsigned long long)bus_address,
127 (unsigned long)address);
128 }
129
130 pci_gart = (u32 *) address;
131
132 max_pages = (gart_info->table_size / sizeof(u32));
133 pages = (entry->pages <= max_pages)
134 ? entry->pages : max_pages;
135
136 memset(pci_gart, 0, max_pages * sizeof(u32));
137
138 for (i = 0; i < pages; i++) {
139 /* we need to support large memory configurations */
140 entry->busaddr[i] = pci_map_single(dev->pdev,
141 page_address(entry->
142 pagelist[i]),
143 PAGE_SIZE, PCI_DMA_TODEVICE);
144 if (entry->busaddr[i] == 0) {
145 DRM_ERROR("unable to map PCIGART pages!\n");
146 drm_ati_pcigart_cleanup(dev, gart_info);
147 address = NULL;
148 bus_address = 0;
149 goto done;
150 }
151 page_base = (u32) entry->busaddr[i];
152
153 for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) {
154 switch(gart_info->gart_reg_if) {
155 case DRM_ATI_GART_IGP:
156 *pci_gart = cpu_to_le32((page_base) | 0xc);
157 break;
158 case DRM_ATI_GART_PCIE:
159 *pci_gart = cpu_to_le32((page_base >> 8) | 0xc);
160 break;
161 default:
162 case DRM_ATI_GART_PCI:
163 *pci_gart = cpu_to_le32(page_base);
164 break;
165 }
166 pci_gart++;
167 page_base += ATI_PCIGART_PAGE_SIZE;
168 }
169 }
170 ret = 1;
171
172#if defined(__i386__) || defined(__x86_64__)
173 wbinvd();
174#else
175 mb();
176#endif
177
178 done:
179 gart_info->addr = address;
180 gart_info->bus_addr = bus_address;
181 return ret;
182}
183EXPORT_SYMBOL(drm_ati_pcigart_init);
diff --git a/drivers/char/drm/drm.h b/drivers/char/drm/drm.h
deleted file mode 100644
index 6874f31ca8ca..000000000000
--- a/drivers/char/drm/drm.h
+++ /dev/null
@@ -1,711 +0,0 @@
1/**
2 * \file drm.h
3 * Header for the Direct Rendering Manager
4 *
5 * \author Rickard E. (Rik) Faith <faith@valinux.com>
6 *
7 * \par Acknowledgments:
8 * Dec 1999, Richard Henderson <rth@twiddle.net>, move to generic \c cmpxchg.
9 */
10
11/*
12 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
13 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
14 * All rights reserved.
15 *
16 * Permission is hereby granted, free of charge, to any person obtaining a
17 * copy of this software and associated documentation files (the "Software"),
18 * to deal in the Software without restriction, including without limitation
19 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
20 * and/or sell copies of the Software, and to permit persons to whom the
21 * Software is furnished to do so, subject to the following conditions:
22 *
23 * The above copyright notice and this permission notice (including the next
24 * paragraph) shall be included in all copies or substantial portions of the
25 * Software.
26 *
27 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
30 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
31 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
32 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
33 * OTHER DEALINGS IN THE SOFTWARE.
34 */
35
36#ifndef _DRM_H_
37#define _DRM_H_
38
39#if defined(__linux__)
40#if defined(__KERNEL__)
41#endif
42#include <asm/ioctl.h> /* For _IO* macros */
43#define DRM_IOCTL_NR(n) _IOC_NR(n)
44#define DRM_IOC_VOID _IOC_NONE
45#define DRM_IOC_READ _IOC_READ
46#define DRM_IOC_WRITE _IOC_WRITE
47#define DRM_IOC_READWRITE _IOC_READ|_IOC_WRITE
48#define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size)
49#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
50#if defined(__FreeBSD__) && defined(IN_MODULE)
51/* Prevent name collision when including sys/ioccom.h */
52#undef ioctl
53#include <sys/ioccom.h>
54#define ioctl(a,b,c) xf86ioctl(a,b,c)
55#else
56#include <sys/ioccom.h>
57#endif /* __FreeBSD__ && xf86ioctl */
58#define DRM_IOCTL_NR(n) ((n) & 0xff)
59#define DRM_IOC_VOID IOC_VOID
60#define DRM_IOC_READ IOC_OUT
61#define DRM_IOC_WRITE IOC_IN
62#define DRM_IOC_READWRITE IOC_INOUT
63#define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size)
64#endif
65
66#define DRM_MAJOR 226
67#define DRM_MAX_MINOR 15
68
69#define DRM_NAME "drm" /**< Name in kernel, /dev, and /proc */
70#define DRM_MIN_ORDER 5 /**< At least 2^5 bytes = 32 bytes */
71#define DRM_MAX_ORDER 22 /**< Up to 2^22 bytes = 4MB */
72#define DRM_RAM_PERCENT 10 /**< How much system ram can we lock? */
73
74#define _DRM_LOCK_HELD 0x80000000U /**< Hardware lock is held */
75#define _DRM_LOCK_CONT 0x40000000U /**< Hardware lock is contended */
76#define _DRM_LOCK_IS_HELD(lock) ((lock) & _DRM_LOCK_HELD)
77#define _DRM_LOCK_IS_CONT(lock) ((lock) & _DRM_LOCK_CONT)
78#define _DRM_LOCKING_CONTEXT(lock) ((lock) & ~(_DRM_LOCK_HELD|_DRM_LOCK_CONT))
79
80typedef unsigned int drm_handle_t;
81typedef unsigned int drm_context_t;
82typedef unsigned int drm_drawable_t;
83typedef unsigned int drm_magic_t;
84
85/**
86 * Cliprect.
87 *
88 * \warning: If you change this structure, make sure you change
89 * XF86DRIClipRectRec in the server as well
90 *
91 * \note KW: Actually it's illegal to change either for
92 * backwards-compatibility reasons.
93 */
94struct drm_clip_rect {
95 unsigned short x1;
96 unsigned short y1;
97 unsigned short x2;
98 unsigned short y2;
99};
100
101/**
102 * Drawable information.
103 */
104struct drm_drawable_info {
105 unsigned int num_rects;
106 struct drm_clip_rect *rects;
107};
108
109/**
110 * Texture region,
111 */
112struct drm_tex_region {
113 unsigned char next;
114 unsigned char prev;
115 unsigned char in_use;
116 unsigned char padding;
117 unsigned int age;
118};
119
120/**
121 * Hardware lock.
122 *
123 * The lock structure is a simple cache-line aligned integer. To avoid
124 * processor bus contention on a multiprocessor system, there should not be any
125 * other data stored in the same cache line.
126 */
127struct drm_hw_lock {
128 __volatile__ unsigned int lock; /**< lock variable */
129 char padding[60]; /**< Pad to cache line */
130};
131
132/**
133 * DRM_IOCTL_VERSION ioctl argument type.
134 *
135 * \sa drmGetVersion().
136 */
137struct drm_version {
138 int version_major; /**< Major version */
139 int version_minor; /**< Minor version */
140 int version_patchlevel; /**< Patch level */
141 size_t name_len; /**< Length of name buffer */
142 char __user *name; /**< Name of driver */
143 size_t date_len; /**< Length of date buffer */
144 char __user *date; /**< User-space buffer to hold date */
145 size_t desc_len; /**< Length of desc buffer */
146 char __user *desc; /**< User-space buffer to hold desc */
147};
148
149/**
150 * DRM_IOCTL_GET_UNIQUE ioctl argument type.
151 *
152 * \sa drmGetBusid() and drmSetBusId().
153 */
154struct drm_unique {
155 size_t unique_len; /**< Length of unique */
156 char __user *unique; /**< Unique name for driver instantiation */
157};
158
159struct drm_list {
160 int count; /**< Length of user-space structures */
161 struct drm_version __user *version;
162};
163
164struct drm_block {
165 int unused;
166};
167
168/**
169 * DRM_IOCTL_CONTROL ioctl argument type.
170 *
171 * \sa drmCtlInstHandler() and drmCtlUninstHandler().
172 */
173struct drm_control {
174 enum {
175 DRM_ADD_COMMAND,
176 DRM_RM_COMMAND,
177 DRM_INST_HANDLER,
178 DRM_UNINST_HANDLER
179 } func;
180 int irq;
181};
182
183/**
184 * Type of memory to map.
185 */
186enum drm_map_type {
187 _DRM_FRAME_BUFFER = 0, /**< WC (no caching), no core dump */
188 _DRM_REGISTERS = 1, /**< no caching, no core dump */
189 _DRM_SHM = 2, /**< shared, cached */
190 _DRM_AGP = 3, /**< AGP/GART */
191 _DRM_SCATTER_GATHER = 4, /**< Scatter/gather memory for PCI DMA */
192 _DRM_CONSISTENT = 5, /**< Consistent memory for PCI DMA */
193};
194
195/**
196 * Memory mapping flags.
197 */
198enum drm_map_flags {
199 _DRM_RESTRICTED = 0x01, /**< Cannot be mapped to user-virtual */
200 _DRM_READ_ONLY = 0x02,
201 _DRM_LOCKED = 0x04, /**< shared, cached, locked */
202 _DRM_KERNEL = 0x08, /**< kernel requires access */
203 _DRM_WRITE_COMBINING = 0x10, /**< use write-combining if available */
204 _DRM_CONTAINS_LOCK = 0x20, /**< SHM page that contains lock */
205 _DRM_REMOVABLE = 0x40, /**< Removable mapping */
206 _DRM_DRIVER = 0x80 /**< Managed by driver */
207};
208
209struct drm_ctx_priv_map {
210 unsigned int ctx_id; /**< Context requesting private mapping */
211 void *handle; /**< Handle of map */
212};
213
214/**
215 * DRM_IOCTL_GET_MAP, DRM_IOCTL_ADD_MAP and DRM_IOCTL_RM_MAP ioctls
216 * argument type.
217 *
218 * \sa drmAddMap().
219 */
220struct drm_map {
221 unsigned long offset; /**< Requested physical address (0 for SAREA)*/
222 unsigned long size; /**< Requested physical size (bytes) */
223 enum drm_map_type type; /**< Type of memory to map */
224 enum drm_map_flags flags; /**< Flags */
225 void *handle; /**< User-space: "Handle" to pass to mmap() */
226 /**< Kernel-space: kernel-virtual address */
227 int mtrr; /**< MTRR slot used */
228 /* Private data */
229};
230
231/**
232 * DRM_IOCTL_GET_CLIENT ioctl argument type.
233 */
234struct drm_client {
235 int idx; /**< Which client desired? */
236 int auth; /**< Is client authenticated? */
237 unsigned long pid; /**< Process ID */
238 unsigned long uid; /**< User ID */
239 unsigned long magic; /**< Magic */
240 unsigned long iocs; /**< Ioctl count */
241};
242
243enum drm_stat_type {
244 _DRM_STAT_LOCK,
245 _DRM_STAT_OPENS,
246 _DRM_STAT_CLOSES,
247 _DRM_STAT_IOCTLS,
248 _DRM_STAT_LOCKS,
249 _DRM_STAT_UNLOCKS,
250 _DRM_STAT_VALUE, /**< Generic value */
251 _DRM_STAT_BYTE, /**< Generic byte counter (1024bytes/K) */
252 _DRM_STAT_COUNT, /**< Generic non-byte counter (1000/k) */
253
254 _DRM_STAT_IRQ, /**< IRQ */
255 _DRM_STAT_PRIMARY, /**< Primary DMA bytes */
256 _DRM_STAT_SECONDARY, /**< Secondary DMA bytes */
257 _DRM_STAT_DMA, /**< DMA */
258 _DRM_STAT_SPECIAL, /**< Special DMA (e.g., priority or polled) */
259 _DRM_STAT_MISSED /**< Missed DMA opportunity */
260 /* Add to the *END* of the list */
261};
262
263/**
264 * DRM_IOCTL_GET_STATS ioctl argument type.
265 */
266struct drm_stats {
267 unsigned long count;
268 struct {
269 unsigned long value;
270 enum drm_stat_type type;
271 } data[15];
272};
273
274/**
275 * Hardware locking flags.
276 */
277enum drm_lock_flags {
278 _DRM_LOCK_READY = 0x01, /**< Wait until hardware is ready for DMA */
279 _DRM_LOCK_QUIESCENT = 0x02, /**< Wait until hardware quiescent */
280 _DRM_LOCK_FLUSH = 0x04, /**< Flush this context's DMA queue first */
281 _DRM_LOCK_FLUSH_ALL = 0x08, /**< Flush all DMA queues first */
282 /* These *HALT* flags aren't supported yet
283 -- they will be used to support the
284 full-screen DGA-like mode. */
285 _DRM_HALT_ALL_QUEUES = 0x10, /**< Halt all current and future queues */
286 _DRM_HALT_CUR_QUEUES = 0x20 /**< Halt all current queues */
287};
288
289/**
290 * DRM_IOCTL_LOCK, DRM_IOCTL_UNLOCK and DRM_IOCTL_FINISH ioctl argument type.
291 *
292 * \sa drmGetLock() and drmUnlock().
293 */
294struct drm_lock {
295 int context;
296 enum drm_lock_flags flags;
297};
298
299/**
300 * DMA flags
301 *
302 * \warning
303 * These values \e must match xf86drm.h.
304 *
305 * \sa drm_dma.
306 */
307enum drm_dma_flags {
308 /* Flags for DMA buffer dispatch */
309 _DRM_DMA_BLOCK = 0x01, /**<
310 * Block until buffer dispatched.
311 *
312 * \note The buffer may not yet have
313 * been processed by the hardware --
314 * getting a hardware lock with the
315 * hardware quiescent will ensure
316 * that the buffer has been
317 * processed.
318 */
319 _DRM_DMA_WHILE_LOCKED = 0x02, /**< Dispatch while lock held */
320 _DRM_DMA_PRIORITY = 0x04, /**< High priority dispatch */
321
322 /* Flags for DMA buffer request */
323 _DRM_DMA_WAIT = 0x10, /**< Wait for free buffers */
324 _DRM_DMA_SMALLER_OK = 0x20, /**< Smaller-than-requested buffers OK */
325 _DRM_DMA_LARGER_OK = 0x40 /**< Larger-than-requested buffers OK */
326};
327
328/**
329 * DRM_IOCTL_ADD_BUFS and DRM_IOCTL_MARK_BUFS ioctl argument type.
330 *
331 * \sa drmAddBufs().
332 */
333struct drm_buf_desc {
334 int count; /**< Number of buffers of this size */
335 int size; /**< Size in bytes */
336 int low_mark; /**< Low water mark */
337 int high_mark; /**< High water mark */
338 enum {
339 _DRM_PAGE_ALIGN = 0x01, /**< Align on page boundaries for DMA */
340 _DRM_AGP_BUFFER = 0x02, /**< Buffer is in AGP space */
341 _DRM_SG_BUFFER = 0x04, /**< Scatter/gather memory buffer */
342 _DRM_FB_BUFFER = 0x08, /**< Buffer is in frame buffer */
343 _DRM_PCI_BUFFER_RO = 0x10 /**< Map PCI DMA buffer read-only */
344 } flags;
345 unsigned long agp_start; /**<
346 * Start address of where the AGP buffers are
347 * in the AGP aperture
348 */
349};
350
351/**
352 * DRM_IOCTL_INFO_BUFS ioctl argument type.
353 */
354struct drm_buf_info {
355 int count; /**< Entries in list */
356 struct drm_buf_desc __user *list;
357};
358
359/**
360 * DRM_IOCTL_FREE_BUFS ioctl argument type.
361 */
362struct drm_buf_free {
363 int count;
364 int __user *list;
365};
366
367/**
368 * Buffer information
369 *
370 * \sa drm_buf_map.
371 */
372struct drm_buf_pub {
373 int idx; /**< Index into the master buffer list */
374 int total; /**< Buffer size */
375 int used; /**< Amount of buffer in use (for DMA) */
376 void __user *address; /**< Address of buffer */
377};
378
379/**
380 * DRM_IOCTL_MAP_BUFS ioctl argument type.
381 */
382struct drm_buf_map {
383 int count; /**< Length of the buffer list */
384 void __user *virtual; /**< Mmap'd area in user-virtual */
385 struct drm_buf_pub __user *list; /**< Buffer information */
386};
387
388/**
389 * DRM_IOCTL_DMA ioctl argument type.
390 *
391 * Indices here refer to the offset into the buffer list in drm_buf_get.
392 *
393 * \sa drmDMA().
394 */
395struct drm_dma {
396 int context; /**< Context handle */
397 int send_count; /**< Number of buffers to send */
398 int __user *send_indices; /**< List of handles to buffers */
399 int __user *send_sizes; /**< Lengths of data to send */
400 enum drm_dma_flags flags; /**< Flags */
401 int request_count; /**< Number of buffers requested */
402 int request_size; /**< Desired size for buffers */
403 int __user *request_indices; /**< Buffer information */
404 int __user *request_sizes;
405 int granted_count; /**< Number of buffers granted */
406};
407
408enum drm_ctx_flags {
409 _DRM_CONTEXT_PRESERVED = 0x01,
410 _DRM_CONTEXT_2DONLY = 0x02
411};
412
413/**
414 * DRM_IOCTL_ADD_CTX ioctl argument type.
415 *
416 * \sa drmCreateContext() and drmDestroyContext().
417 */
418struct drm_ctx {
419 drm_context_t handle;
420 enum drm_ctx_flags flags;
421};
422
423/**
424 * DRM_IOCTL_RES_CTX ioctl argument type.
425 */
426struct drm_ctx_res {
427 int count;
428 struct drm_ctx __user *contexts;
429};
430
431/**
432 * DRM_IOCTL_ADD_DRAW and DRM_IOCTL_RM_DRAW ioctl argument type.
433 */
434struct drm_draw {
435 drm_drawable_t handle;
436};
437
438/**
439 * DRM_IOCTL_UPDATE_DRAW ioctl argument type.
440 */
441typedef enum {
442 DRM_DRAWABLE_CLIPRECTS,
443} drm_drawable_info_type_t;
444
445struct drm_update_draw {
446 drm_drawable_t handle;
447 unsigned int type;
448 unsigned int num;
449 unsigned long long data;
450};
451
452/**
453 * DRM_IOCTL_GET_MAGIC and DRM_IOCTL_AUTH_MAGIC ioctl argument type.
454 */
455struct drm_auth {
456 drm_magic_t magic;
457};
458
459/**
460 * DRM_IOCTL_IRQ_BUSID ioctl argument type.
461 *
462 * \sa drmGetInterruptFromBusID().
463 */
464struct drm_irq_busid {
465 int irq; /**< IRQ number */
466 int busnum; /**< bus number */
467 int devnum; /**< device number */
468 int funcnum; /**< function number */
469};
470
471enum drm_vblank_seq_type {
472 _DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence number */
473 _DRM_VBLANK_RELATIVE = 0x1, /**< Wait for given number of vblanks */
474 _DRM_VBLANK_FLIP = 0x8000000, /**< Scheduled buffer swap should flip */
475 _DRM_VBLANK_NEXTONMISS = 0x10000000, /**< If missed, wait for next vblank */
476 _DRM_VBLANK_SECONDARY = 0x20000000, /**< Secondary display controller */
477 _DRM_VBLANK_SIGNAL = 0x40000000 /**< Send signal instead of blocking */
478};
479
480#define _DRM_VBLANK_TYPES_MASK (_DRM_VBLANK_ABSOLUTE | _DRM_VBLANK_RELATIVE)
481#define _DRM_VBLANK_FLAGS_MASK (_DRM_VBLANK_SIGNAL | _DRM_VBLANK_SECONDARY | \
482 _DRM_VBLANK_NEXTONMISS)
483
484struct drm_wait_vblank_request {
485 enum drm_vblank_seq_type type;
486 unsigned int sequence;
487 unsigned long signal;
488};
489
490struct drm_wait_vblank_reply {
491 enum drm_vblank_seq_type type;
492 unsigned int sequence;
493 long tval_sec;
494 long tval_usec;
495};
496
497/**
498 * DRM_IOCTL_WAIT_VBLANK ioctl argument type.
499 *
500 * \sa drmWaitVBlank().
501 */
502union drm_wait_vblank {
503 struct drm_wait_vblank_request request;
504 struct drm_wait_vblank_reply reply;
505};
506
507enum drm_modeset_ctl_cmd {
508 _DRM_PRE_MODESET = 1,
509 _DRM_POST_MODESET = 2,
510};
511
512/**
513 * DRM_IOCTL_MODESET_CTL ioctl argument type
514 *
515 * \sa drmModesetCtl().
516 */
517struct drm_modeset_ctl {
518 unsigned long arg;
519 enum drm_modeset_ctl_cmd cmd;
520};
521
522/**
523 * DRM_IOCTL_AGP_ENABLE ioctl argument type.
524 *
525 * \sa drmAgpEnable().
526 */
527struct drm_agp_mode {
528 unsigned long mode; /**< AGP mode */
529};
530
531/**
532 * DRM_IOCTL_AGP_ALLOC and DRM_IOCTL_AGP_FREE ioctls argument type.
533 *
534 * \sa drmAgpAlloc() and drmAgpFree().
535 */
536struct drm_agp_buffer {
537 unsigned long size; /**< In bytes -- will round to page boundary */
538 unsigned long handle; /**< Used for binding / unbinding */
539 unsigned long type; /**< Type of memory to allocate */
540 unsigned long physical; /**< Physical used by i810 */
541};
542
543/**
544 * DRM_IOCTL_AGP_BIND and DRM_IOCTL_AGP_UNBIND ioctls argument type.
545 *
546 * \sa drmAgpBind() and drmAgpUnbind().
547 */
548struct drm_agp_binding {
549 unsigned long handle; /**< From drm_agp_buffer */
550 unsigned long offset; /**< In bytes -- will round to page boundary */
551};
552
553/**
554 * DRM_IOCTL_AGP_INFO ioctl argument type.
555 *
556 * \sa drmAgpVersionMajor(), drmAgpVersionMinor(), drmAgpGetMode(),
557 * drmAgpBase(), drmAgpSize(), drmAgpMemoryUsed(), drmAgpMemoryAvail(),
558 * drmAgpVendorId() and drmAgpDeviceId().
559 */
560struct drm_agp_info {
561 int agp_version_major;
562 int agp_version_minor;
563 unsigned long mode;
564 unsigned long aperture_base; /* physical address */
565 unsigned long aperture_size; /* bytes */
566 unsigned long memory_allowed; /* bytes */
567 unsigned long memory_used;
568
569 /* PCI information */
570 unsigned short id_vendor;
571 unsigned short id_device;
572};
573
574/**
575 * DRM_IOCTL_SG_ALLOC ioctl argument type.
576 */
577struct drm_scatter_gather {
578 unsigned long size; /**< In bytes -- will round to page boundary */
579 unsigned long handle; /**< Used for mapping / unmapping */
580};
581
582/**
583 * DRM_IOCTL_SET_VERSION ioctl argument type.
584 */
585struct drm_set_version {
586 int drm_di_major;
587 int drm_di_minor;
588 int drm_dd_major;
589 int drm_dd_minor;
590};
591
592#define DRM_IOCTL_BASE 'd'
593#define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr)
594#define DRM_IOR(nr,type) _IOR(DRM_IOCTL_BASE,nr,type)
595#define DRM_IOW(nr,type) _IOW(DRM_IOCTL_BASE,nr,type)
596#define DRM_IOWR(nr,type) _IOWR(DRM_IOCTL_BASE,nr,type)
597
598#define DRM_IOCTL_VERSION DRM_IOWR(0x00, struct drm_version)
599#define DRM_IOCTL_GET_UNIQUE DRM_IOWR(0x01, struct drm_unique)
600#define DRM_IOCTL_GET_MAGIC DRM_IOR( 0x02, struct drm_auth)
601#define DRM_IOCTL_IRQ_BUSID DRM_IOWR(0x03, struct drm_irq_busid)
602#define DRM_IOCTL_GET_MAP DRM_IOWR(0x04, struct drm_map)
603#define DRM_IOCTL_GET_CLIENT DRM_IOWR(0x05, struct drm_client)
604#define DRM_IOCTL_GET_STATS DRM_IOR( 0x06, struct drm_stats)
605#define DRM_IOCTL_SET_VERSION DRM_IOWR(0x07, struct drm_set_version)
606#define DRM_IOCTL_MODESET_CTL DRM_IOW(0x08, struct drm_modeset_ctl)
607
608#define DRM_IOCTL_SET_UNIQUE DRM_IOW( 0x10, struct drm_unique)
609#define DRM_IOCTL_AUTH_MAGIC DRM_IOW( 0x11, struct drm_auth)
610#define DRM_IOCTL_BLOCK DRM_IOWR(0x12, struct drm_block)
611#define DRM_IOCTL_UNBLOCK DRM_IOWR(0x13, struct drm_block)
612#define DRM_IOCTL_CONTROL DRM_IOW( 0x14, struct drm_control)
613#define DRM_IOCTL_ADD_MAP DRM_IOWR(0x15, struct drm_map)
614#define DRM_IOCTL_ADD_BUFS DRM_IOWR(0x16, struct drm_buf_desc)
615#define DRM_IOCTL_MARK_BUFS DRM_IOW( 0x17, struct drm_buf_desc)
616#define DRM_IOCTL_INFO_BUFS DRM_IOWR(0x18, struct drm_buf_info)
617#define DRM_IOCTL_MAP_BUFS DRM_IOWR(0x19, struct drm_buf_map)
618#define DRM_IOCTL_FREE_BUFS DRM_IOW( 0x1a, struct drm_buf_free)
619
620#define DRM_IOCTL_RM_MAP DRM_IOW( 0x1b, struct drm_map)
621
622#define DRM_IOCTL_SET_SAREA_CTX DRM_IOW( 0x1c, struct drm_ctx_priv_map)
623#define DRM_IOCTL_GET_SAREA_CTX DRM_IOWR(0x1d, struct drm_ctx_priv_map)
624
625#define DRM_IOCTL_ADD_CTX DRM_IOWR(0x20, struct drm_ctx)
626#define DRM_IOCTL_RM_CTX DRM_IOWR(0x21, struct drm_ctx)
627#define DRM_IOCTL_MOD_CTX DRM_IOW( 0x22, struct drm_ctx)
628#define DRM_IOCTL_GET_CTX DRM_IOWR(0x23, struct drm_ctx)
629#define DRM_IOCTL_SWITCH_CTX DRM_IOW( 0x24, struct drm_ctx)
630#define DRM_IOCTL_NEW_CTX DRM_IOW( 0x25, struct drm_ctx)
631#define DRM_IOCTL_RES_CTX DRM_IOWR(0x26, struct drm_ctx_res)
632#define DRM_IOCTL_ADD_DRAW DRM_IOWR(0x27, struct drm_draw)
633#define DRM_IOCTL_RM_DRAW DRM_IOWR(0x28, struct drm_draw)
634#define DRM_IOCTL_DMA DRM_IOWR(0x29, struct drm_dma)
635#define DRM_IOCTL_LOCK DRM_IOW( 0x2a, struct drm_lock)
636#define DRM_IOCTL_UNLOCK DRM_IOW( 0x2b, struct drm_lock)
637#define DRM_IOCTL_FINISH DRM_IOW( 0x2c, struct drm_lock)
638
639#define DRM_IOCTL_AGP_ACQUIRE DRM_IO( 0x30)
640#define DRM_IOCTL_AGP_RELEASE DRM_IO( 0x31)
641#define DRM_IOCTL_AGP_ENABLE DRM_IOW( 0x32, struct drm_agp_mode)
642#define DRM_IOCTL_AGP_INFO DRM_IOR( 0x33, struct drm_agp_info)
643#define DRM_IOCTL_AGP_ALLOC DRM_IOWR(0x34, struct drm_agp_buffer)
644#define DRM_IOCTL_AGP_FREE DRM_IOW( 0x35, struct drm_agp_buffer)
645#define DRM_IOCTL_AGP_BIND DRM_IOW( 0x36, struct drm_agp_binding)
646#define DRM_IOCTL_AGP_UNBIND DRM_IOW( 0x37, struct drm_agp_binding)
647
648#define DRM_IOCTL_SG_ALLOC DRM_IOW( 0x38, struct drm_scatter_gather)
649#define DRM_IOCTL_SG_FREE DRM_IOW( 0x39, struct drm_scatter_gather)
650
651#define DRM_IOCTL_WAIT_VBLANK DRM_IOWR(0x3a, union drm_wait_vblank)
652
653#define DRM_IOCTL_UPDATE_DRAW DRM_IOW(0x3f, struct drm_update_draw)
654
655/**
656 * Device specific ioctls should only be in their respective headers
657 * The device specific ioctl range is from 0x40 to 0x99.
658 * Generic IOCTLS restart at 0xA0.
659 *
660 * \sa drmCommandNone(), drmCommandRead(), drmCommandWrite(), and
661 * drmCommandReadWrite().
662 */
663#define DRM_COMMAND_BASE 0x40
664#define DRM_COMMAND_END 0xA0
665
666/* typedef area */
667#ifndef __KERNEL__
668typedef struct drm_clip_rect drm_clip_rect_t;
669typedef struct drm_drawable_info drm_drawable_info_t;
670typedef struct drm_tex_region drm_tex_region_t;
671typedef struct drm_hw_lock drm_hw_lock_t;
672typedef struct drm_version drm_version_t;
673typedef struct drm_unique drm_unique_t;
674typedef struct drm_list drm_list_t;
675typedef struct drm_block drm_block_t;
676typedef struct drm_control drm_control_t;
677typedef enum drm_map_type drm_map_type_t;
678typedef enum drm_map_flags drm_map_flags_t;
679typedef struct drm_ctx_priv_map drm_ctx_priv_map_t;
680typedef struct drm_map drm_map_t;
681typedef struct drm_client drm_client_t;
682typedef enum drm_stat_type drm_stat_type_t;
683typedef struct drm_stats drm_stats_t;
684typedef enum drm_lock_flags drm_lock_flags_t;
685typedef struct drm_lock drm_lock_t;
686typedef enum drm_dma_flags drm_dma_flags_t;
687typedef struct drm_buf_desc drm_buf_desc_t;
688typedef struct drm_buf_info drm_buf_info_t;
689typedef struct drm_buf_free drm_buf_free_t;
690typedef struct drm_buf_pub drm_buf_pub_t;
691typedef struct drm_buf_map drm_buf_map_t;
692typedef struct drm_dma drm_dma_t;
693typedef union drm_wait_vblank drm_wait_vblank_t;
694typedef struct drm_agp_mode drm_agp_mode_t;
695typedef enum drm_ctx_flags drm_ctx_flags_t;
696typedef struct drm_ctx drm_ctx_t;
697typedef struct drm_ctx_res drm_ctx_res_t;
698typedef struct drm_draw drm_draw_t;
699typedef struct drm_update_draw drm_update_draw_t;
700typedef struct drm_auth drm_auth_t;
701typedef struct drm_irq_busid drm_irq_busid_t;
702typedef enum drm_vblank_seq_type drm_vblank_seq_type_t;
703
704typedef struct drm_agp_buffer drm_agp_buffer_t;
705typedef struct drm_agp_binding drm_agp_binding_t;
706typedef struct drm_agp_info drm_agp_info_t;
707typedef struct drm_scatter_gather drm_scatter_gather_t;
708typedef struct drm_set_version drm_set_version_t;
709#endif
710
711#endif
diff --git a/drivers/char/drm/drmP.h b/drivers/char/drm/drmP.h
deleted file mode 100644
index 213b3ca3468e..000000000000
--- a/drivers/char/drm/drmP.h
+++ /dev/null
@@ -1,1210 +0,0 @@
1/**
2 * \file drmP.h
3 * Private header for Direct Rendering Manager
4 *
5 * \author Rickard E. (Rik) Faith <faith@valinux.com>
6 * \author Gareth Hughes <gareth@valinux.com>
7 */
8
9/*
10 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
11 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
12 * All rights reserved.
13 *
14 * Permission is hereby granted, free of charge, to any person obtaining a
15 * copy of this software and associated documentation files (the "Software"),
16 * to deal in the Software without restriction, including without limitation
17 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
18 * and/or sell copies of the Software, and to permit persons to whom the
19 * Software is furnished to do so, subject to the following conditions:
20 *
21 * The above copyright notice and this permission notice (including the next
22 * paragraph) shall be included in all copies or substantial portions of the
23 * Software.
24 *
25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
28 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
29 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
30 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
31 * OTHER DEALINGS IN THE SOFTWARE.
32 */
33
34#ifndef _DRM_P_H_
35#define _DRM_P_H_
36
37/* If you want the memory alloc debug functionality, change define below */
38/* #define DEBUG_MEMORY */
39
40#ifdef __KERNEL__
41#ifdef __alpha__
42/* add include of current.h so that "current" is defined
43 * before static inline funcs in wait.h. Doing this so we
44 * can build the DRM (part of PI DRI). 4/21/2000 S + B */
45#include <asm/current.h>
46#endif /* __alpha__ */
47#include <linux/module.h>
48#include <linux/kernel.h>
49#include <linux/miscdevice.h>
50#include <linux/fs.h>
51#include <linux/proc_fs.h>
52#include <linux/init.h>
53#include <linux/file.h>
54#include <linux/pci.h>
55#include <linux/jiffies.h>
56#include <linux/smp_lock.h> /* For (un)lock_kernel */
57#include <linux/dma-mapping.h>
58#include <linux/mm.h>
59#include <linux/cdev.h>
60#include <linux/mutex.h>
61#if defined(__alpha__) || defined(__powerpc__)
62#include <asm/pgtable.h> /* For pte_wrprotect */
63#endif
64#include <asm/io.h>
65#include <asm/mman.h>
66#include <asm/uaccess.h>
67#ifdef CONFIG_MTRR
68#include <asm/mtrr.h>
69#endif
70#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
71#include <linux/types.h>
72#include <linux/agp_backend.h>
73#endif
74#include <linux/workqueue.h>
75#include <linux/poll.h>
76#include <asm/pgalloc.h>
77#include "drm.h"
78
79#include <linux/idr.h>
80
81#define __OS_HAS_AGP (defined(CONFIG_AGP) || (defined(CONFIG_AGP_MODULE) && defined(MODULE)))
82#define __OS_HAS_MTRR (defined(CONFIG_MTRR))
83
84struct drm_file;
85struct drm_device;
86
87#include "drm_os_linux.h"
88#include "drm_hashtab.h"
89
90/***********************************************************************/
91/** \name DRM template customization defaults */
92/*@{*/
93
94/* driver capabilities and requirements mask */
95#define DRIVER_USE_AGP 0x1
96#define DRIVER_REQUIRE_AGP 0x2
97#define DRIVER_USE_MTRR 0x4
98#define DRIVER_PCI_DMA 0x8
99#define DRIVER_SG 0x10
100#define DRIVER_HAVE_DMA 0x20
101#define DRIVER_HAVE_IRQ 0x40
102#define DRIVER_IRQ_SHARED 0x80
103#define DRIVER_DMA_QUEUE 0x200
104#define DRIVER_FB_DMA 0x400
105
106/***********************************************************************/
107/** \name Begin the DRM... */
108/*@{*/
109
110#define DRM_DEBUG_CODE 2 /**< Include debugging code if > 1, then
111 also include looping detection. */
112
113#define DRM_MAGIC_HASH_ORDER 4 /**< Size of key hash table. Must be power of 2. */
114#define DRM_KERNEL_CONTEXT 0 /**< Change drm_resctx if changed */
115#define DRM_RESERVED_CONTEXTS 1 /**< Change drm_resctx if changed */
116#define DRM_LOOPING_LIMIT 5000000
117#define DRM_TIME_SLICE (HZ/20) /**< Time slice for GLXContexts */
118#define DRM_LOCK_SLICE 1 /**< Time slice for lock, in jiffies */
119
120#define DRM_FLAG_DEBUG 0x01
121
122#define DRM_MEM_DMA 0
123#define DRM_MEM_SAREA 1
124#define DRM_MEM_DRIVER 2
125#define DRM_MEM_MAGIC 3
126#define DRM_MEM_IOCTLS 4
127#define DRM_MEM_MAPS 5
128#define DRM_MEM_VMAS 6
129#define DRM_MEM_BUFS 7
130#define DRM_MEM_SEGS 8
131#define DRM_MEM_PAGES 9
132#define DRM_MEM_FILES 10
133#define DRM_MEM_QUEUES 11
134#define DRM_MEM_CMDS 12
135#define DRM_MEM_MAPPINGS 13
136#define DRM_MEM_BUFLISTS 14
137#define DRM_MEM_AGPLISTS 15
138#define DRM_MEM_TOTALAGP 16
139#define DRM_MEM_BOUNDAGP 17
140#define DRM_MEM_CTXBITMAP 18
141#define DRM_MEM_STUB 19
142#define DRM_MEM_SGLISTS 20
143#define DRM_MEM_CTXLIST 21
144#define DRM_MEM_MM 22
145#define DRM_MEM_HASHTAB 23
146
147#define DRM_MAX_CTXBITMAP (PAGE_SIZE * 8)
148#define DRM_MAP_HASH_OFFSET 0x10000000
149
150/*@}*/
151
152/***********************************************************************/
153/** \name Macros to make printk easier */
154/*@{*/
155
156/**
157 * Error output.
158 *
159 * \param fmt printf() like format string.
160 * \param arg arguments
161 */
162#define DRM_ERROR(fmt, arg...) \
163 printk(KERN_ERR "[" DRM_NAME ":%s] *ERROR* " fmt , __func__ , ##arg)
164
165/**
166 * Memory error output.
167 *
168 * \param area memory area where the error occurred.
169 * \param fmt printf() like format string.
170 * \param arg arguments
171 */
172#define DRM_MEM_ERROR(area, fmt, arg...) \
173 printk(KERN_ERR "[" DRM_NAME ":%s:%s] *ERROR* " fmt , __func__, \
174 drm_mem_stats[area].name , ##arg)
175
176#define DRM_INFO(fmt, arg...) printk(KERN_INFO "[" DRM_NAME "] " fmt , ##arg)
177
178/**
179 * Debug output.
180 *
181 * \param fmt printf() like format string.
182 * \param arg arguments
183 */
184#if DRM_DEBUG_CODE
185#define DRM_DEBUG(fmt, arg...) \
186 do { \
187 if ( drm_debug ) \
188 printk(KERN_DEBUG \
189 "[" DRM_NAME ":%s] " fmt , \
190 __func__ , ##arg); \
191 } while (0)
192#else
193#define DRM_DEBUG(fmt, arg...) do { } while (0)
194#endif
195
196#define DRM_PROC_LIMIT (PAGE_SIZE-80)
197
198#define DRM_PROC_PRINT(fmt, arg...) \
199 len += sprintf(&buf[len], fmt , ##arg); \
200 if (len > DRM_PROC_LIMIT) { *eof = 1; return len - offset; }
201
202#define DRM_PROC_PRINT_RET(ret, fmt, arg...) \
203 len += sprintf(&buf[len], fmt , ##arg); \
204 if (len > DRM_PROC_LIMIT) { ret; *eof = 1; return len - offset; }
205
206/*@}*/
207
208/***********************************************************************/
209/** \name Internal types and structures */
210/*@{*/
211
212#define DRM_ARRAY_SIZE(x) ARRAY_SIZE(x)
213
214#define DRM_LEFTCOUNT(x) (((x)->rp + (x)->count - (x)->wp) % ((x)->count + 1))
215#define DRM_BUFCOUNT(x) ((x)->count - DRM_LEFTCOUNT(x))
216#define DRM_WAITCOUNT(dev,idx) DRM_BUFCOUNT(&dev->queuelist[idx]->waitlist)
217
218#define DRM_IF_VERSION(maj, min) (maj << 16 | min)
219/**
220 * Get the private SAREA mapping.
221 *
222 * \param _dev DRM device.
223 * \param _ctx context number.
224 * \param _map output mapping.
225 */
226#define DRM_GET_PRIV_SAREA(_dev, _ctx, _map) do { \
227 (_map) = (_dev)->context_sareas[_ctx]; \
228} while(0)
229
230/**
231 * Test that the hardware lock is held by the caller, returning otherwise.
232 *
233 * \param dev DRM device.
234 * \param filp file pointer of the caller.
235 */
236#define LOCK_TEST_WITH_RETURN( dev, file_priv ) \
237do { \
238 if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || \
239 dev->lock.file_priv != file_priv ) { \
240 DRM_ERROR( "%s called without lock held, held %d owner %p %p\n",\
241 __func__, _DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ),\
242 dev->lock.file_priv, file_priv ); \
243 return -EINVAL; \
244 } \
245} while (0)
246
247/**
248 * Copy and IOCTL return string to user space
249 */
250#define DRM_COPY( name, value ) \
251 len = strlen( value ); \
252 if ( len > name##_len ) len = name##_len; \
253 name##_len = strlen( value ); \
254 if ( len && name ) { \
255 if ( copy_to_user( name, value, len ) ) \
256 return -EFAULT; \
257 }
258
259/**
260 * Ioctl function type.
261 *
262 * \param inode device inode.
263 * \param file_priv DRM file private pointer.
264 * \param cmd command.
265 * \param arg argument.
266 */
267typedef int drm_ioctl_t(struct drm_device *dev, void *data,
268 struct drm_file *file_priv);
269
270typedef int drm_ioctl_compat_t(struct file *filp, unsigned int cmd,
271 unsigned long arg);
272
273#define DRM_AUTH 0x1
274#define DRM_MASTER 0x2
275#define DRM_ROOT_ONLY 0x4
276
277struct drm_ioctl_desc {
278 unsigned int cmd;
279 drm_ioctl_t *func;
280 int flags;
281};
282
283/**
284 * Creates a driver or general drm_ioctl_desc array entry for the given
285 * ioctl, for use by drm_ioctl().
286 */
287#define DRM_IOCTL_DEF(ioctl, func, flags) \
288 [DRM_IOCTL_NR(ioctl)] = {ioctl, func, flags}
289
290struct drm_magic_entry {
291 struct list_head head;
292 struct drm_hash_item hash_item;
293 struct drm_file *priv;
294};
295
296struct drm_vma_entry {
297 struct list_head head;
298 struct vm_area_struct *vma;
299 pid_t pid;
300};
301
302/**
303 * DMA buffer.
304 */
305struct drm_buf {
306 int idx; /**< Index into master buflist */
307 int total; /**< Buffer size */
308 int order; /**< log-base-2(total) */
309 int used; /**< Amount of buffer in use (for DMA) */
310 unsigned long offset; /**< Byte offset (used internally) */
311 void *address; /**< Address of buffer */
312 unsigned long bus_address; /**< Bus address of buffer */
313 struct drm_buf *next; /**< Kernel-only: used for free list */
314 __volatile__ int waiting; /**< On kernel DMA queue */
315 __volatile__ int pending; /**< On hardware DMA queue */
316 wait_queue_head_t dma_wait; /**< Processes waiting */
317 struct drm_file *file_priv; /**< Private of holding file descr */
318 int context; /**< Kernel queue for this buffer */
319 int while_locked; /**< Dispatch this buffer while locked */
320 enum {
321 DRM_LIST_NONE = 0,
322 DRM_LIST_FREE = 1,
323 DRM_LIST_WAIT = 2,
324 DRM_LIST_PEND = 3,
325 DRM_LIST_PRIO = 4,
326 DRM_LIST_RECLAIM = 5
327 } list; /**< Which list we're on */
328
329 int dev_priv_size; /**< Size of buffer private storage */
330 void *dev_private; /**< Per-buffer private storage */
331};
332
333/** bufs is one longer than it has to be */
334struct drm_waitlist {
335 int count; /**< Number of possible buffers */
336 struct drm_buf **bufs; /**< List of pointers to buffers */
337 struct drm_buf **rp; /**< Read pointer */
338 struct drm_buf **wp; /**< Write pointer */
339 struct drm_buf **end; /**< End pointer */
340 spinlock_t read_lock;
341 spinlock_t write_lock;
342};
343
344struct drm_freelist {
345 int initialized; /**< Freelist in use */
346 atomic_t count; /**< Number of free buffers */
347 struct drm_buf *next; /**< End pointer */
348
349 wait_queue_head_t waiting; /**< Processes waiting on free bufs */
350 int low_mark; /**< Low water mark */
351 int high_mark; /**< High water mark */
352 atomic_t wfh; /**< If waiting for high mark */
353 spinlock_t lock;
354};
355
356typedef struct drm_dma_handle {
357 dma_addr_t busaddr;
358 void *vaddr;
359 size_t size;
360} drm_dma_handle_t;
361
362/**
363 * Buffer entry. There is one of this for each buffer size order.
364 */
365struct drm_buf_entry {
366 int buf_size; /**< size */
367 int buf_count; /**< number of buffers */
368 struct drm_buf *buflist; /**< buffer list */
369 int seg_count;
370 int page_order;
371 struct drm_dma_handle **seglist;
372
373 struct drm_freelist freelist;
374};
375
376/** File private data */
377struct drm_file {
378 int authenticated;
379 int master;
380 pid_t pid;
381 uid_t uid;
382 drm_magic_t magic;
383 unsigned long ioctl_count;
384 struct list_head lhead;
385 struct drm_minor *minor;
386 int remove_auth_on_close;
387 unsigned long lock_count;
388 struct file *filp;
389 void *driver_priv;
390};
391
392/** Wait queue */
393struct drm_queue {
394 atomic_t use_count; /**< Outstanding uses (+1) */
395 atomic_t finalization; /**< Finalization in progress */
396 atomic_t block_count; /**< Count of processes waiting */
397 atomic_t block_read; /**< Queue blocked for reads */
398 wait_queue_head_t read_queue; /**< Processes waiting on block_read */
399 atomic_t block_write; /**< Queue blocked for writes */
400 wait_queue_head_t write_queue; /**< Processes waiting on block_write */
401 atomic_t total_queued; /**< Total queued statistic */
402 atomic_t total_flushed; /**< Total flushes statistic */
403 atomic_t total_locks; /**< Total locks statistics */
404 enum drm_ctx_flags flags; /**< Context preserving and 2D-only */
405 struct drm_waitlist waitlist; /**< Pending buffers */
406 wait_queue_head_t flush_queue; /**< Processes waiting until flush */
407};
408
409/**
410 * Lock data.
411 */
412struct drm_lock_data {
413 struct drm_hw_lock *hw_lock; /**< Hardware lock */
414 /** Private of lock holder's file (NULL=kernel) */
415 struct drm_file *file_priv;
416 wait_queue_head_t lock_queue; /**< Queue of blocked processes */
417 unsigned long lock_time; /**< Time of last lock in jiffies */
418 spinlock_t spinlock;
419 uint32_t kernel_waiters;
420 uint32_t user_waiters;
421 int idle_has_lock;
422};
423
424/**
425 * DMA data.
426 */
427struct drm_device_dma {
428
429 struct drm_buf_entry bufs[DRM_MAX_ORDER + 1]; /**< buffers, grouped by their size order */
430 int buf_count; /**< total number of buffers */
431 struct drm_buf **buflist; /**< Vector of pointers into drm_device_dma::bufs */
432 int seg_count;
433 int page_count; /**< number of pages */
434 unsigned long *pagelist; /**< page list */
435 unsigned long byte_count;
436 enum {
437 _DRM_DMA_USE_AGP = 0x01,
438 _DRM_DMA_USE_SG = 0x02,
439 _DRM_DMA_USE_FB = 0x04,
440 _DRM_DMA_USE_PCI_RO = 0x08
441 } flags;
442
443};
444
445/**
446 * AGP memory entry. Stored as a doubly linked list.
447 */
448struct drm_agp_mem {
449 unsigned long handle; /**< handle */
450 DRM_AGP_MEM *memory;
451 unsigned long bound; /**< address */
452 int pages;
453 struct list_head head;
454};
455
456/**
457 * AGP data.
458 *
459 * \sa drm_agp_init() and drm_device::agp.
460 */
461struct drm_agp_head {
462 DRM_AGP_KERN agp_info; /**< AGP device information */
463 struct list_head memory;
464 unsigned long mode; /**< AGP mode */
465 struct agp_bridge_data *bridge;
466 int enabled; /**< whether the AGP bus as been enabled */
467 int acquired; /**< whether the AGP device has been acquired */
468 unsigned long base;
469 int agp_mtrr;
470 int cant_use_aperture;
471 unsigned long page_mask;
472};
473
474/**
475 * Scatter-gather memory.
476 */
477struct drm_sg_mem {
478 unsigned long handle;
479 void *virtual;
480 int pages;
481 struct page **pagelist;
482 dma_addr_t *busaddr;
483};
484
485struct drm_sigdata {
486 int context;
487 struct drm_hw_lock *lock;
488};
489
490
491/*
492 * Generic memory manager structs
493 */
494
495struct drm_mm_node {
496 struct list_head fl_entry;
497 struct list_head ml_entry;
498 int free;
499 unsigned long start;
500 unsigned long size;
501 struct drm_mm *mm;
502 void *private;
503};
504
505struct drm_mm {
506 struct list_head fl_entry;
507 struct list_head ml_entry;
508};
509
510
511/**
512 * Mappings list
513 */
514struct drm_map_list {
515 struct list_head head; /**< list head */
516 struct drm_hash_item hash;
517 struct drm_map *map; /**< mapping */
518 uint64_t user_token;
519};
520
521typedef struct drm_map drm_local_map_t;
522
523/**
524 * Context handle list
525 */
526struct drm_ctx_list {
527 struct list_head head; /**< list head */
528 drm_context_t handle; /**< context handle */
529 struct drm_file *tag; /**< associated fd private data */
530};
531
532struct drm_vbl_sig {
533 struct list_head head;
534 unsigned int sequence;
535 struct siginfo info;
536 struct task_struct *task;
537};
538
539/* location of GART table */
540#define DRM_ATI_GART_MAIN 1
541#define DRM_ATI_GART_FB 2
542
543#define DRM_ATI_GART_PCI 1
544#define DRM_ATI_GART_PCIE 2
545#define DRM_ATI_GART_IGP 3
546
547struct drm_ati_pcigart_info {
548 int gart_table_location;
549 int gart_reg_if;
550 void *addr;
551 dma_addr_t bus_addr;
552 dma_addr_t table_mask;
553 struct drm_dma_handle *table_handle;
554 drm_local_map_t mapping;
555 int table_size;
556};
557
558/**
559 * DRM driver structure. This structure represent the common code for
560 * a family of cards. There will one drm_device for each card present
561 * in this family
562 */
563struct drm_driver {
564 int (*load) (struct drm_device *, unsigned long flags);
565 int (*firstopen) (struct drm_device *);
566 int (*open) (struct drm_device *, struct drm_file *);
567 void (*preclose) (struct drm_device *, struct drm_file *file_priv);
568 void (*postclose) (struct drm_device *, struct drm_file *);
569 void (*lastclose) (struct drm_device *);
570 int (*unload) (struct drm_device *);
571 int (*suspend) (struct drm_device *, pm_message_t state);
572 int (*resume) (struct drm_device *);
573 int (*dma_ioctl) (struct drm_device *dev, void *data, struct drm_file *file_priv);
574 void (*dma_ready) (struct drm_device *);
575 int (*dma_quiescent) (struct drm_device *);
576 int (*context_ctor) (struct drm_device *dev, int context);
577 int (*context_dtor) (struct drm_device *dev, int context);
578 int (*kernel_context_switch) (struct drm_device *dev, int old,
579 int new);
580 void (*kernel_context_switch_unlock) (struct drm_device * dev);
581 /**
582 * get_vblank_counter - get raw hardware vblank counter
583 * @dev: DRM device
584 * @crtc: counter to fetch
585 *
586 * Driver callback for fetching a raw hardware vblank counter
587 * for @crtc. If a device doesn't have a hardware counter, the
588 * driver can simply return the value of drm_vblank_count and
589 * make the enable_vblank() and disable_vblank() hooks into no-ops,
590 * leaving interrupts enabled at all times.
591 *
592 * Wraparound handling and loss of events due to modesetting is dealt
593 * with in the DRM core code.
594 *
595 * RETURNS
596 * Raw vblank counter value.
597 */
598 u32 (*get_vblank_counter) (struct drm_device *dev, int crtc);
599
600 /**
601 * enable_vblank - enable vblank interrupt events
602 * @dev: DRM device
603 * @crtc: which irq to enable
604 *
605 * Enable vblank interrupts for @crtc. If the device doesn't have
606 * a hardware vblank counter, this routine should be a no-op, since
607 * interrupts will have to stay on to keep the count accurate.
608 *
609 * RETURNS
610 * Zero on success, appropriate errno if the given @crtc's vblank
611 * interrupt cannot be enabled.
612 */
613 int (*enable_vblank) (struct drm_device *dev, int crtc);
614
615 /**
616 * disable_vblank - disable vblank interrupt events
617 * @dev: DRM device
618 * @crtc: which irq to enable
619 *
620 * Disable vblank interrupts for @crtc. If the device doesn't have
621 * a hardware vblank counter, this routine should be a no-op, since
622 * interrupts will have to stay on to keep the count accurate.
623 */
624 void (*disable_vblank) (struct drm_device *dev, int crtc);
625 int (*dri_library_name) (struct drm_device *dev, char * buf);
626
627 /**
628 * Called by \c drm_device_is_agp. Typically used to determine if a
629 * card is really attached to AGP or not.
630 *
631 * \param dev DRM device handle
632 *
633 * \returns
634 * One of three values is returned depending on whether or not the
635 * card is absolutely \b not AGP (return of 0), absolutely \b is AGP
636 * (return of 1), or may or may not be AGP (return of 2).
637 */
638 int (*device_is_agp) (struct drm_device *dev);
639
640 /* these have to be filled in */
641
642 irqreturn_t(*irq_handler) (DRM_IRQ_ARGS);
643 void (*irq_preinstall) (struct drm_device *dev);
644 int (*irq_postinstall) (struct drm_device *dev);
645 void (*irq_uninstall) (struct drm_device *dev);
646 void (*reclaim_buffers) (struct drm_device *dev,
647 struct drm_file * file_priv);
648 void (*reclaim_buffers_locked) (struct drm_device *dev,
649 struct drm_file *file_priv);
650 void (*reclaim_buffers_idlelocked) (struct drm_device *dev,
651 struct drm_file *file_priv);
652 unsigned long (*get_map_ofs) (struct drm_map * map);
653 unsigned long (*get_reg_ofs) (struct drm_device *dev);
654 void (*set_version) (struct drm_device *dev,
655 struct drm_set_version *sv);
656
657 int major;
658 int minor;
659 int patchlevel;
660 char *name;
661 char *desc;
662 char *date;
663
664 u32 driver_features;
665 int dev_priv_size;
666 struct drm_ioctl_desc *ioctls;
667 int num_ioctls;
668 struct file_operations fops;
669 struct pci_driver pci_driver;
670};
671
672#define DRM_MINOR_UNASSIGNED 0
673#define DRM_MINOR_LEGACY 1
674
675/**
676 * DRM minor structure. This structure represents a drm minor number.
677 */
678struct drm_minor {
679 int index; /**< Minor device number */
680 int type; /**< Control or render */
681 dev_t device; /**< Device number for mknod */
682 struct device kdev; /**< Linux device */
683 struct drm_device *dev;
684 struct proc_dir_entry *dev_root; /**< proc directory entry */
685};
686
687/**
688 * DRM device structure. This structure represent a complete card that
689 * may contain multiple heads.
690 */
691struct drm_device {
692 char *unique; /**< Unique identifier: e.g., busid */
693 int unique_len; /**< Length of unique field */
694 char *devname; /**< For /proc/interrupts */
695 int if_version; /**< Highest interface version set */
696
697 int blocked; /**< Blocked due to VC switch? */
698
699 /** \name Locks */
700 /*@{ */
701 spinlock_t count_lock; /**< For inuse, drm_device::open_count, drm_device::buf_use */
702 struct mutex struct_mutex; /**< For others */
703 /*@} */
704
705 /** \name Usage Counters */
706 /*@{ */
707 int open_count; /**< Outstanding files open */
708 atomic_t ioctl_count; /**< Outstanding IOCTLs pending */
709 atomic_t vma_count; /**< Outstanding vma areas open */
710 int buf_use; /**< Buffers in use -- cannot alloc */
711 atomic_t buf_alloc; /**< Buffer allocation in progress */
712 /*@} */
713
714 /** \name Performance counters */
715 /*@{ */
716 unsigned long counters;
717 enum drm_stat_type types[15];
718 atomic_t counts[15];
719 /*@} */
720
721 /** \name Authentication */
722 /*@{ */
723 struct list_head filelist;
724 struct drm_open_hash magiclist; /**< magic hash table */
725 struct list_head magicfree;
726 /*@} */
727
728 /** \name Memory management */
729 /*@{ */
730 struct list_head maplist; /**< Linked list of regions */
731 int map_count; /**< Number of mappable regions */
732 struct drm_open_hash map_hash; /**< User token hash table for maps */
733
734 /** \name Context handle management */
735 /*@{ */
736 struct list_head ctxlist; /**< Linked list of context handles */
737 int ctx_count; /**< Number of context handles */
738 struct mutex ctxlist_mutex; /**< For ctxlist */
739
740 struct idr ctx_idr;
741
742 struct list_head vmalist; /**< List of vmas (for debugging) */
743 struct drm_lock_data lock; /**< Information on hardware lock */
744 /*@} */
745
746 /** \name DMA queues (contexts) */
747 /*@{ */
748 int queue_count; /**< Number of active DMA queues */
749 int queue_reserved; /**< Number of reserved DMA queues */
750 int queue_slots; /**< Actual length of queuelist */
751 struct drm_queue **queuelist; /**< Vector of pointers to DMA queues */
752 struct drm_device_dma *dma; /**< Optional pointer for DMA support */
753 /*@} */
754
755 /** \name Context support */
756 /*@{ */
757 int irq; /**< Interrupt used by board */
758 int irq_enabled; /**< True if irq handler is enabled */
759 __volatile__ long context_flag; /**< Context swapping flag */
760 __volatile__ long interrupt_flag; /**< Interruption handler flag */
761 __volatile__ long dma_flag; /**< DMA dispatch flag */
762 struct timer_list timer; /**< Timer for delaying ctx switch */
763 wait_queue_head_t context_wait; /**< Processes waiting on ctx switch */
764 int last_checked; /**< Last context checked for DMA */
765 int last_context; /**< Last current context */
766 unsigned long last_switch; /**< jiffies at last context switch */
767 /*@} */
768
769 struct work_struct work;
770 /** \name VBLANK IRQ support */
771 /*@{ */
772
773 wait_queue_head_t *vbl_queue; /**< VBLANK wait queue */
774 atomic_t *_vblank_count; /**< number of VBLANK interrupts (driver must alloc the right number of counters) */
775 spinlock_t vbl_lock;
776 struct list_head *vbl_sigs; /**< signal list to send on VBLANK */
777 atomic_t vbl_signal_pending; /* number of signals pending on all crtcs*/
778 atomic_t *vblank_refcount; /* number of users of vblank interrupts per crtc */
779 u32 *last_vblank; /* protected by dev->vbl_lock, used */
780 /* for wraparound handling */
781 u32 *vblank_offset; /* used to track how many vblanks */
782 int *vblank_enabled; /* so we don't call enable more than
783 once per disable */
784 u32 *vblank_premodeset; /* were lost during modeset */
785 struct timer_list vblank_disable_timer;
786
787 unsigned long max_vblank_count; /**< size of vblank counter register */
788 spinlock_t tasklet_lock; /**< For drm_locked_tasklet */
789 void (*locked_tasklet_func)(struct drm_device *dev);
790
791 /*@} */
792 cycles_t ctx_start;
793 cycles_t lck_start;
794
795 struct fasync_struct *buf_async;/**< Processes waiting for SIGIO */
796 wait_queue_head_t buf_readers; /**< Processes waiting to read */
797 wait_queue_head_t buf_writers; /**< Processes waiting to ctx switch */
798
799 struct drm_agp_head *agp; /**< AGP data */
800
801 struct pci_dev *pdev; /**< PCI device structure */
802 int pci_vendor; /**< PCI vendor id */
803 int pci_device; /**< PCI device id */
804#ifdef __alpha__
805 struct pci_controller *hose;
806#endif
807 int num_crtcs; /**< Number of CRTCs on this device */
808 struct drm_sg_mem *sg; /**< Scatter gather memory */
809 void *dev_private; /**< device private data */
810 struct drm_sigdata sigdata; /**< For block_all_signals */
811 sigset_t sigmask;
812
813 struct drm_driver *driver;
814 drm_local_map_t *agp_buffer_map;
815 unsigned int agp_buffer_token;
816 struct drm_minor *primary; /**< render type primary screen head */
817
818 /** \name Drawable information */
819 /*@{ */
820 spinlock_t drw_lock;
821 struct idr drw_idr;
822 /*@} */
823};
824
825static __inline__ int drm_core_check_feature(struct drm_device *dev,
826 int feature)
827{
828 return ((dev->driver->driver_features & feature) ? 1 : 0);
829}
830
831#ifdef __alpha__
832#define drm_get_pci_domain(dev) dev->hose->index
833#else
834#define drm_get_pci_domain(dev) 0
835#endif
836
837#if __OS_HAS_AGP
838static inline int drm_core_has_AGP(struct drm_device *dev)
839{
840 return drm_core_check_feature(dev, DRIVER_USE_AGP);
841}
842#else
843#define drm_core_has_AGP(dev) (0)
844#endif
845
846#if __OS_HAS_MTRR
847static inline int drm_core_has_MTRR(struct drm_device *dev)
848{
849 return drm_core_check_feature(dev, DRIVER_USE_MTRR);
850}
851
852#define DRM_MTRR_WC MTRR_TYPE_WRCOMB
853
854static inline int drm_mtrr_add(unsigned long offset, unsigned long size,
855 unsigned int flags)
856{
857 return mtrr_add(offset, size, flags, 1);
858}
859
860static inline int drm_mtrr_del(int handle, unsigned long offset,
861 unsigned long size, unsigned int flags)
862{
863 return mtrr_del(handle, offset, size);
864}
865
866#else
867#define drm_core_has_MTRR(dev) (0)
868
869#define DRM_MTRR_WC 0
870
871static inline int drm_mtrr_add(unsigned long offset, unsigned long size,
872 unsigned int flags)
873{
874 return 0;
875}
876
877static inline int drm_mtrr_del(int handle, unsigned long offset,
878 unsigned long size, unsigned int flags)
879{
880 return 0;
881}
882#endif
883
884/******************************************************************/
885/** \name Internal function definitions */
886/*@{*/
887
888 /* Driver support (drm_drv.h) */
889extern int drm_init(struct drm_driver *driver);
890extern void drm_exit(struct drm_driver *driver);
891extern int drm_ioctl(struct inode *inode, struct file *filp,
892 unsigned int cmd, unsigned long arg);
893extern long drm_compat_ioctl(struct file *filp,
894 unsigned int cmd, unsigned long arg);
895extern int drm_lastclose(struct drm_device *dev);
896
897 /* Device support (drm_fops.h) */
898extern int drm_open(struct inode *inode, struct file *filp);
899extern int drm_stub_open(struct inode *inode, struct file *filp);
900extern int drm_fasync(int fd, struct file *filp, int on);
901extern int drm_release(struct inode *inode, struct file *filp);
902
903 /* Mapping support (drm_vm.h) */
904extern int drm_mmap(struct file *filp, struct vm_area_struct *vma);
905extern unsigned long drm_core_get_map_ofs(struct drm_map * map);
906extern unsigned long drm_core_get_reg_ofs(struct drm_device *dev);
907extern unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait);
908
909 /* Memory management support (drm_memory.h) */
910#include "drm_memory.h"
911extern void drm_mem_init(void);
912extern int drm_mem_info(char *buf, char **start, off_t offset,
913 int request, int *eof, void *data);
914extern void *drm_realloc(void *oldpt, size_t oldsize, size_t size, int area);
915
916extern DRM_AGP_MEM *drm_alloc_agp(struct drm_device *dev, int pages, u32 type);
917extern int drm_free_agp(DRM_AGP_MEM * handle, int pages);
918extern int drm_bind_agp(DRM_AGP_MEM * handle, unsigned int start);
919extern int drm_unbind_agp(DRM_AGP_MEM * handle);
920
921 /* Misc. IOCTL support (drm_ioctl.h) */
922extern int drm_irq_by_busid(struct drm_device *dev, void *data,
923 struct drm_file *file_priv);
924extern int drm_getunique(struct drm_device *dev, void *data,
925 struct drm_file *file_priv);
926extern int drm_setunique(struct drm_device *dev, void *data,
927 struct drm_file *file_priv);
928extern int drm_getmap(struct drm_device *dev, void *data,
929 struct drm_file *file_priv);
930extern int drm_getclient(struct drm_device *dev, void *data,
931 struct drm_file *file_priv);
932extern int drm_getstats(struct drm_device *dev, void *data,
933 struct drm_file *file_priv);
934extern int drm_setversion(struct drm_device *dev, void *data,
935 struct drm_file *file_priv);
936extern int drm_noop(struct drm_device *dev, void *data,
937 struct drm_file *file_priv);
938
939 /* Context IOCTL support (drm_context.h) */
940extern int drm_resctx(struct drm_device *dev, void *data,
941 struct drm_file *file_priv);
942extern int drm_addctx(struct drm_device *dev, void *data,
943 struct drm_file *file_priv);
944extern int drm_modctx(struct drm_device *dev, void *data,
945 struct drm_file *file_priv);
946extern int drm_getctx(struct drm_device *dev, void *data,
947 struct drm_file *file_priv);
948extern int drm_switchctx(struct drm_device *dev, void *data,
949 struct drm_file *file_priv);
950extern int drm_newctx(struct drm_device *dev, void *data,
951 struct drm_file *file_priv);
952extern int drm_rmctx(struct drm_device *dev, void *data,
953 struct drm_file *file_priv);
954
955extern int drm_ctxbitmap_init(struct drm_device *dev);
956extern void drm_ctxbitmap_cleanup(struct drm_device *dev);
957extern void drm_ctxbitmap_free(struct drm_device *dev, int ctx_handle);
958
959extern int drm_setsareactx(struct drm_device *dev, void *data,
960 struct drm_file *file_priv);
961extern int drm_getsareactx(struct drm_device *dev, void *data,
962 struct drm_file *file_priv);
963
964 /* Drawable IOCTL support (drm_drawable.h) */
965extern int drm_adddraw(struct drm_device *dev, void *data,
966 struct drm_file *file_priv);
967extern int drm_rmdraw(struct drm_device *dev, void *data,
968 struct drm_file *file_priv);
969extern int drm_update_drawable_info(struct drm_device *dev, void *data,
970 struct drm_file *file_priv);
971extern struct drm_drawable_info *drm_get_drawable_info(struct drm_device *dev,
972 drm_drawable_t id);
973extern void drm_drawable_free_all(struct drm_device *dev);
974
975 /* Authentication IOCTL support (drm_auth.h) */
976extern int drm_getmagic(struct drm_device *dev, void *data,
977 struct drm_file *file_priv);
978extern int drm_authmagic(struct drm_device *dev, void *data,
979 struct drm_file *file_priv);
980
981 /* Locking IOCTL support (drm_lock.h) */
982extern int drm_lock(struct drm_device *dev, void *data,
983 struct drm_file *file_priv);
984extern int drm_unlock(struct drm_device *dev, void *data,
985 struct drm_file *file_priv);
986extern int drm_lock_take(struct drm_lock_data *lock_data, unsigned int context);
987extern int drm_lock_free(struct drm_lock_data *lock_data, unsigned int context);
988extern void drm_idlelock_take(struct drm_lock_data *lock_data);
989extern void drm_idlelock_release(struct drm_lock_data *lock_data);
990
991/*
992 * These are exported to drivers so that they can implement fencing using
993 * DMA quiscent + idle. DMA quiescent usually requires the hardware lock.
994 */
995
996extern int drm_i_have_hw_lock(struct drm_device *dev, struct drm_file *file_priv);
997
998 /* Buffer management support (drm_bufs.h) */
999extern int drm_addbufs_agp(struct drm_device *dev, struct drm_buf_desc * request);
1000extern int drm_addbufs_pci(struct drm_device *dev, struct drm_buf_desc * request);
1001extern int drm_addmap(struct drm_device *dev, unsigned int offset,
1002 unsigned int size, enum drm_map_type type,
1003 enum drm_map_flags flags, drm_local_map_t ** map_ptr);
1004extern int drm_addmap_ioctl(struct drm_device *dev, void *data,
1005 struct drm_file *file_priv);
1006extern int drm_rmmap(struct drm_device *dev, drm_local_map_t *map);
1007extern int drm_rmmap_locked(struct drm_device *dev, drm_local_map_t *map);
1008extern int drm_rmmap_ioctl(struct drm_device *dev, void *data,
1009 struct drm_file *file_priv);
1010extern int drm_addbufs(struct drm_device *dev, void *data,
1011 struct drm_file *file_priv);
1012extern int drm_infobufs(struct drm_device *dev, void *data,
1013 struct drm_file *file_priv);
1014extern int drm_markbufs(struct drm_device *dev, void *data,
1015 struct drm_file *file_priv);
1016extern int drm_freebufs(struct drm_device *dev, void *data,
1017 struct drm_file *file_priv);
1018extern int drm_mapbufs(struct drm_device *dev, void *data,
1019 struct drm_file *file_priv);
1020extern int drm_order(unsigned long size);
1021extern unsigned long drm_get_resource_start(struct drm_device *dev,
1022 unsigned int resource);
1023extern unsigned long drm_get_resource_len(struct drm_device *dev,
1024 unsigned int resource);
1025
1026 /* DMA support (drm_dma.h) */
1027extern int drm_dma_setup(struct drm_device *dev);
1028extern void drm_dma_takedown(struct drm_device *dev);
1029extern void drm_free_buffer(struct drm_device *dev, struct drm_buf * buf);
1030extern void drm_core_reclaim_buffers(struct drm_device *dev,
1031 struct drm_file *filp);
1032
1033 /* IRQ support (drm_irq.h) */
1034extern int drm_control(struct drm_device *dev, void *data,
1035 struct drm_file *file_priv);
1036extern irqreturn_t drm_irq_handler(DRM_IRQ_ARGS);
1037extern int drm_irq_uninstall(struct drm_device *dev);
1038extern void drm_driver_irq_preinstall(struct drm_device *dev);
1039extern void drm_driver_irq_postinstall(struct drm_device *dev);
1040extern void drm_driver_irq_uninstall(struct drm_device *dev);
1041
1042extern int drm_vblank_init(struct drm_device *dev, int num_crtcs);
1043extern int drm_wait_vblank(struct drm_device *dev, void *data, struct drm_file *filp);
1044extern int drm_vblank_wait(struct drm_device * dev, unsigned int *vbl_seq);
1045extern void drm_locked_tasklet(struct drm_device *dev, void(*func)(struct drm_device*));
1046extern u32 drm_vblank_count(struct drm_device *dev, int crtc);
1047extern void drm_update_vblank_count(struct drm_device *dev, int crtc);
1048extern void drm_handle_vblank(struct drm_device *dev, int crtc);
1049extern int drm_vblank_get(struct drm_device *dev, int crtc);
1050extern void drm_vblank_put(struct drm_device *dev, int crtc);
1051
1052 /* Modesetting support */
1053extern int drm_modeset_ctl(struct drm_device *dev, void *data,
1054 struct drm_file *file_priv);
1055
1056 /* AGP/GART support (drm_agpsupport.h) */
1057extern struct drm_agp_head *drm_agp_init(struct drm_device *dev);
1058extern int drm_agp_acquire(struct drm_device *dev);
1059extern int drm_agp_acquire_ioctl(struct drm_device *dev, void *data,
1060 struct drm_file *file_priv);
1061extern int drm_agp_release(struct drm_device *dev);
1062extern int drm_agp_release_ioctl(struct drm_device *dev, void *data,
1063 struct drm_file *file_priv);
1064extern int drm_agp_enable(struct drm_device *dev, struct drm_agp_mode mode);
1065extern int drm_agp_enable_ioctl(struct drm_device *dev, void *data,
1066 struct drm_file *file_priv);
1067extern int drm_agp_info(struct drm_device *dev, struct drm_agp_info *info);
1068extern int drm_agp_info_ioctl(struct drm_device *dev, void *data,
1069 struct drm_file *file_priv);
1070extern int drm_agp_alloc(struct drm_device *dev, struct drm_agp_buffer *request);
1071extern int drm_agp_alloc_ioctl(struct drm_device *dev, void *data,
1072 struct drm_file *file_priv);
1073extern int drm_agp_free(struct drm_device *dev, struct drm_agp_buffer *request);
1074extern int drm_agp_free_ioctl(struct drm_device *dev, void *data,
1075 struct drm_file *file_priv);
1076extern int drm_agp_unbind(struct drm_device *dev, struct drm_agp_binding *request);
1077extern int drm_agp_unbind_ioctl(struct drm_device *dev, void *data,
1078 struct drm_file *file_priv);
1079extern int drm_agp_bind(struct drm_device *dev, struct drm_agp_binding *request);
1080extern int drm_agp_bind_ioctl(struct drm_device *dev, void *data,
1081 struct drm_file *file_priv);
1082extern DRM_AGP_MEM *drm_agp_allocate_memory(struct agp_bridge_data *bridge, size_t pages, u32 type);
1083extern int drm_agp_free_memory(DRM_AGP_MEM * handle);
1084extern int drm_agp_bind_memory(DRM_AGP_MEM * handle, off_t start);
1085extern int drm_agp_unbind_memory(DRM_AGP_MEM * handle);
1086
1087 /* Stub support (drm_stub.h) */
1088extern int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
1089 struct drm_driver *driver);
1090extern int drm_put_dev(struct drm_device *dev);
1091extern int drm_put_minor(struct drm_minor **minor);
1092extern unsigned int drm_debug;
1093
1094extern struct class *drm_class;
1095extern struct proc_dir_entry *drm_proc_root;
1096
1097extern struct idr drm_minors_idr;
1098
1099extern drm_local_map_t *drm_getsarea(struct drm_device *dev);
1100
1101 /* Proc support (drm_proc.h) */
1102extern int drm_proc_init(struct drm_minor *minor, int minor_id,
1103 struct proc_dir_entry *root);
1104extern int drm_proc_cleanup(struct drm_minor *minor, struct proc_dir_entry *root);
1105
1106 /* Scatter Gather Support (drm_scatter.h) */
1107extern void drm_sg_cleanup(struct drm_sg_mem * entry);
1108extern int drm_sg_alloc_ioctl(struct drm_device *dev, void *data,
1109 struct drm_file *file_priv);
1110extern int drm_sg_alloc(struct drm_device *dev, struct drm_scatter_gather * request);
1111extern int drm_sg_free(struct drm_device *dev, void *data,
1112 struct drm_file *file_priv);
1113
1114 /* ATI PCIGART support (ati_pcigart.h) */
1115extern int drm_ati_pcigart_init(struct drm_device *dev,
1116 struct drm_ati_pcigart_info * gart_info);
1117extern int drm_ati_pcigart_cleanup(struct drm_device *dev,
1118 struct drm_ati_pcigart_info * gart_info);
1119
1120extern drm_dma_handle_t *drm_pci_alloc(struct drm_device *dev, size_t size,
1121 size_t align, dma_addr_t maxaddr);
1122extern void __drm_pci_free(struct drm_device *dev, drm_dma_handle_t * dmah);
1123extern void drm_pci_free(struct drm_device *dev, drm_dma_handle_t * dmah);
1124
1125 /* sysfs support (drm_sysfs.c) */
1126struct drm_sysfs_class;
1127extern struct class *drm_sysfs_create(struct module *owner, char *name);
1128extern void drm_sysfs_destroy(void);
1129extern int drm_sysfs_device_add(struct drm_minor *minor);
1130extern void drm_sysfs_device_remove(struct drm_minor *minor);
1131
1132/*
1133 * Basic memory manager support (drm_mm.c)
1134 */
1135extern struct drm_mm_node *drm_mm_get_block(struct drm_mm_node * parent,
1136 unsigned long size,
1137 unsigned alignment);
1138extern void drm_mm_put_block(struct drm_mm_node * cur);
1139extern struct drm_mm_node *drm_mm_search_free(const struct drm_mm *mm, unsigned long size,
1140 unsigned alignment, int best_match);
1141extern int drm_mm_init(struct drm_mm *mm, unsigned long start, unsigned long size);
1142extern void drm_mm_takedown(struct drm_mm *mm);
1143extern int drm_mm_clean(struct drm_mm *mm);
1144extern unsigned long drm_mm_tail_space(struct drm_mm *mm);
1145extern int drm_mm_remove_space_from_tail(struct drm_mm *mm, unsigned long size);
1146extern int drm_mm_add_space_to_tail(struct drm_mm *mm, unsigned long size);
1147
1148extern void drm_core_ioremap(struct drm_map *map, struct drm_device *dev);
1149extern void drm_core_ioremapfree(struct drm_map *map, struct drm_device *dev);
1150
1151static __inline__ struct drm_map *drm_core_findmap(struct drm_device *dev,
1152 unsigned int token)
1153{
1154 struct drm_map_list *_entry;
1155 list_for_each_entry(_entry, &dev->maplist, head)
1156 if (_entry->user_token == token)
1157 return _entry->map;
1158 return NULL;
1159}
1160
1161static __inline__ int drm_device_is_agp(struct drm_device *dev)
1162{
1163 if (dev->driver->device_is_agp != NULL) {
1164 int err = (*dev->driver->device_is_agp) (dev);
1165
1166 if (err != 2) {
1167 return err;
1168 }
1169 }
1170
1171 return pci_find_capability(dev->pdev, PCI_CAP_ID_AGP);
1172}
1173
1174static __inline__ int drm_device_is_pcie(struct drm_device *dev)
1175{
1176 return pci_find_capability(dev->pdev, PCI_CAP_ID_EXP);
1177}
1178
1179static __inline__ void drm_core_dropmap(struct drm_map *map)
1180{
1181}
1182
1183#ifndef DEBUG_MEMORY
1184/** Wrapper around kmalloc() */
1185static __inline__ void *drm_alloc(size_t size, int area)
1186{
1187 return kmalloc(size, GFP_KERNEL);
1188}
1189
1190/** Wrapper around kfree() */
1191static __inline__ void drm_free(void *pt, size_t size, int area)
1192{
1193 kfree(pt);
1194}
1195
1196/** Wrapper around kcalloc() */
1197static __inline__ void *drm_calloc(size_t nmemb, size_t size, int area)
1198{
1199 return kcalloc(nmemb, size, GFP_KERNEL);
1200}
1201#else
1202extern void *drm_alloc(size_t size, int area);
1203extern void drm_free(void *pt, size_t size, int area);
1204extern void *drm_calloc(size_t nmemb, size_t size, int area);
1205#endif
1206
1207/*@}*/
1208
1209#endif /* __KERNEL__ */
1210#endif
diff --git a/drivers/char/drm/drm_agpsupport.c b/drivers/char/drm/drm_agpsupport.c
deleted file mode 100644
index aefa5ac4c0b1..000000000000
--- a/drivers/char/drm/drm_agpsupport.c
+++ /dev/null
@@ -1,455 +0,0 @@
1/**
2 * \file drm_agpsupport.c
3 * DRM support for AGP/GART backend
4 *
5 * \author Rickard E. (Rik) Faith <faith@valinux.com>
6 * \author Gareth Hughes <gareth@valinux.com>
7 */
8
9/*
10 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
11 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
12 * All Rights Reserved.
13 *
14 * Permission is hereby granted, free of charge, to any person obtaining a
15 * copy of this software and associated documentation files (the "Software"),
16 * to deal in the Software without restriction, including without limitation
17 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
18 * and/or sell copies of the Software, and to permit persons to whom the
19 * Software is furnished to do so, subject to the following conditions:
20 *
21 * The above copyright notice and this permission notice (including the next
22 * paragraph) shall be included in all copies or substantial portions of the
23 * Software.
24 *
25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
28 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
29 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
30 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
31 * OTHER DEALINGS IN THE SOFTWARE.
32 */
33
34#include "drmP.h"
35#include <linux/module.h>
36
37#if __OS_HAS_AGP
38
39/**
40 * Get AGP information.
41 *
42 * \param inode device inode.
43 * \param file_priv DRM file private.
44 * \param cmd command.
45 * \param arg pointer to a (output) drm_agp_info structure.
46 * \return zero on success or a negative number on failure.
47 *
48 * Verifies the AGP device has been initialized and acquired and fills in the
49 * drm_agp_info structure with the information in drm_agp_head::agp_info.
50 */
51int drm_agp_info(struct drm_device *dev, struct drm_agp_info *info)
52{
53 DRM_AGP_KERN *kern;
54
55 if (!dev->agp || !dev->agp->acquired)
56 return -EINVAL;
57
58 kern = &dev->agp->agp_info;
59 info->agp_version_major = kern->version.major;
60 info->agp_version_minor = kern->version.minor;
61 info->mode = kern->mode;
62 info->aperture_base = kern->aper_base;
63 info->aperture_size = kern->aper_size * 1024 * 1024;
64 info->memory_allowed = kern->max_memory << PAGE_SHIFT;
65 info->memory_used = kern->current_memory << PAGE_SHIFT;
66 info->id_vendor = kern->device->vendor;
67 info->id_device = kern->device->device;
68
69 return 0;
70}
71
72EXPORT_SYMBOL(drm_agp_info);
73
74int drm_agp_info_ioctl(struct drm_device *dev, void *data,
75 struct drm_file *file_priv)
76{
77 struct drm_agp_info *info = data;
78 int err;
79
80 err = drm_agp_info(dev, info);
81 if (err)
82 return err;
83
84 return 0;
85}
86
87/**
88 * Acquire the AGP device.
89 *
90 * \param dev DRM device that is to acquire AGP.
91 * \return zero on success or a negative number on failure.
92 *
93 * Verifies the AGP device hasn't been acquired before and calls
94 * \c agp_backend_acquire.
95 */
96int drm_agp_acquire(struct drm_device * dev)
97{
98 if (!dev->agp)
99 return -ENODEV;
100 if (dev->agp->acquired)
101 return -EBUSY;
102 if (!(dev->agp->bridge = agp_backend_acquire(dev->pdev)))
103 return -ENODEV;
104 dev->agp->acquired = 1;
105 return 0;
106}
107
108EXPORT_SYMBOL(drm_agp_acquire);
109
110/**
111 * Acquire the AGP device (ioctl).
112 *
113 * \param inode device inode.
114 * \param file_priv DRM file private.
115 * \param cmd command.
116 * \param arg user argument.
117 * \return zero on success or a negative number on failure.
118 *
119 * Verifies the AGP device hasn't been acquired before and calls
120 * \c agp_backend_acquire.
121 */
122int drm_agp_acquire_ioctl(struct drm_device *dev, void *data,
123 struct drm_file *file_priv)
124{
125 return drm_agp_acquire((struct drm_device *) file_priv->minor->dev);
126}
127
128/**
129 * Release the AGP device.
130 *
131 * \param dev DRM device that is to release AGP.
132 * \return zero on success or a negative number on failure.
133 *
134 * Verifies the AGP device has been acquired and calls \c agp_backend_release.
135 */
136int drm_agp_release(struct drm_device * dev)
137{
138 if (!dev->agp || !dev->agp->acquired)
139 return -EINVAL;
140 agp_backend_release(dev->agp->bridge);
141 dev->agp->acquired = 0;
142 return 0;
143}
144EXPORT_SYMBOL(drm_agp_release);
145
146int drm_agp_release_ioctl(struct drm_device *dev, void *data,
147 struct drm_file *file_priv)
148{
149 return drm_agp_release(dev);
150}
151
152/**
153 * Enable the AGP bus.
154 *
155 * \param dev DRM device that has previously acquired AGP.
156 * \param mode Requested AGP mode.
157 * \return zero on success or a negative number on failure.
158 *
159 * Verifies the AGP device has been acquired but not enabled, and calls
160 * \c agp_enable.
161 */
162int drm_agp_enable(struct drm_device * dev, struct drm_agp_mode mode)
163{
164 if (!dev->agp || !dev->agp->acquired)
165 return -EINVAL;
166
167 dev->agp->mode = mode.mode;
168 agp_enable(dev->agp->bridge, mode.mode);
169 dev->agp->enabled = 1;
170 return 0;
171}
172
173EXPORT_SYMBOL(drm_agp_enable);
174
175int drm_agp_enable_ioctl(struct drm_device *dev, void *data,
176 struct drm_file *file_priv)
177{
178 struct drm_agp_mode *mode = data;
179
180 return drm_agp_enable(dev, *mode);
181}
182
183/**
184 * Allocate AGP memory.
185 *
186 * \param inode device inode.
187 * \param file_priv file private pointer.
188 * \param cmd command.
189 * \param arg pointer to a drm_agp_buffer structure.
190 * \return zero on success or a negative number on failure.
191 *
192 * Verifies the AGP device is present and has been acquired, allocates the
193 * memory via alloc_agp() and creates a drm_agp_mem entry for it.
194 */
195int drm_agp_alloc(struct drm_device *dev, struct drm_agp_buffer *request)
196{
197 struct drm_agp_mem *entry;
198 DRM_AGP_MEM *memory;
199 unsigned long pages;
200 u32 type;
201
202 if (!dev->agp || !dev->agp->acquired)
203 return -EINVAL;
204 if (!(entry = drm_alloc(sizeof(*entry), DRM_MEM_AGPLISTS)))
205 return -ENOMEM;
206
207 memset(entry, 0, sizeof(*entry));
208
209 pages = (request->size + PAGE_SIZE - 1) / PAGE_SIZE;
210 type = (u32) request->type;
211 if (!(memory = drm_alloc_agp(dev, pages, type))) {
212 drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
213 return -ENOMEM;
214 }
215
216 entry->handle = (unsigned long)memory->key + 1;
217 entry->memory = memory;
218 entry->bound = 0;
219 entry->pages = pages;
220 list_add(&entry->head, &dev->agp->memory);
221
222 request->handle = entry->handle;
223 request->physical = memory->physical;
224
225 return 0;
226}
227EXPORT_SYMBOL(drm_agp_alloc);
228
229
230int drm_agp_alloc_ioctl(struct drm_device *dev, void *data,
231 struct drm_file *file_priv)
232{
233 struct drm_agp_buffer *request = data;
234
235 return drm_agp_alloc(dev, request);
236}
237
238/**
239 * Search for the AGP memory entry associated with a handle.
240 *
241 * \param dev DRM device structure.
242 * \param handle AGP memory handle.
243 * \return pointer to the drm_agp_mem structure associated with \p handle.
244 *
245 * Walks through drm_agp_head::memory until finding a matching handle.
246 */
247static struct drm_agp_mem *drm_agp_lookup_entry(struct drm_device * dev,
248 unsigned long handle)
249{
250 struct drm_agp_mem *entry;
251
252 list_for_each_entry(entry, &dev->agp->memory, head) {
253 if (entry->handle == handle)
254 return entry;
255 }
256 return NULL;
257}
258
259/**
260 * Unbind AGP memory from the GATT (ioctl).
261 *
262 * \param inode device inode.
263 * \param file_priv DRM file private.
264 * \param cmd command.
265 * \param arg pointer to a drm_agp_binding structure.
266 * \return zero on success or a negative number on failure.
267 *
268 * Verifies the AGP device is present and acquired, looks-up the AGP memory
269 * entry and passes it to the unbind_agp() function.
270 */
271int drm_agp_unbind(struct drm_device *dev, struct drm_agp_binding *request)
272{
273 struct drm_agp_mem *entry;
274 int ret;
275
276 if (!dev->agp || !dev->agp->acquired)
277 return -EINVAL;
278 if (!(entry = drm_agp_lookup_entry(dev, request->handle)))
279 return -EINVAL;
280 if (!entry->bound)
281 return -EINVAL;
282 ret = drm_unbind_agp(entry->memory);
283 if (ret == 0)
284 entry->bound = 0;
285 return ret;
286}
287EXPORT_SYMBOL(drm_agp_unbind);
288
289
290int drm_agp_unbind_ioctl(struct drm_device *dev, void *data,
291 struct drm_file *file_priv)
292{
293 struct drm_agp_binding *request = data;
294
295 return drm_agp_unbind(dev, request);
296}
297
298/**
299 * Bind AGP memory into the GATT (ioctl)
300 *
301 * \param inode device inode.
302 * \param file_priv DRM file private.
303 * \param cmd command.
304 * \param arg pointer to a drm_agp_binding structure.
305 * \return zero on success or a negative number on failure.
306 *
307 * Verifies the AGP device is present and has been acquired and that no memory
308 * is currently bound into the GATT. Looks-up the AGP memory entry and passes
309 * it to bind_agp() function.
310 */
311int drm_agp_bind(struct drm_device *dev, struct drm_agp_binding *request)
312{
313 struct drm_agp_mem *entry;
314 int retcode;
315 int page;
316
317 if (!dev->agp || !dev->agp->acquired)
318 return -EINVAL;
319 if (!(entry = drm_agp_lookup_entry(dev, request->handle)))
320 return -EINVAL;
321 if (entry->bound)
322 return -EINVAL;
323 page = (request->offset + PAGE_SIZE - 1) / PAGE_SIZE;
324 if ((retcode = drm_bind_agp(entry->memory, page)))
325 return retcode;
326 entry->bound = dev->agp->base + (page << PAGE_SHIFT);
327 DRM_DEBUG("base = 0x%lx entry->bound = 0x%lx\n",
328 dev->agp->base, entry->bound);
329 return 0;
330}
331EXPORT_SYMBOL(drm_agp_bind);
332
333
334int drm_agp_bind_ioctl(struct drm_device *dev, void *data,
335 struct drm_file *file_priv)
336{
337 struct drm_agp_binding *request = data;
338
339 return drm_agp_bind(dev, request);
340}
341
342/**
343 * Free AGP memory (ioctl).
344 *
345 * \param inode device inode.
346 * \param file_priv DRM file private.
347 * \param cmd command.
348 * \param arg pointer to a drm_agp_buffer structure.
349 * \return zero on success or a negative number on failure.
350 *
351 * Verifies the AGP device is present and has been acquired and looks up the
352 * AGP memory entry. If the memory it's currently bound, unbind it via
353 * unbind_agp(). Frees it via free_agp() as well as the entry itself
354 * and unlinks from the doubly linked list it's inserted in.
355 */
356int drm_agp_free(struct drm_device *dev, struct drm_agp_buffer *request)
357{
358 struct drm_agp_mem *entry;
359
360 if (!dev->agp || !dev->agp->acquired)
361 return -EINVAL;
362 if (!(entry = drm_agp_lookup_entry(dev, request->handle)))
363 return -EINVAL;
364 if (entry->bound)
365 drm_unbind_agp(entry->memory);
366
367 list_del(&entry->head);
368
369 drm_free_agp(entry->memory, entry->pages);
370 drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
371 return 0;
372}
373EXPORT_SYMBOL(drm_agp_free);
374
375
376
377int drm_agp_free_ioctl(struct drm_device *dev, void *data,
378 struct drm_file *file_priv)
379{
380 struct drm_agp_buffer *request = data;
381
382 return drm_agp_free(dev, request);
383}
384
385/**
386 * Initialize the AGP resources.
387 *
388 * \return pointer to a drm_agp_head structure.
389 *
390 * Gets the drm_agp_t structure which is made available by the agpgart module
391 * via the inter_module_* functions. Creates and initializes a drm_agp_head
392 * structure.
393 */
394struct drm_agp_head *drm_agp_init(struct drm_device *dev)
395{
396 struct drm_agp_head *head = NULL;
397
398 if (!(head = drm_alloc(sizeof(*head), DRM_MEM_AGPLISTS)))
399 return NULL;
400 memset((void *)head, 0, sizeof(*head));
401 head->bridge = agp_find_bridge(dev->pdev);
402 if (!head->bridge) {
403 if (!(head->bridge = agp_backend_acquire(dev->pdev))) {
404 drm_free(head, sizeof(*head), DRM_MEM_AGPLISTS);
405 return NULL;
406 }
407 agp_copy_info(head->bridge, &head->agp_info);
408 agp_backend_release(head->bridge);
409 } else {
410 agp_copy_info(head->bridge, &head->agp_info);
411 }
412 if (head->agp_info.chipset == NOT_SUPPORTED) {
413 drm_free(head, sizeof(*head), DRM_MEM_AGPLISTS);
414 return NULL;
415 }
416 INIT_LIST_HEAD(&head->memory);
417 head->cant_use_aperture = head->agp_info.cant_use_aperture;
418 head->page_mask = head->agp_info.page_mask;
419 head->base = head->agp_info.aper_base;
420 return head;
421}
422
423/** Calls agp_allocate_memory() */
424DRM_AGP_MEM *drm_agp_allocate_memory(struct agp_bridge_data * bridge,
425 size_t pages, u32 type)
426{
427 return agp_allocate_memory(bridge, pages, type);
428}
429
430/** Calls agp_free_memory() */
431int drm_agp_free_memory(DRM_AGP_MEM * handle)
432{
433 if (!handle)
434 return 0;
435 agp_free_memory(handle);
436 return 1;
437}
438
439/** Calls agp_bind_memory() */
440int drm_agp_bind_memory(DRM_AGP_MEM * handle, off_t start)
441{
442 if (!handle)
443 return -EINVAL;
444 return agp_bind_memory(handle, start);
445}
446
447/** Calls agp_unbind_memory() */
448int drm_agp_unbind_memory(DRM_AGP_MEM * handle)
449{
450 if (!handle)
451 return -EINVAL;
452 return agp_unbind_memory(handle);
453}
454
455#endif /* __OS_HAS_AGP */
diff --git a/drivers/char/drm/drm_auth.c b/drivers/char/drm/drm_auth.c
deleted file mode 100644
index a73462723d2d..000000000000
--- a/drivers/char/drm/drm_auth.c
+++ /dev/null
@@ -1,190 +0,0 @@
1/**
2 * \file drm_auth.c
3 * IOCTLs for authentication
4 *
5 * \author Rickard E. (Rik) Faith <faith@valinux.com>
6 * \author Gareth Hughes <gareth@valinux.com>
7 */
8
9/*
10 * Created: Tue Feb 2 08:37:54 1999 by faith@valinux.com
11 *
12 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
13 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
14 * All Rights Reserved.
15 *
16 * Permission is hereby granted, free of charge, to any person obtaining a
17 * copy of this software and associated documentation files (the "Software"),
18 * to deal in the Software without restriction, including without limitation
19 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
20 * and/or sell copies of the Software, and to permit persons to whom the
21 * Software is furnished to do so, subject to the following conditions:
22 *
23 * The above copyright notice and this permission notice (including the next
24 * paragraph) shall be included in all copies or substantial portions of the
25 * Software.
26 *
27 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
30 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
31 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
32 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
33 * OTHER DEALINGS IN THE SOFTWARE.
34 */
35
36#include "drmP.h"
37
38/**
39 * Find the file with the given magic number.
40 *
41 * \param dev DRM device.
42 * \param magic magic number.
43 *
44 * Searches in drm_device::magiclist within all files with the same hash key
45 * the one with matching magic number, while holding the drm_device::struct_mutex
46 * lock.
47 */
48static struct drm_file *drm_find_file(struct drm_device * dev, drm_magic_t magic)
49{
50 struct drm_file *retval = NULL;
51 struct drm_magic_entry *pt;
52 struct drm_hash_item *hash;
53
54 mutex_lock(&dev->struct_mutex);
55 if (!drm_ht_find_item(&dev->magiclist, (unsigned long)magic, &hash)) {
56 pt = drm_hash_entry(hash, struct drm_magic_entry, hash_item);
57 retval = pt->priv;
58 }
59 mutex_unlock(&dev->struct_mutex);
60 return retval;
61}
62
63/**
64 * Adds a magic number.
65 *
66 * \param dev DRM device.
67 * \param priv file private data.
68 * \param magic magic number.
69 *
70 * Creates a drm_magic_entry structure and appends to the linked list
71 * associated the magic number hash key in drm_device::magiclist, while holding
72 * the drm_device::struct_mutex lock.
73 */
74static int drm_add_magic(struct drm_device * dev, struct drm_file * priv,
75 drm_magic_t magic)
76{
77 struct drm_magic_entry *entry;
78
79 DRM_DEBUG("%d\n", magic);
80
81 entry = drm_alloc(sizeof(*entry), DRM_MEM_MAGIC);
82 if (!entry)
83 return -ENOMEM;
84 memset(entry, 0, sizeof(*entry));
85 entry->priv = priv;
86
87 entry->hash_item.key = (unsigned long)magic;
88 mutex_lock(&dev->struct_mutex);
89 drm_ht_insert_item(&dev->magiclist, &entry->hash_item);
90 list_add_tail(&entry->head, &dev->magicfree);
91 mutex_unlock(&dev->struct_mutex);
92
93 return 0;
94}
95
96/**
97 * Remove a magic number.
98 *
99 * \param dev DRM device.
100 * \param magic magic number.
101 *
102 * Searches and unlinks the entry in drm_device::magiclist with the magic
103 * number hash key, while holding the drm_device::struct_mutex lock.
104 */
105static int drm_remove_magic(struct drm_device * dev, drm_magic_t magic)
106{
107 struct drm_magic_entry *pt;
108 struct drm_hash_item *hash;
109
110 DRM_DEBUG("%d\n", magic);
111
112 mutex_lock(&dev->struct_mutex);
113 if (drm_ht_find_item(&dev->magiclist, (unsigned long)magic, &hash)) {
114 mutex_unlock(&dev->struct_mutex);
115 return -EINVAL;
116 }
117 pt = drm_hash_entry(hash, struct drm_magic_entry, hash_item);
118 drm_ht_remove_item(&dev->magiclist, hash);
119 list_del(&pt->head);
120 mutex_unlock(&dev->struct_mutex);
121
122 drm_free(pt, sizeof(*pt), DRM_MEM_MAGIC);
123
124 return 0;
125}
126
127/**
128 * Get a unique magic number (ioctl).
129 *
130 * \param inode device inode.
131 * \param file_priv DRM file private.
132 * \param cmd command.
133 * \param arg pointer to a resulting drm_auth structure.
134 * \return zero on success, or a negative number on failure.
135 *
136 * If there is a magic number in drm_file::magic then use it, otherwise
137 * searches an unique non-zero magic number and add it associating it with \p
138 * file_priv.
139 */
140int drm_getmagic(struct drm_device *dev, void *data, struct drm_file *file_priv)
141{
142 static drm_magic_t sequence = 0;
143 static DEFINE_SPINLOCK(lock);
144 struct drm_auth *auth = data;
145
146 /* Find unique magic */
147 if (file_priv->magic) {
148 auth->magic = file_priv->magic;
149 } else {
150 do {
151 spin_lock(&lock);
152 if (!sequence)
153 ++sequence; /* reserve 0 */
154 auth->magic = sequence++;
155 spin_unlock(&lock);
156 } while (drm_find_file(dev, auth->magic));
157 file_priv->magic = auth->magic;
158 drm_add_magic(dev, file_priv, auth->magic);
159 }
160
161 DRM_DEBUG("%u\n", auth->magic);
162
163 return 0;
164}
165
166/**
167 * Authenticate with a magic.
168 *
169 * \param inode device inode.
170 * \param file_priv DRM file private.
171 * \param cmd command.
172 * \param arg pointer to a drm_auth structure.
173 * \return zero if authentication successed, or a negative number otherwise.
174 *
175 * Checks if \p file_priv is associated with the magic number passed in \arg.
176 */
177int drm_authmagic(struct drm_device *dev, void *data,
178 struct drm_file *file_priv)
179{
180 struct drm_auth *auth = data;
181 struct drm_file *file;
182
183 DRM_DEBUG("%u\n", auth->magic);
184 if ((file = drm_find_file(dev, auth->magic))) {
185 file->authenticated = 1;
186 drm_remove_magic(dev, auth->magic);
187 return 0;
188 }
189 return -EINVAL;
190}
diff --git a/drivers/char/drm/drm_bufs.c b/drivers/char/drm/drm_bufs.c
deleted file mode 100644
index bde64b84166e..000000000000
--- a/drivers/char/drm/drm_bufs.c
+++ /dev/null
@@ -1,1601 +0,0 @@
1/**
2 * \file drm_bufs.c
3 * Generic buffer template
4 *
5 * \author Rickard E. (Rik) Faith <faith@valinux.com>
6 * \author Gareth Hughes <gareth@valinux.com>
7 */
8
9/*
10 * Created: Thu Nov 23 03:10:50 2000 by gareth@valinux.com
11 *
12 * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
13 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
14 * All Rights Reserved.
15 *
16 * Permission is hereby granted, free of charge, to any person obtaining a
17 * copy of this software and associated documentation files (the "Software"),
18 * to deal in the Software without restriction, including without limitation
19 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
20 * and/or sell copies of the Software, and to permit persons to whom the
21 * Software is furnished to do so, subject to the following conditions:
22 *
23 * The above copyright notice and this permission notice (including the next
24 * paragraph) shall be included in all copies or substantial portions of the
25 * Software.
26 *
27 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
30 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
31 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
32 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
33 * OTHER DEALINGS IN THE SOFTWARE.
34 */
35
36#include <linux/vmalloc.h>
37#include "drmP.h"
38
39unsigned long drm_get_resource_start(struct drm_device *dev, unsigned int resource)
40{
41 return pci_resource_start(dev->pdev, resource);
42}
43EXPORT_SYMBOL(drm_get_resource_start);
44
45unsigned long drm_get_resource_len(struct drm_device *dev, unsigned int resource)
46{
47 return pci_resource_len(dev->pdev, resource);
48}
49
50EXPORT_SYMBOL(drm_get_resource_len);
51
52static struct drm_map_list *drm_find_matching_map(struct drm_device *dev,
53 drm_local_map_t *map)
54{
55 struct drm_map_list *entry;
56 list_for_each_entry(entry, &dev->maplist, head) {
57 if (entry->map && map->type == entry->map->type &&
58 ((entry->map->offset == map->offset) ||
59 (map->type == _DRM_SHM && map->flags==_DRM_CONTAINS_LOCK))) {
60 return entry;
61 }
62 }
63
64 return NULL;
65}
66
67static int drm_map_handle(struct drm_device *dev, struct drm_hash_item *hash,
68 unsigned long user_token, int hashed_handle)
69{
70 int use_hashed_handle;
71#if (BITS_PER_LONG == 64)
72 use_hashed_handle = ((user_token & 0xFFFFFFFF00000000UL) || hashed_handle);
73#elif (BITS_PER_LONG == 32)
74 use_hashed_handle = hashed_handle;
75#else
76#error Unsupported long size. Neither 64 nor 32 bits.
77#endif
78
79 if (!use_hashed_handle) {
80 int ret;
81 hash->key = user_token >> PAGE_SHIFT;
82 ret = drm_ht_insert_item(&dev->map_hash, hash);
83 if (ret != -EINVAL)
84 return ret;
85 }
86 return drm_ht_just_insert_please(&dev->map_hash, hash,
87 user_token, 32 - PAGE_SHIFT - 3,
88 0, DRM_MAP_HASH_OFFSET >> PAGE_SHIFT);
89}
90
91/**
92 * Ioctl to specify a range of memory that is available for mapping by a non-root process.
93 *
94 * \param inode device inode.
95 * \param file_priv DRM file private.
96 * \param cmd command.
97 * \param arg pointer to a drm_map structure.
98 * \return zero on success or a negative value on error.
99 *
100 * Adjusts the memory offset to its absolute value according to the mapping
101 * type. Adds the map to the map list drm_device::maplist. Adds MTRR's where
102 * applicable and if supported by the kernel.
103 */
104static int drm_addmap_core(struct drm_device * dev, unsigned int offset,
105 unsigned int size, enum drm_map_type type,
106 enum drm_map_flags flags,
107 struct drm_map_list ** maplist)
108{
109 struct drm_map *map;
110 struct drm_map_list *list;
111 drm_dma_handle_t *dmah;
112 unsigned long user_token;
113 int ret;
114
115 map = drm_alloc(sizeof(*map), DRM_MEM_MAPS);
116 if (!map)
117 return -ENOMEM;
118
119 map->offset = offset;
120 map->size = size;
121 map->flags = flags;
122 map->type = type;
123
124 /* Only allow shared memory to be removable since we only keep enough
125 * book keeping information about shared memory to allow for removal
126 * when processes fork.
127 */
128 if ((map->flags & _DRM_REMOVABLE) && map->type != _DRM_SHM) {
129 drm_free(map, sizeof(*map), DRM_MEM_MAPS);
130 return -EINVAL;
131 }
132 DRM_DEBUG("offset = 0x%08lx, size = 0x%08lx, type = %d\n",
133 map->offset, map->size, map->type);
134 if ((map->offset & (~PAGE_MASK)) || (map->size & (~PAGE_MASK))) {
135 drm_free(map, sizeof(*map), DRM_MEM_MAPS);
136 return -EINVAL;
137 }
138 map->mtrr = -1;
139 map->handle = NULL;
140
141 switch (map->type) {
142 case _DRM_REGISTERS:
143 case _DRM_FRAME_BUFFER:
144#if !defined(__sparc__) && !defined(__alpha__) && !defined(__ia64__) && !defined(__powerpc64__) && !defined(__x86_64__)
145 if (map->offset + (map->size-1) < map->offset ||
146 map->offset < virt_to_phys(high_memory)) {
147 drm_free(map, sizeof(*map), DRM_MEM_MAPS);
148 return -EINVAL;
149 }
150#endif
151#ifdef __alpha__
152 map->offset += dev->hose->mem_space->start;
153#endif
154 /* Some drivers preinitialize some maps, without the X Server
155 * needing to be aware of it. Therefore, we just return success
156 * when the server tries to create a duplicate map.
157 */
158 list = drm_find_matching_map(dev, map);
159 if (list != NULL) {
160 if (list->map->size != map->size) {
161 DRM_DEBUG("Matching maps of type %d with "
162 "mismatched sizes, (%ld vs %ld)\n",
163 map->type, map->size,
164 list->map->size);
165 list->map->size = map->size;
166 }
167
168 drm_free(map, sizeof(*map), DRM_MEM_MAPS);
169 *maplist = list;
170 return 0;
171 }
172
173 if (drm_core_has_MTRR(dev)) {
174 if (map->type == _DRM_FRAME_BUFFER ||
175 (map->flags & _DRM_WRITE_COMBINING)) {
176 map->mtrr = mtrr_add(map->offset, map->size,
177 MTRR_TYPE_WRCOMB, 1);
178 }
179 }
180 if (map->type == _DRM_REGISTERS) {
181 map->handle = ioremap(map->offset, map->size);
182 if (!map->handle) {
183 drm_free(map, sizeof(*map), DRM_MEM_MAPS);
184 return -ENOMEM;
185 }
186 }
187
188 break;
189 case _DRM_SHM:
190 list = drm_find_matching_map(dev, map);
191 if (list != NULL) {
192 if(list->map->size != map->size) {
193 DRM_DEBUG("Matching maps of type %d with "
194 "mismatched sizes, (%ld vs %ld)\n",
195 map->type, map->size, list->map->size);
196 list->map->size = map->size;
197 }
198
199 drm_free(map, sizeof(*map), DRM_MEM_MAPS);
200 *maplist = list;
201 return 0;
202 }
203 map->handle = vmalloc_user(map->size);
204 DRM_DEBUG("%lu %d %p\n",
205 map->size, drm_order(map->size), map->handle);
206 if (!map->handle) {
207 drm_free(map, sizeof(*map), DRM_MEM_MAPS);
208 return -ENOMEM;
209 }
210 map->offset = (unsigned long)map->handle;
211 if (map->flags & _DRM_CONTAINS_LOCK) {
212 /* Prevent a 2nd X Server from creating a 2nd lock */
213 if (dev->lock.hw_lock != NULL) {
214 vfree(map->handle);
215 drm_free(map, sizeof(*map), DRM_MEM_MAPS);
216 return -EBUSY;
217 }
218 dev->sigdata.lock = dev->lock.hw_lock = map->handle; /* Pointer to lock */
219 }
220 break;
221 case _DRM_AGP: {
222 struct drm_agp_mem *entry;
223 int valid = 0;
224
225 if (!drm_core_has_AGP(dev)) {
226 drm_free(map, sizeof(*map), DRM_MEM_MAPS);
227 return -EINVAL;
228 }
229#ifdef __alpha__
230 map->offset += dev->hose->mem_space->start;
231#endif
232 /* In some cases (i810 driver), user space may have already
233 * added the AGP base itself, because dev->agp->base previously
234 * only got set during AGP enable. So, only add the base
235 * address if the map's offset isn't already within the
236 * aperture.
237 */
238 if (map->offset < dev->agp->base ||
239 map->offset > dev->agp->base +
240 dev->agp->agp_info.aper_size * 1024 * 1024 - 1) {
241 map->offset += dev->agp->base;
242 }
243 map->mtrr = dev->agp->agp_mtrr; /* for getmap */
244
245 /* This assumes the DRM is in total control of AGP space.
246 * It's not always the case as AGP can be in the control
247 * of user space (i.e. i810 driver). So this loop will get
248 * skipped and we double check that dev->agp->memory is
249 * actually set as well as being invalid before EPERM'ing
250 */
251 list_for_each_entry(entry, &dev->agp->memory, head) {
252 if ((map->offset >= entry->bound) &&
253 (map->offset + map->size <= entry->bound + entry->pages * PAGE_SIZE)) {
254 valid = 1;
255 break;
256 }
257 }
258 if (!list_empty(&dev->agp->memory) && !valid) {
259 drm_free(map, sizeof(*map), DRM_MEM_MAPS);
260 return -EPERM;
261 }
262 DRM_DEBUG("AGP offset = 0x%08lx, size = 0x%08lx\n", map->offset, map->size);
263
264 break;
265 }
266 case _DRM_SCATTER_GATHER:
267 if (!dev->sg) {
268 drm_free(map, sizeof(*map), DRM_MEM_MAPS);
269 return -EINVAL;
270 }
271 map->offset += (unsigned long)dev->sg->virtual;
272 break;
273 case _DRM_CONSISTENT:
274 /* dma_addr_t is 64bit on i386 with CONFIG_HIGHMEM64G,
275 * As we're limiting the address to 2^32-1 (or less),
276 * casting it down to 32 bits is no problem, but we
277 * need to point to a 64bit variable first. */
278 dmah = drm_pci_alloc(dev, map->size, map->size, 0xffffffffUL);
279 if (!dmah) {
280 drm_free(map, sizeof(*map), DRM_MEM_MAPS);
281 return -ENOMEM;
282 }
283 map->handle = dmah->vaddr;
284 map->offset = (unsigned long)dmah->busaddr;
285 kfree(dmah);
286 break;
287 default:
288 drm_free(map, sizeof(*map), DRM_MEM_MAPS);
289 return -EINVAL;
290 }
291
292 list = drm_alloc(sizeof(*list), DRM_MEM_MAPS);
293 if (!list) {
294 if (map->type == _DRM_REGISTERS)
295 iounmap(map->handle);
296 drm_free(map, sizeof(*map), DRM_MEM_MAPS);
297 return -EINVAL;
298 }
299 memset(list, 0, sizeof(*list));
300 list->map = map;
301
302 mutex_lock(&dev->struct_mutex);
303 list_add(&list->head, &dev->maplist);
304
305 /* Assign a 32-bit handle */
306 /* We do it here so that dev->struct_mutex protects the increment */
307 user_token = (map->type == _DRM_SHM) ? (unsigned long)map->handle :
308 map->offset;
309 ret = drm_map_handle(dev, &list->hash, user_token, 0);
310 if (ret) {
311 if (map->type == _DRM_REGISTERS)
312 iounmap(map->handle);
313 drm_free(map, sizeof(*map), DRM_MEM_MAPS);
314 drm_free(list, sizeof(*list), DRM_MEM_MAPS);
315 mutex_unlock(&dev->struct_mutex);
316 return ret;
317 }
318
319 list->user_token = list->hash.key << PAGE_SHIFT;
320 mutex_unlock(&dev->struct_mutex);
321
322 *maplist = list;
323 return 0;
324 }
325
326int drm_addmap(struct drm_device * dev, unsigned int offset,
327 unsigned int size, enum drm_map_type type,
328 enum drm_map_flags flags, drm_local_map_t ** map_ptr)
329{
330 struct drm_map_list *list;
331 int rc;
332
333 rc = drm_addmap_core(dev, offset, size, type, flags, &list);
334 if (!rc)
335 *map_ptr = list->map;
336 return rc;
337}
338
339EXPORT_SYMBOL(drm_addmap);
340
341int drm_addmap_ioctl(struct drm_device *dev, void *data,
342 struct drm_file *file_priv)
343{
344 struct drm_map *map = data;
345 struct drm_map_list *maplist;
346 int err;
347
348 if (!(capable(CAP_SYS_ADMIN) || map->type == _DRM_AGP))
349 return -EPERM;
350
351 err = drm_addmap_core(dev, map->offset, map->size, map->type,
352 map->flags, &maplist);
353
354 if (err)
355 return err;
356
357 /* avoid a warning on 64-bit, this casting isn't very nice, but the API is set so too late */
358 map->handle = (void *)(unsigned long)maplist->user_token;
359 return 0;
360}
361
362/**
363 * Remove a map private from list and deallocate resources if the mapping
364 * isn't in use.
365 *
366 * \param inode device inode.
367 * \param file_priv DRM file private.
368 * \param cmd command.
369 * \param arg pointer to a struct drm_map structure.
370 * \return zero on success or a negative value on error.
371 *
372 * Searches the map on drm_device::maplist, removes it from the list, see if
373 * its being used, and free any associate resource (such as MTRR's) if it's not
374 * being on use.
375 *
376 * \sa drm_addmap
377 */
378int drm_rmmap_locked(struct drm_device *dev, drm_local_map_t *map)
379{
380 struct drm_map_list *r_list = NULL, *list_t;
381 drm_dma_handle_t dmah;
382 int found = 0;
383
384 /* Find the list entry for the map and remove it */
385 list_for_each_entry_safe(r_list, list_t, &dev->maplist, head) {
386 if (r_list->map == map) {
387 list_del(&r_list->head);
388 drm_ht_remove_key(&dev->map_hash,
389 r_list->user_token >> PAGE_SHIFT);
390 drm_free(r_list, sizeof(*r_list), DRM_MEM_MAPS);
391 found = 1;
392 break;
393 }
394 }
395
396 if (!found)
397 return -EINVAL;
398
399 switch (map->type) {
400 case _DRM_REGISTERS:
401 iounmap(map->handle);
402 /* FALLTHROUGH */
403 case _DRM_FRAME_BUFFER:
404 if (drm_core_has_MTRR(dev) && map->mtrr >= 0) {
405 int retcode;
406 retcode = mtrr_del(map->mtrr, map->offset, map->size);
407 DRM_DEBUG("mtrr_del=%d\n", retcode);
408 }
409 break;
410 case _DRM_SHM:
411 vfree(map->handle);
412 break;
413 case _DRM_AGP:
414 case _DRM_SCATTER_GATHER:
415 break;
416 case _DRM_CONSISTENT:
417 dmah.vaddr = map->handle;
418 dmah.busaddr = map->offset;
419 dmah.size = map->size;
420 __drm_pci_free(dev, &dmah);
421 break;
422 }
423 drm_free(map, sizeof(*map), DRM_MEM_MAPS);
424
425 return 0;
426}
427
428int drm_rmmap(struct drm_device *dev, drm_local_map_t *map)
429{
430 int ret;
431
432 mutex_lock(&dev->struct_mutex);
433 ret = drm_rmmap_locked(dev, map);
434 mutex_unlock(&dev->struct_mutex);
435
436 return ret;
437}
438EXPORT_SYMBOL(drm_rmmap);
439
440/* The rmmap ioctl appears to be unnecessary. All mappings are torn down on
441 * the last close of the device, and this is necessary for cleanup when things
442 * exit uncleanly. Therefore, having userland manually remove mappings seems
443 * like a pointless exercise since they're going away anyway.
444 *
445 * One use case might be after addmap is allowed for normal users for SHM and
446 * gets used by drivers that the server doesn't need to care about. This seems
447 * unlikely.
448 */
449int drm_rmmap_ioctl(struct drm_device *dev, void *data,
450 struct drm_file *file_priv)
451{
452 struct drm_map *request = data;
453 drm_local_map_t *map = NULL;
454 struct drm_map_list *r_list;
455 int ret;
456
457 mutex_lock(&dev->struct_mutex);
458 list_for_each_entry(r_list, &dev->maplist, head) {
459 if (r_list->map &&
460 r_list->user_token == (unsigned long)request->handle &&
461 r_list->map->flags & _DRM_REMOVABLE) {
462 map = r_list->map;
463 break;
464 }
465 }
466
467 /* List has wrapped around to the head pointer, or its empty we didn't
468 * find anything.
469 */
470 if (list_empty(&dev->maplist) || !map) {
471 mutex_unlock(&dev->struct_mutex);
472 return -EINVAL;
473 }
474
475 /* Register and framebuffer maps are permanent */
476 if ((map->type == _DRM_REGISTERS) || (map->type == _DRM_FRAME_BUFFER)) {
477 mutex_unlock(&dev->struct_mutex);
478 return 0;
479 }
480
481 ret = drm_rmmap_locked(dev, map);
482
483 mutex_unlock(&dev->struct_mutex);
484
485 return ret;
486}
487
488/**
489 * Cleanup after an error on one of the addbufs() functions.
490 *
491 * \param dev DRM device.
492 * \param entry buffer entry where the error occurred.
493 *
494 * Frees any pages and buffers associated with the given entry.
495 */
496static void drm_cleanup_buf_error(struct drm_device * dev,
497 struct drm_buf_entry * entry)
498{
499 int i;
500
501 if (entry->seg_count) {
502 for (i = 0; i < entry->seg_count; i++) {
503 if (entry->seglist[i]) {
504 drm_pci_free(dev, entry->seglist[i]);
505 }
506 }
507 drm_free(entry->seglist,
508 entry->seg_count *
509 sizeof(*entry->seglist), DRM_MEM_SEGS);
510
511 entry->seg_count = 0;
512 }
513
514 if (entry->buf_count) {
515 for (i = 0; i < entry->buf_count; i++) {
516 if (entry->buflist[i].dev_private) {
517 drm_free(entry->buflist[i].dev_private,
518 entry->buflist[i].dev_priv_size,
519 DRM_MEM_BUFS);
520 }
521 }
522 drm_free(entry->buflist,
523 entry->buf_count *
524 sizeof(*entry->buflist), DRM_MEM_BUFS);
525
526 entry->buf_count = 0;
527 }
528}
529
530#if __OS_HAS_AGP
531/**
532 * Add AGP buffers for DMA transfers.
533 *
534 * \param dev struct drm_device to which the buffers are to be added.
535 * \param request pointer to a struct drm_buf_desc describing the request.
536 * \return zero on success or a negative number on failure.
537 *
538 * After some sanity checks creates a drm_buf structure for each buffer and
539 * reallocates the buffer list of the same size order to accommodate the new
540 * buffers.
541 */
542int drm_addbufs_agp(struct drm_device * dev, struct drm_buf_desc * request)
543{
544 struct drm_device_dma *dma = dev->dma;
545 struct drm_buf_entry *entry;
546 struct drm_agp_mem *agp_entry;
547 struct drm_buf *buf;
548 unsigned long offset;
549 unsigned long agp_offset;
550 int count;
551 int order;
552 int size;
553 int alignment;
554 int page_order;
555 int total;
556 int byte_count;
557 int i, valid;
558 struct drm_buf **temp_buflist;
559
560 if (!dma)
561 return -EINVAL;
562
563 count = request->count;
564 order = drm_order(request->size);
565 size = 1 << order;
566
567 alignment = (request->flags & _DRM_PAGE_ALIGN)
568 ? PAGE_ALIGN(size) : size;
569 page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0;
570 total = PAGE_SIZE << page_order;
571
572 byte_count = 0;
573 agp_offset = dev->agp->base + request->agp_start;
574
575 DRM_DEBUG("count: %d\n", count);
576 DRM_DEBUG("order: %d\n", order);
577 DRM_DEBUG("size: %d\n", size);
578 DRM_DEBUG("agp_offset: %lx\n", agp_offset);
579 DRM_DEBUG("alignment: %d\n", alignment);
580 DRM_DEBUG("page_order: %d\n", page_order);
581 DRM_DEBUG("total: %d\n", total);
582
583 if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER)
584 return -EINVAL;
585 if (dev->queue_count)
586 return -EBUSY; /* Not while in use */
587
588 /* Make sure buffers are located in AGP memory that we own */
589 valid = 0;
590 list_for_each_entry(agp_entry, &dev->agp->memory, head) {
591 if ((agp_offset >= agp_entry->bound) &&
592 (agp_offset + total * count <= agp_entry->bound + agp_entry->pages * PAGE_SIZE)) {
593 valid = 1;
594 break;
595 }
596 }
597 if (!list_empty(&dev->agp->memory) && !valid) {
598 DRM_DEBUG("zone invalid\n");
599 return -EINVAL;
600 }
601 spin_lock(&dev->count_lock);
602 if (dev->buf_use) {
603 spin_unlock(&dev->count_lock);
604 return -EBUSY;
605 }
606 atomic_inc(&dev->buf_alloc);
607 spin_unlock(&dev->count_lock);
608
609 mutex_lock(&dev->struct_mutex);
610 entry = &dma->bufs[order];
611 if (entry->buf_count) {
612 mutex_unlock(&dev->struct_mutex);
613 atomic_dec(&dev->buf_alloc);
614 return -ENOMEM; /* May only call once for each order */
615 }
616
617 if (count < 0 || count > 4096) {
618 mutex_unlock(&dev->struct_mutex);
619 atomic_dec(&dev->buf_alloc);
620 return -EINVAL;
621 }
622
623 entry->buflist = drm_alloc(count * sizeof(*entry->buflist),
624 DRM_MEM_BUFS);
625 if (!entry->buflist) {
626 mutex_unlock(&dev->struct_mutex);
627 atomic_dec(&dev->buf_alloc);
628 return -ENOMEM;
629 }
630 memset(entry->buflist, 0, count * sizeof(*entry->buflist));
631
632 entry->buf_size = size;
633 entry->page_order = page_order;
634
635 offset = 0;
636
637 while (entry->buf_count < count) {
638 buf = &entry->buflist[entry->buf_count];
639 buf->idx = dma->buf_count + entry->buf_count;
640 buf->total = alignment;
641 buf->order = order;
642 buf->used = 0;
643
644 buf->offset = (dma->byte_count + offset);
645 buf->bus_address = agp_offset + offset;
646 buf->address = (void *)(agp_offset + offset);
647 buf->next = NULL;
648 buf->waiting = 0;
649 buf->pending = 0;
650 init_waitqueue_head(&buf->dma_wait);
651 buf->file_priv = NULL;
652
653 buf->dev_priv_size = dev->driver->dev_priv_size;
654 buf->dev_private = drm_alloc(buf->dev_priv_size, DRM_MEM_BUFS);
655 if (!buf->dev_private) {
656 /* Set count correctly so we free the proper amount. */
657 entry->buf_count = count;
658 drm_cleanup_buf_error(dev, entry);
659 mutex_unlock(&dev->struct_mutex);
660 atomic_dec(&dev->buf_alloc);
661 return -ENOMEM;
662 }
663 memset(buf->dev_private, 0, buf->dev_priv_size);
664
665 DRM_DEBUG("buffer %d @ %p\n", entry->buf_count, buf->address);
666
667 offset += alignment;
668 entry->buf_count++;
669 byte_count += PAGE_SIZE << page_order;
670 }
671
672 DRM_DEBUG("byte_count: %d\n", byte_count);
673
674 temp_buflist = drm_realloc(dma->buflist,
675 dma->buf_count * sizeof(*dma->buflist),
676 (dma->buf_count + entry->buf_count)
677 * sizeof(*dma->buflist), DRM_MEM_BUFS);
678 if (!temp_buflist) {
679 /* Free the entry because it isn't valid */
680 drm_cleanup_buf_error(dev, entry);
681 mutex_unlock(&dev->struct_mutex);
682 atomic_dec(&dev->buf_alloc);
683 return -ENOMEM;
684 }
685 dma->buflist = temp_buflist;
686
687 for (i = 0; i < entry->buf_count; i++) {
688 dma->buflist[i + dma->buf_count] = &entry->buflist[i];
689 }
690
691 dma->buf_count += entry->buf_count;
692 dma->seg_count += entry->seg_count;
693 dma->page_count += byte_count >> PAGE_SHIFT;
694 dma->byte_count += byte_count;
695
696 DRM_DEBUG("dma->buf_count : %d\n", dma->buf_count);
697 DRM_DEBUG("entry->buf_count : %d\n", entry->buf_count);
698
699 mutex_unlock(&dev->struct_mutex);
700
701 request->count = entry->buf_count;
702 request->size = size;
703
704 dma->flags = _DRM_DMA_USE_AGP;
705
706 atomic_dec(&dev->buf_alloc);
707 return 0;
708}
709EXPORT_SYMBOL(drm_addbufs_agp);
710#endif /* __OS_HAS_AGP */
711
712int drm_addbufs_pci(struct drm_device * dev, struct drm_buf_desc * request)
713{
714 struct drm_device_dma *dma = dev->dma;
715 int count;
716 int order;
717 int size;
718 int total;
719 int page_order;
720 struct drm_buf_entry *entry;
721 drm_dma_handle_t *dmah;
722 struct drm_buf *buf;
723 int alignment;
724 unsigned long offset;
725 int i;
726 int byte_count;
727 int page_count;
728 unsigned long *temp_pagelist;
729 struct drm_buf **temp_buflist;
730
731 if (!drm_core_check_feature(dev, DRIVER_PCI_DMA))
732 return -EINVAL;
733
734 if (!dma)
735 return -EINVAL;
736
737 if (!capable(CAP_SYS_ADMIN))
738 return -EPERM;
739
740 count = request->count;
741 order = drm_order(request->size);
742 size = 1 << order;
743
744 DRM_DEBUG("count=%d, size=%d (%d), order=%d, queue_count=%d\n",
745 request->count, request->size, size, order, dev->queue_count);
746
747 if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER)
748 return -EINVAL;
749 if (dev->queue_count)
750 return -EBUSY; /* Not while in use */
751
752 alignment = (request->flags & _DRM_PAGE_ALIGN)
753 ? PAGE_ALIGN(size) : size;
754 page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0;
755 total = PAGE_SIZE << page_order;
756
757 spin_lock(&dev->count_lock);
758 if (dev->buf_use) {
759 spin_unlock(&dev->count_lock);
760 return -EBUSY;
761 }
762 atomic_inc(&dev->buf_alloc);
763 spin_unlock(&dev->count_lock);
764
765 mutex_lock(&dev->struct_mutex);
766 entry = &dma->bufs[order];
767 if (entry->buf_count) {
768 mutex_unlock(&dev->struct_mutex);
769 atomic_dec(&dev->buf_alloc);
770 return -ENOMEM; /* May only call once for each order */
771 }
772
773 if (count < 0 || count > 4096) {
774 mutex_unlock(&dev->struct_mutex);
775 atomic_dec(&dev->buf_alloc);
776 return -EINVAL;
777 }
778
779 entry->buflist = drm_alloc(count * sizeof(*entry->buflist),
780 DRM_MEM_BUFS);
781 if (!entry->buflist) {
782 mutex_unlock(&dev->struct_mutex);
783 atomic_dec(&dev->buf_alloc);
784 return -ENOMEM;
785 }
786 memset(entry->buflist, 0, count * sizeof(*entry->buflist));
787
788 entry->seglist = drm_alloc(count * sizeof(*entry->seglist),
789 DRM_MEM_SEGS);
790 if (!entry->seglist) {
791 drm_free(entry->buflist,
792 count * sizeof(*entry->buflist), DRM_MEM_BUFS);
793 mutex_unlock(&dev->struct_mutex);
794 atomic_dec(&dev->buf_alloc);
795 return -ENOMEM;
796 }
797 memset(entry->seglist, 0, count * sizeof(*entry->seglist));
798
799 /* Keep the original pagelist until we know all the allocations
800 * have succeeded
801 */
802 temp_pagelist = drm_alloc((dma->page_count + (count << page_order))
803 * sizeof(*dma->pagelist), DRM_MEM_PAGES);
804 if (!temp_pagelist) {
805 drm_free(entry->buflist,
806 count * sizeof(*entry->buflist), DRM_MEM_BUFS);
807 drm_free(entry->seglist,
808 count * sizeof(*entry->seglist), DRM_MEM_SEGS);
809 mutex_unlock(&dev->struct_mutex);
810 atomic_dec(&dev->buf_alloc);
811 return -ENOMEM;
812 }
813 memcpy(temp_pagelist,
814 dma->pagelist, dma->page_count * sizeof(*dma->pagelist));
815 DRM_DEBUG("pagelist: %d entries\n",
816 dma->page_count + (count << page_order));
817
818 entry->buf_size = size;
819 entry->page_order = page_order;
820 byte_count = 0;
821 page_count = 0;
822
823 while (entry->buf_count < count) {
824
825 dmah = drm_pci_alloc(dev, PAGE_SIZE << page_order, 0x1000, 0xfffffffful);
826
827 if (!dmah) {
828 /* Set count correctly so we free the proper amount. */
829 entry->buf_count = count;
830 entry->seg_count = count;
831 drm_cleanup_buf_error(dev, entry);
832 drm_free(temp_pagelist,
833 (dma->page_count + (count << page_order))
834 * sizeof(*dma->pagelist), DRM_MEM_PAGES);
835 mutex_unlock(&dev->struct_mutex);
836 atomic_dec(&dev->buf_alloc);
837 return -ENOMEM;
838 }
839 entry->seglist[entry->seg_count++] = dmah;
840 for (i = 0; i < (1 << page_order); i++) {
841 DRM_DEBUG("page %d @ 0x%08lx\n",
842 dma->page_count + page_count,
843 (unsigned long)dmah->vaddr + PAGE_SIZE * i);
844 temp_pagelist[dma->page_count + page_count++]
845 = (unsigned long)dmah->vaddr + PAGE_SIZE * i;
846 }
847 for (offset = 0;
848 offset + size <= total && entry->buf_count < count;
849 offset += alignment, ++entry->buf_count) {
850 buf = &entry->buflist[entry->buf_count];
851 buf->idx = dma->buf_count + entry->buf_count;
852 buf->total = alignment;
853 buf->order = order;
854 buf->used = 0;
855 buf->offset = (dma->byte_count + byte_count + offset);
856 buf->address = (void *)(dmah->vaddr + offset);
857 buf->bus_address = dmah->busaddr + offset;
858 buf->next = NULL;
859 buf->waiting = 0;
860 buf->pending = 0;
861 init_waitqueue_head(&buf->dma_wait);
862 buf->file_priv = NULL;
863
864 buf->dev_priv_size = dev->driver->dev_priv_size;
865 buf->dev_private = drm_alloc(buf->dev_priv_size,
866 DRM_MEM_BUFS);
867 if (!buf->dev_private) {
868 /* Set count correctly so we free the proper amount. */
869 entry->buf_count = count;
870 entry->seg_count = count;
871 drm_cleanup_buf_error(dev, entry);
872 drm_free(temp_pagelist,
873 (dma->page_count +
874 (count << page_order))
875 * sizeof(*dma->pagelist),
876 DRM_MEM_PAGES);
877 mutex_unlock(&dev->struct_mutex);
878 atomic_dec(&dev->buf_alloc);
879 return -ENOMEM;
880 }
881 memset(buf->dev_private, 0, buf->dev_priv_size);
882
883 DRM_DEBUG("buffer %d @ %p\n",
884 entry->buf_count, buf->address);
885 }
886 byte_count += PAGE_SIZE << page_order;
887 }
888
889 temp_buflist = drm_realloc(dma->buflist,
890 dma->buf_count * sizeof(*dma->buflist),
891 (dma->buf_count + entry->buf_count)
892 * sizeof(*dma->buflist), DRM_MEM_BUFS);
893 if (!temp_buflist) {
894 /* Free the entry because it isn't valid */
895 drm_cleanup_buf_error(dev, entry);
896 drm_free(temp_pagelist,
897 (dma->page_count + (count << page_order))
898 * sizeof(*dma->pagelist), DRM_MEM_PAGES);
899 mutex_unlock(&dev->struct_mutex);
900 atomic_dec(&dev->buf_alloc);
901 return -ENOMEM;
902 }
903 dma->buflist = temp_buflist;
904
905 for (i = 0; i < entry->buf_count; i++) {
906 dma->buflist[i + dma->buf_count] = &entry->buflist[i];
907 }
908
909 /* No allocations failed, so now we can replace the orginal pagelist
910 * with the new one.
911 */
912 if (dma->page_count) {
913 drm_free(dma->pagelist,
914 dma->page_count * sizeof(*dma->pagelist),
915 DRM_MEM_PAGES);
916 }
917 dma->pagelist = temp_pagelist;
918
919 dma->buf_count += entry->buf_count;
920 dma->seg_count += entry->seg_count;
921 dma->page_count += entry->seg_count << page_order;
922 dma->byte_count += PAGE_SIZE * (entry->seg_count << page_order);
923
924 mutex_unlock(&dev->struct_mutex);
925
926 request->count = entry->buf_count;
927 request->size = size;
928
929 if (request->flags & _DRM_PCI_BUFFER_RO)
930 dma->flags = _DRM_DMA_USE_PCI_RO;
931
932 atomic_dec(&dev->buf_alloc);
933 return 0;
934
935}
936EXPORT_SYMBOL(drm_addbufs_pci);
937
938static int drm_addbufs_sg(struct drm_device * dev, struct drm_buf_desc * request)
939{
940 struct drm_device_dma *dma = dev->dma;
941 struct drm_buf_entry *entry;
942 struct drm_buf *buf;
943 unsigned long offset;
944 unsigned long agp_offset;
945 int count;
946 int order;
947 int size;
948 int alignment;
949 int page_order;
950 int total;
951 int byte_count;
952 int i;
953 struct drm_buf **temp_buflist;
954
955 if (!drm_core_check_feature(dev, DRIVER_SG))
956 return -EINVAL;
957
958 if (!dma)
959 return -EINVAL;
960
961 if (!capable(CAP_SYS_ADMIN))
962 return -EPERM;
963
964 count = request->count;
965 order = drm_order(request->size);
966 size = 1 << order;
967
968 alignment = (request->flags & _DRM_PAGE_ALIGN)
969 ? PAGE_ALIGN(size) : size;
970 page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0;
971 total = PAGE_SIZE << page_order;
972
973 byte_count = 0;
974 agp_offset = request->agp_start;
975
976 DRM_DEBUG("count: %d\n", count);
977 DRM_DEBUG("order: %d\n", order);
978 DRM_DEBUG("size: %d\n", size);
979 DRM_DEBUG("agp_offset: %lu\n", agp_offset);
980 DRM_DEBUG("alignment: %d\n", alignment);
981 DRM_DEBUG("page_order: %d\n", page_order);
982 DRM_DEBUG("total: %d\n", total);
983
984 if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER)
985 return -EINVAL;
986 if (dev->queue_count)
987 return -EBUSY; /* Not while in use */
988
989 spin_lock(&dev->count_lock);
990 if (dev->buf_use) {
991 spin_unlock(&dev->count_lock);
992 return -EBUSY;
993 }
994 atomic_inc(&dev->buf_alloc);
995 spin_unlock(&dev->count_lock);
996
997 mutex_lock(&dev->struct_mutex);
998 entry = &dma->bufs[order];
999 if (entry->buf_count) {
1000 mutex_unlock(&dev->struct_mutex);
1001 atomic_dec(&dev->buf_alloc);
1002 return -ENOMEM; /* May only call once for each order */
1003 }
1004
1005 if (count < 0 || count > 4096) {
1006 mutex_unlock(&dev->struct_mutex);
1007 atomic_dec(&dev->buf_alloc);
1008 return -EINVAL;
1009 }
1010
1011 entry->buflist = drm_alloc(count * sizeof(*entry->buflist),
1012 DRM_MEM_BUFS);
1013 if (!entry->buflist) {
1014 mutex_unlock(&dev->struct_mutex);
1015 atomic_dec(&dev->buf_alloc);
1016 return -ENOMEM;
1017 }
1018 memset(entry->buflist, 0, count * sizeof(*entry->buflist));
1019
1020 entry->buf_size = size;
1021 entry->page_order = page_order;
1022
1023 offset = 0;
1024
1025 while (entry->buf_count < count) {
1026 buf = &entry->buflist[entry->buf_count];
1027 buf->idx = dma->buf_count + entry->buf_count;
1028 buf->total = alignment;
1029 buf->order = order;
1030 buf->used = 0;
1031
1032 buf->offset = (dma->byte_count + offset);
1033 buf->bus_address = agp_offset + offset;
1034 buf->address = (void *)(agp_offset + offset
1035 + (unsigned long)dev->sg->virtual);
1036 buf->next = NULL;
1037 buf->waiting = 0;
1038 buf->pending = 0;
1039 init_waitqueue_head(&buf->dma_wait);
1040 buf->file_priv = NULL;
1041
1042 buf->dev_priv_size = dev->driver->dev_priv_size;
1043 buf->dev_private = drm_alloc(buf->dev_priv_size, DRM_MEM_BUFS);
1044 if (!buf->dev_private) {
1045 /* Set count correctly so we free the proper amount. */
1046 entry->buf_count = count;
1047 drm_cleanup_buf_error(dev, entry);
1048 mutex_unlock(&dev->struct_mutex);
1049 atomic_dec(&dev->buf_alloc);
1050 return -ENOMEM;
1051 }
1052
1053 memset(buf->dev_private, 0, buf->dev_priv_size);
1054
1055 DRM_DEBUG("buffer %d @ %p\n", entry->buf_count, buf->address);
1056
1057 offset += alignment;
1058 entry->buf_count++;
1059 byte_count += PAGE_SIZE << page_order;
1060 }
1061
1062 DRM_DEBUG("byte_count: %d\n", byte_count);
1063
1064 temp_buflist = drm_realloc(dma->buflist,
1065 dma->buf_count * sizeof(*dma->buflist),
1066 (dma->buf_count + entry->buf_count)
1067 * sizeof(*dma->buflist), DRM_MEM_BUFS);
1068 if (!temp_buflist) {
1069 /* Free the entry because it isn't valid */
1070 drm_cleanup_buf_error(dev, entry);
1071 mutex_unlock(&dev->struct_mutex);
1072 atomic_dec(&dev->buf_alloc);
1073 return -ENOMEM;
1074 }
1075 dma->buflist = temp_buflist;
1076
1077 for (i = 0; i < entry->buf_count; i++) {
1078 dma->buflist[i + dma->buf_count] = &entry->buflist[i];
1079 }
1080
1081 dma->buf_count += entry->buf_count;
1082 dma->seg_count += entry->seg_count;
1083 dma->page_count += byte_count >> PAGE_SHIFT;
1084 dma->byte_count += byte_count;
1085
1086 DRM_DEBUG("dma->buf_count : %d\n", dma->buf_count);
1087 DRM_DEBUG("entry->buf_count : %d\n", entry->buf_count);
1088
1089 mutex_unlock(&dev->struct_mutex);
1090
1091 request->count = entry->buf_count;
1092 request->size = size;
1093
1094 dma->flags = _DRM_DMA_USE_SG;
1095
1096 atomic_dec(&dev->buf_alloc);
1097 return 0;
1098}
1099
1100static int drm_addbufs_fb(struct drm_device * dev, struct drm_buf_desc * request)
1101{
1102 struct drm_device_dma *dma = dev->dma;
1103 struct drm_buf_entry *entry;
1104 struct drm_buf *buf;
1105 unsigned long offset;
1106 unsigned long agp_offset;
1107 int count;
1108 int order;
1109 int size;
1110 int alignment;
1111 int page_order;
1112 int total;
1113 int byte_count;
1114 int i;
1115 struct drm_buf **temp_buflist;
1116
1117 if (!drm_core_check_feature(dev, DRIVER_FB_DMA))
1118 return -EINVAL;
1119
1120 if (!dma)
1121 return -EINVAL;
1122
1123 if (!capable(CAP_SYS_ADMIN))
1124 return -EPERM;
1125
1126 count = request->count;
1127 order = drm_order(request->size);
1128 size = 1 << order;
1129
1130 alignment = (request->flags & _DRM_PAGE_ALIGN)
1131 ? PAGE_ALIGN(size) : size;
1132 page_order = order - PAGE_SHIFT > 0 ? order - PAGE_SHIFT : 0;
1133 total = PAGE_SIZE << page_order;
1134
1135 byte_count = 0;
1136 agp_offset = request->agp_start;
1137
1138 DRM_DEBUG("count: %d\n", count);
1139 DRM_DEBUG("order: %d\n", order);
1140 DRM_DEBUG("size: %d\n", size);
1141 DRM_DEBUG("agp_offset: %lu\n", agp_offset);
1142 DRM_DEBUG("alignment: %d\n", alignment);
1143 DRM_DEBUG("page_order: %d\n", page_order);
1144 DRM_DEBUG("total: %d\n", total);
1145
1146 if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER)
1147 return -EINVAL;
1148 if (dev->queue_count)
1149 return -EBUSY; /* Not while in use */
1150
1151 spin_lock(&dev->count_lock);
1152 if (dev->buf_use) {
1153 spin_unlock(&dev->count_lock);
1154 return -EBUSY;
1155 }
1156 atomic_inc(&dev->buf_alloc);
1157 spin_unlock(&dev->count_lock);
1158
1159 mutex_lock(&dev->struct_mutex);
1160 entry = &dma->bufs[order];
1161 if (entry->buf_count) {
1162 mutex_unlock(&dev->struct_mutex);
1163 atomic_dec(&dev->buf_alloc);
1164 return -ENOMEM; /* May only call once for each order */
1165 }
1166
1167 if (count < 0 || count > 4096) {
1168 mutex_unlock(&dev->struct_mutex);
1169 atomic_dec(&dev->buf_alloc);
1170 return -EINVAL;
1171 }
1172
1173 entry->buflist = drm_alloc(count * sizeof(*entry->buflist),
1174 DRM_MEM_BUFS);
1175 if (!entry->buflist) {
1176 mutex_unlock(&dev->struct_mutex);
1177 atomic_dec(&dev->buf_alloc);
1178 return -ENOMEM;
1179 }
1180 memset(entry->buflist, 0, count * sizeof(*entry->buflist));
1181
1182 entry->buf_size = size;
1183 entry->page_order = page_order;
1184
1185 offset = 0;
1186
1187 while (entry->buf_count < count) {
1188 buf = &entry->buflist[entry->buf_count];
1189 buf->idx = dma->buf_count + entry->buf_count;
1190 buf->total = alignment;
1191 buf->order = order;
1192 buf->used = 0;
1193
1194 buf->offset = (dma->byte_count + offset);
1195 buf->bus_address = agp_offset + offset;
1196 buf->address = (void *)(agp_offset + offset);
1197 buf->next = NULL;
1198 buf->waiting = 0;
1199 buf->pending = 0;
1200 init_waitqueue_head(&buf->dma_wait);
1201 buf->file_priv = NULL;
1202
1203 buf->dev_priv_size = dev->driver->dev_priv_size;
1204 buf->dev_private = drm_alloc(buf->dev_priv_size, DRM_MEM_BUFS);
1205 if (!buf->dev_private) {
1206 /* Set count correctly so we free the proper amount. */
1207 entry->buf_count = count;
1208 drm_cleanup_buf_error(dev, entry);
1209 mutex_unlock(&dev->struct_mutex);
1210 atomic_dec(&dev->buf_alloc);
1211 return -ENOMEM;
1212 }
1213 memset(buf->dev_private, 0, buf->dev_priv_size);
1214
1215 DRM_DEBUG("buffer %d @ %p\n", entry->buf_count, buf->address);
1216
1217 offset += alignment;
1218 entry->buf_count++;
1219 byte_count += PAGE_SIZE << page_order;
1220 }
1221
1222 DRM_DEBUG("byte_count: %d\n", byte_count);
1223
1224 temp_buflist = drm_realloc(dma->buflist,
1225 dma->buf_count * sizeof(*dma->buflist),
1226 (dma->buf_count + entry->buf_count)
1227 * sizeof(*dma->buflist), DRM_MEM_BUFS);
1228 if (!temp_buflist) {
1229 /* Free the entry because it isn't valid */
1230 drm_cleanup_buf_error(dev, entry);
1231 mutex_unlock(&dev->struct_mutex);
1232 atomic_dec(&dev->buf_alloc);
1233 return -ENOMEM;
1234 }
1235 dma->buflist = temp_buflist;
1236
1237 for (i = 0; i < entry->buf_count; i++) {
1238 dma->buflist[i + dma->buf_count] = &entry->buflist[i];
1239 }
1240
1241 dma->buf_count += entry->buf_count;
1242 dma->seg_count += entry->seg_count;
1243 dma->page_count += byte_count >> PAGE_SHIFT;
1244 dma->byte_count += byte_count;
1245
1246 DRM_DEBUG("dma->buf_count : %d\n", dma->buf_count);
1247 DRM_DEBUG("entry->buf_count : %d\n", entry->buf_count);
1248
1249 mutex_unlock(&dev->struct_mutex);
1250
1251 request->count = entry->buf_count;
1252 request->size = size;
1253
1254 dma->flags = _DRM_DMA_USE_FB;
1255
1256 atomic_dec(&dev->buf_alloc);
1257 return 0;
1258}
1259
1260
1261/**
1262 * Add buffers for DMA transfers (ioctl).
1263 *
1264 * \param inode device inode.
1265 * \param file_priv DRM file private.
1266 * \param cmd command.
1267 * \param arg pointer to a struct drm_buf_desc request.
1268 * \return zero on success or a negative number on failure.
1269 *
1270 * According with the memory type specified in drm_buf_desc::flags and the
1271 * build options, it dispatches the call either to addbufs_agp(),
1272 * addbufs_sg() or addbufs_pci() for AGP, scatter-gather or consistent
1273 * PCI memory respectively.
1274 */
1275int drm_addbufs(struct drm_device *dev, void *data,
1276 struct drm_file *file_priv)
1277{
1278 struct drm_buf_desc *request = data;
1279 int ret;
1280
1281 if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA))
1282 return -EINVAL;
1283
1284#if __OS_HAS_AGP
1285 if (request->flags & _DRM_AGP_BUFFER)
1286 ret = drm_addbufs_agp(dev, request);
1287 else
1288#endif
1289 if (request->flags & _DRM_SG_BUFFER)
1290 ret = drm_addbufs_sg(dev, request);
1291 else if (request->flags & _DRM_FB_BUFFER)
1292 ret = drm_addbufs_fb(dev, request);
1293 else
1294 ret = drm_addbufs_pci(dev, request);
1295
1296 return ret;
1297}
1298
1299/**
1300 * Get information about the buffer mappings.
1301 *
1302 * This was originally mean for debugging purposes, or by a sophisticated
1303 * client library to determine how best to use the available buffers (e.g.,
1304 * large buffers can be used for image transfer).
1305 *
1306 * \param inode device inode.
1307 * \param file_priv DRM file private.
1308 * \param cmd command.
1309 * \param arg pointer to a drm_buf_info structure.
1310 * \return zero on success or a negative number on failure.
1311 *
1312 * Increments drm_device::buf_use while holding the drm_device::count_lock
1313 * lock, preventing of allocating more buffers after this call. Information
1314 * about each requested buffer is then copied into user space.
1315 */
1316int drm_infobufs(struct drm_device *dev, void *data,
1317 struct drm_file *file_priv)
1318{
1319 struct drm_device_dma *dma = dev->dma;
1320 struct drm_buf_info *request = data;
1321 int i;
1322 int count;
1323
1324 if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA))
1325 return -EINVAL;
1326
1327 if (!dma)
1328 return -EINVAL;
1329
1330 spin_lock(&dev->count_lock);
1331 if (atomic_read(&dev->buf_alloc)) {
1332 spin_unlock(&dev->count_lock);
1333 return -EBUSY;
1334 }
1335 ++dev->buf_use; /* Can't allocate more after this call */
1336 spin_unlock(&dev->count_lock);
1337
1338 for (i = 0, count = 0; i < DRM_MAX_ORDER + 1; i++) {
1339 if (dma->bufs[i].buf_count)
1340 ++count;
1341 }
1342
1343 DRM_DEBUG("count = %d\n", count);
1344
1345 if (request->count >= count) {
1346 for (i = 0, count = 0; i < DRM_MAX_ORDER + 1; i++) {
1347 if (dma->bufs[i].buf_count) {
1348 struct drm_buf_desc __user *to =
1349 &request->list[count];
1350 struct drm_buf_entry *from = &dma->bufs[i];
1351 struct drm_freelist *list = &dma->bufs[i].freelist;
1352 if (copy_to_user(&to->count,
1353 &from->buf_count,
1354 sizeof(from->buf_count)) ||
1355 copy_to_user(&to->size,
1356 &from->buf_size,
1357 sizeof(from->buf_size)) ||
1358 copy_to_user(&to->low_mark,
1359 &list->low_mark,
1360 sizeof(list->low_mark)) ||
1361 copy_to_user(&to->high_mark,
1362 &list->high_mark,
1363 sizeof(list->high_mark)))
1364 return -EFAULT;
1365
1366 DRM_DEBUG("%d %d %d %d %d\n",
1367 i,
1368 dma->bufs[i].buf_count,
1369 dma->bufs[i].buf_size,
1370 dma->bufs[i].freelist.low_mark,
1371 dma->bufs[i].freelist.high_mark);
1372 ++count;
1373 }
1374 }
1375 }
1376 request->count = count;
1377
1378 return 0;
1379}
1380
1381/**
1382 * Specifies a low and high water mark for buffer allocation
1383 *
1384 * \param inode device inode.
1385 * \param file_priv DRM file private.
1386 * \param cmd command.
1387 * \param arg a pointer to a drm_buf_desc structure.
1388 * \return zero on success or a negative number on failure.
1389 *
1390 * Verifies that the size order is bounded between the admissible orders and
1391 * updates the respective drm_device_dma::bufs entry low and high water mark.
1392 *
1393 * \note This ioctl is deprecated and mostly never used.
1394 */
1395int drm_markbufs(struct drm_device *dev, void *data,
1396 struct drm_file *file_priv)
1397{
1398 struct drm_device_dma *dma = dev->dma;
1399 struct drm_buf_desc *request = data;
1400 int order;
1401 struct drm_buf_entry *entry;
1402
1403 if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA))
1404 return -EINVAL;
1405
1406 if (!dma)
1407 return -EINVAL;
1408
1409 DRM_DEBUG("%d, %d, %d\n",
1410 request->size, request->low_mark, request->high_mark);
1411 order = drm_order(request->size);
1412 if (order < DRM_MIN_ORDER || order > DRM_MAX_ORDER)
1413 return -EINVAL;
1414 entry = &dma->bufs[order];
1415
1416 if (request->low_mark < 0 || request->low_mark > entry->buf_count)
1417 return -EINVAL;
1418 if (request->high_mark < 0 || request->high_mark > entry->buf_count)
1419 return -EINVAL;
1420
1421 entry->freelist.low_mark = request->low_mark;
1422 entry->freelist.high_mark = request->high_mark;
1423
1424 return 0;
1425}
1426
1427/**
1428 * Unreserve the buffers in list, previously reserved using drmDMA.
1429 *
1430 * \param inode device inode.
1431 * \param file_priv DRM file private.
1432 * \param cmd command.
1433 * \param arg pointer to a drm_buf_free structure.
1434 * \return zero on success or a negative number on failure.
1435 *
1436 * Calls free_buffer() for each used buffer.
1437 * This function is primarily used for debugging.
1438 */
1439int drm_freebufs(struct drm_device *dev, void *data,
1440 struct drm_file *file_priv)
1441{
1442 struct drm_device_dma *dma = dev->dma;
1443 struct drm_buf_free *request = data;
1444 int i;
1445 int idx;
1446 struct drm_buf *buf;
1447
1448 if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA))
1449 return -EINVAL;
1450
1451 if (!dma)
1452 return -EINVAL;
1453
1454 DRM_DEBUG("%d\n", request->count);
1455 for (i = 0; i < request->count; i++) {
1456 if (copy_from_user(&idx, &request->list[i], sizeof(idx)))
1457 return -EFAULT;
1458 if (idx < 0 || idx >= dma->buf_count) {
1459 DRM_ERROR("Index %d (of %d max)\n",
1460 idx, dma->buf_count - 1);
1461 return -EINVAL;
1462 }
1463 buf = dma->buflist[idx];
1464 if (buf->file_priv != file_priv) {
1465 DRM_ERROR("Process %d freeing buffer not owned\n",
1466 task_pid_nr(current));
1467 return -EINVAL;
1468 }
1469 drm_free_buffer(dev, buf);
1470 }
1471
1472 return 0;
1473}
1474
1475/**
1476 * Maps all of the DMA buffers into client-virtual space (ioctl).
1477 *
1478 * \param inode device inode.
1479 * \param file_priv DRM file private.
1480 * \param cmd command.
1481 * \param arg pointer to a drm_buf_map structure.
1482 * \return zero on success or a negative number on failure.
1483 *
1484 * Maps the AGP, SG or PCI buffer region with do_mmap(), and copies information
1485 * about each buffer into user space. For PCI buffers, it calls do_mmap() with
1486 * offset equal to 0, which drm_mmap() interpretes as PCI buffers and calls
1487 * drm_mmap_dma().
1488 */
1489int drm_mapbufs(struct drm_device *dev, void *data,
1490 struct drm_file *file_priv)
1491{
1492 struct drm_device_dma *dma = dev->dma;
1493 int retcode = 0;
1494 const int zero = 0;
1495 unsigned long virtual;
1496 unsigned long address;
1497 struct drm_buf_map *request = data;
1498 int i;
1499
1500 if (!drm_core_check_feature(dev, DRIVER_HAVE_DMA))
1501 return -EINVAL;
1502
1503 if (!dma)
1504 return -EINVAL;
1505
1506 spin_lock(&dev->count_lock);
1507 if (atomic_read(&dev->buf_alloc)) {
1508 spin_unlock(&dev->count_lock);
1509 return -EBUSY;
1510 }
1511 dev->buf_use++; /* Can't allocate more after this call */
1512 spin_unlock(&dev->count_lock);
1513
1514 if (request->count >= dma->buf_count) {
1515 if ((drm_core_has_AGP(dev) && (dma->flags & _DRM_DMA_USE_AGP))
1516 || (drm_core_check_feature(dev, DRIVER_SG)
1517 && (dma->flags & _DRM_DMA_USE_SG))
1518 || (drm_core_check_feature(dev, DRIVER_FB_DMA)
1519 && (dma->flags & _DRM_DMA_USE_FB))) {
1520 struct drm_map *map = dev->agp_buffer_map;
1521 unsigned long token = dev->agp_buffer_token;
1522
1523 if (!map) {
1524 retcode = -EINVAL;
1525 goto done;
1526 }
1527 down_write(&current->mm->mmap_sem);
1528 virtual = do_mmap(file_priv->filp, 0, map->size,
1529 PROT_READ | PROT_WRITE,
1530 MAP_SHARED,
1531 token);
1532 up_write(&current->mm->mmap_sem);
1533 } else {
1534 down_write(&current->mm->mmap_sem);
1535 virtual = do_mmap(file_priv->filp, 0, dma->byte_count,
1536 PROT_READ | PROT_WRITE,
1537 MAP_SHARED, 0);
1538 up_write(&current->mm->mmap_sem);
1539 }
1540 if (virtual > -1024UL) {
1541 /* Real error */
1542 retcode = (signed long)virtual;
1543 goto done;
1544 }
1545 request->virtual = (void __user *)virtual;
1546
1547 for (i = 0; i < dma->buf_count; i++) {
1548 if (copy_to_user(&request->list[i].idx,
1549 &dma->buflist[i]->idx,
1550 sizeof(request->list[0].idx))) {
1551 retcode = -EFAULT;
1552 goto done;
1553 }
1554 if (copy_to_user(&request->list[i].total,
1555 &dma->buflist[i]->total,
1556 sizeof(request->list[0].total))) {
1557 retcode = -EFAULT;
1558 goto done;
1559 }
1560 if (copy_to_user(&request->list[i].used,
1561 &zero, sizeof(zero))) {
1562 retcode = -EFAULT;
1563 goto done;
1564 }
1565 address = virtual + dma->buflist[i]->offset; /* *** */
1566 if (copy_to_user(&request->list[i].address,
1567 &address, sizeof(address))) {
1568 retcode = -EFAULT;
1569 goto done;
1570 }
1571 }
1572 }
1573 done:
1574 request->count = dma->buf_count;
1575 DRM_DEBUG("%d buffers, retcode = %d\n", request->count, retcode);
1576
1577 return retcode;
1578}
1579
1580/**
1581 * Compute size order. Returns the exponent of the smaller power of two which
1582 * is greater or equal to given number.
1583 *
1584 * \param size size.
1585 * \return order.
1586 *
1587 * \todo Can be made faster.
1588 */
1589int drm_order(unsigned long size)
1590{
1591 int order;
1592 unsigned long tmp;
1593
1594 for (order = 0, tmp = size >> 1; tmp; tmp >>= 1, order++) ;
1595
1596 if (size & (size - 1))
1597 ++order;
1598
1599 return order;
1600}
1601EXPORT_SYMBOL(drm_order);
diff --git a/drivers/char/drm/drm_context.c b/drivers/char/drm/drm_context.c
deleted file mode 100644
index d505f695421f..000000000000
--- a/drivers/char/drm/drm_context.c
+++ /dev/null
@@ -1,471 +0,0 @@
1/**
2 * \file drm_context.c
3 * IOCTLs for generic contexts
4 *
5 * \author Rickard E. (Rik) Faith <faith@valinux.com>
6 * \author Gareth Hughes <gareth@valinux.com>
7 */
8
9/*
10 * Created: Fri Nov 24 18:31:37 2000 by gareth@valinux.com
11 *
12 * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
13 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
14 * All Rights Reserved.
15 *
16 * Permission is hereby granted, free of charge, to any person obtaining a
17 * copy of this software and associated documentation files (the "Software"),
18 * to deal in the Software without restriction, including without limitation
19 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
20 * and/or sell copies of the Software, and to permit persons to whom the
21 * Software is furnished to do so, subject to the following conditions:
22 *
23 * The above copyright notice and this permission notice (including the next
24 * paragraph) shall be included in all copies or substantial portions of the
25 * Software.
26 *
27 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
30 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
31 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
32 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
33 * OTHER DEALINGS IN THE SOFTWARE.
34 */
35
36/*
37 * ChangeLog:
38 * 2001-11-16 Torsten Duwe <duwe@caldera.de>
39 * added context constructor/destructor hooks,
40 * needed by SiS driver's memory management.
41 */
42
43#include "drmP.h"
44
45/******************************************************************/
46/** \name Context bitmap support */
47/*@{*/
48
49/**
50 * Free a handle from the context bitmap.
51 *
52 * \param dev DRM device.
53 * \param ctx_handle context handle.
54 *
55 * Clears the bit specified by \p ctx_handle in drm_device::ctx_bitmap and the entry
56 * in drm_device::ctx_idr, while holding the drm_device::struct_mutex
57 * lock.
58 */
59void drm_ctxbitmap_free(struct drm_device * dev, int ctx_handle)
60{
61 mutex_lock(&dev->struct_mutex);
62 idr_remove(&dev->ctx_idr, ctx_handle);
63 mutex_unlock(&dev->struct_mutex);
64}
65
66/**
67 * Context bitmap allocation.
68 *
69 * \param dev DRM device.
70 * \return (non-negative) context handle on success or a negative number on failure.
71 *
72 * Allocate a new idr from drm_device::ctx_idr while holding the
73 * drm_device::struct_mutex lock.
74 */
75static int drm_ctxbitmap_next(struct drm_device * dev)
76{
77 int new_id;
78 int ret;
79
80again:
81 if (idr_pre_get(&dev->ctx_idr, GFP_KERNEL) == 0) {
82 DRM_ERROR("Out of memory expanding drawable idr\n");
83 return -ENOMEM;
84 }
85 mutex_lock(&dev->struct_mutex);
86 ret = idr_get_new_above(&dev->ctx_idr, NULL,
87 DRM_RESERVED_CONTEXTS, &new_id);
88 if (ret == -EAGAIN) {
89 mutex_unlock(&dev->struct_mutex);
90 goto again;
91 }
92 mutex_unlock(&dev->struct_mutex);
93 return new_id;
94}
95
96/**
97 * Context bitmap initialization.
98 *
99 * \param dev DRM device.
100 *
101 * Initialise the drm_device::ctx_idr
102 */
103int drm_ctxbitmap_init(struct drm_device * dev)
104{
105 idr_init(&dev->ctx_idr);
106 return 0;
107}
108
109/**
110 * Context bitmap cleanup.
111 *
112 * \param dev DRM device.
113 *
114 * Free all idr members using drm_ctx_sarea_free helper function
115 * while holding the drm_device::struct_mutex lock.
116 */
117void drm_ctxbitmap_cleanup(struct drm_device * dev)
118{
119 mutex_lock(&dev->struct_mutex);
120 idr_remove_all(&dev->ctx_idr);
121 mutex_unlock(&dev->struct_mutex);
122}
123
124/*@}*/
125
126/******************************************************************/
127/** \name Per Context SAREA Support */
128/*@{*/
129
130/**
131 * Get per-context SAREA.
132 *
133 * \param inode device inode.
134 * \param file_priv DRM file private.
135 * \param cmd command.
136 * \param arg user argument pointing to a drm_ctx_priv_map structure.
137 * \return zero on success or a negative number on failure.
138 *
139 * Gets the map from drm_device::ctx_idr with the handle specified and
140 * returns its handle.
141 */
142int drm_getsareactx(struct drm_device *dev, void *data,
143 struct drm_file *file_priv)
144{
145 struct drm_ctx_priv_map *request = data;
146 struct drm_map *map;
147 struct drm_map_list *_entry;
148
149 mutex_lock(&dev->struct_mutex);
150
151 map = idr_find(&dev->ctx_idr, request->ctx_id);
152 if (!map) {
153 mutex_unlock(&dev->struct_mutex);
154 return -EINVAL;
155 }
156
157 mutex_unlock(&dev->struct_mutex);
158
159 request->handle = NULL;
160 list_for_each_entry(_entry, &dev->maplist, head) {
161 if (_entry->map == map) {
162 request->handle =
163 (void *)(unsigned long)_entry->user_token;
164 break;
165 }
166 }
167 if (request->handle == NULL)
168 return -EINVAL;
169
170 return 0;
171}
172
173/**
174 * Set per-context SAREA.
175 *
176 * \param inode device inode.
177 * \param file_priv DRM file private.
178 * \param cmd command.
179 * \param arg user argument pointing to a drm_ctx_priv_map structure.
180 * \return zero on success or a negative number on failure.
181 *
182 * Searches the mapping specified in \p arg and update the entry in
183 * drm_device::ctx_idr with it.
184 */
185int drm_setsareactx(struct drm_device *dev, void *data,
186 struct drm_file *file_priv)
187{
188 struct drm_ctx_priv_map *request = data;
189 struct drm_map *map = NULL;
190 struct drm_map_list *r_list = NULL;
191
192 mutex_lock(&dev->struct_mutex);
193 list_for_each_entry(r_list, &dev->maplist, head) {
194 if (r_list->map
195 && r_list->user_token == (unsigned long) request->handle)
196 goto found;
197 }
198 bad:
199 mutex_unlock(&dev->struct_mutex);
200 return -EINVAL;
201
202 found:
203 map = r_list->map;
204 if (!map)
205 goto bad;
206
207 if (IS_ERR(idr_replace(&dev->ctx_idr, map, request->ctx_id)))
208 goto bad;
209
210 mutex_unlock(&dev->struct_mutex);
211
212 return 0;
213}
214
215/*@}*/
216
217/******************************************************************/
218/** \name The actual DRM context handling routines */
219/*@{*/
220
221/**
222 * Switch context.
223 *
224 * \param dev DRM device.
225 * \param old old context handle.
226 * \param new new context handle.
227 * \return zero on success or a negative number on failure.
228 *
229 * Attempt to set drm_device::context_flag.
230 */
231static int drm_context_switch(struct drm_device * dev, int old, int new)
232{
233 if (test_and_set_bit(0, &dev->context_flag)) {
234 DRM_ERROR("Reentering -- FIXME\n");
235 return -EBUSY;
236 }
237
238 DRM_DEBUG("Context switch from %d to %d\n", old, new);
239
240 if (new == dev->last_context) {
241 clear_bit(0, &dev->context_flag);
242 return 0;
243 }
244
245 return 0;
246}
247
248/**
249 * Complete context switch.
250 *
251 * \param dev DRM device.
252 * \param new new context handle.
253 * \return zero on success or a negative number on failure.
254 *
255 * Updates drm_device::last_context and drm_device::last_switch. Verifies the
256 * hardware lock is held, clears the drm_device::context_flag and wakes up
257 * drm_device::context_wait.
258 */
259static int drm_context_switch_complete(struct drm_device * dev, int new)
260{
261 dev->last_context = new; /* PRE/POST: This is the _only_ writer. */
262 dev->last_switch = jiffies;
263
264 if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
265 DRM_ERROR("Lock isn't held after context switch\n");
266 }
267
268 /* If a context switch is ever initiated
269 when the kernel holds the lock, release
270 that lock here. */
271 clear_bit(0, &dev->context_flag);
272 wake_up(&dev->context_wait);
273
274 return 0;
275}
276
277/**
278 * Reserve contexts.
279 *
280 * \param inode device inode.
281 * \param file_priv DRM file private.
282 * \param cmd command.
283 * \param arg user argument pointing to a drm_ctx_res structure.
284 * \return zero on success or a negative number on failure.
285 */
286int drm_resctx(struct drm_device *dev, void *data,
287 struct drm_file *file_priv)
288{
289 struct drm_ctx_res *res = data;
290 struct drm_ctx ctx;
291 int i;
292
293 if (res->count >= DRM_RESERVED_CONTEXTS) {
294 memset(&ctx, 0, sizeof(ctx));
295 for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) {
296 ctx.handle = i;
297 if (copy_to_user(&res->contexts[i], &ctx, sizeof(ctx)))
298 return -EFAULT;
299 }
300 }
301 res->count = DRM_RESERVED_CONTEXTS;
302
303 return 0;
304}
305
306/**
307 * Add context.
308 *
309 * \param inode device inode.
310 * \param file_priv DRM file private.
311 * \param cmd command.
312 * \param arg user argument pointing to a drm_ctx structure.
313 * \return zero on success or a negative number on failure.
314 *
315 * Get a new handle for the context and copy to userspace.
316 */
317int drm_addctx(struct drm_device *dev, void *data,
318 struct drm_file *file_priv)
319{
320 struct drm_ctx_list *ctx_entry;
321 struct drm_ctx *ctx = data;
322
323 ctx->handle = drm_ctxbitmap_next(dev);
324 if (ctx->handle == DRM_KERNEL_CONTEXT) {
325 /* Skip kernel's context and get a new one. */
326 ctx->handle = drm_ctxbitmap_next(dev);
327 }
328 DRM_DEBUG("%d\n", ctx->handle);
329 if (ctx->handle == -1) {
330 DRM_DEBUG("Not enough free contexts.\n");
331 /* Should this return -EBUSY instead? */
332 return -ENOMEM;
333 }
334
335 if (ctx->handle != DRM_KERNEL_CONTEXT) {
336 if (dev->driver->context_ctor)
337 if (!dev->driver->context_ctor(dev, ctx->handle)) {
338 DRM_DEBUG("Running out of ctxs or memory.\n");
339 return -ENOMEM;
340 }
341 }
342
343 ctx_entry = drm_alloc(sizeof(*ctx_entry), DRM_MEM_CTXLIST);
344 if (!ctx_entry) {
345 DRM_DEBUG("out of memory\n");
346 return -ENOMEM;
347 }
348
349 INIT_LIST_HEAD(&ctx_entry->head);
350 ctx_entry->handle = ctx->handle;
351 ctx_entry->tag = file_priv;
352
353 mutex_lock(&dev->ctxlist_mutex);
354 list_add(&ctx_entry->head, &dev->ctxlist);
355 ++dev->ctx_count;
356 mutex_unlock(&dev->ctxlist_mutex);
357
358 return 0;
359}
360
361int drm_modctx(struct drm_device *dev, void *data, struct drm_file *file_priv)
362{
363 /* This does nothing */
364 return 0;
365}
366
367/**
368 * Get context.
369 *
370 * \param inode device inode.
371 * \param file_priv DRM file private.
372 * \param cmd command.
373 * \param arg user argument pointing to a drm_ctx structure.
374 * \return zero on success or a negative number on failure.
375 */
376int drm_getctx(struct drm_device *dev, void *data, struct drm_file *file_priv)
377{
378 struct drm_ctx *ctx = data;
379
380 /* This is 0, because we don't handle any context flags */
381 ctx->flags = 0;
382
383 return 0;
384}
385
386/**
387 * Switch context.
388 *
389 * \param inode device inode.
390 * \param file_priv DRM file private.
391 * \param cmd command.
392 * \param arg user argument pointing to a drm_ctx structure.
393 * \return zero on success or a negative number on failure.
394 *
395 * Calls context_switch().
396 */
397int drm_switchctx(struct drm_device *dev, void *data,
398 struct drm_file *file_priv)
399{
400 struct drm_ctx *ctx = data;
401
402 DRM_DEBUG("%d\n", ctx->handle);
403 return drm_context_switch(dev, dev->last_context, ctx->handle);
404}
405
406/**
407 * New context.
408 *
409 * \param inode device inode.
410 * \param file_priv DRM file private.
411 * \param cmd command.
412 * \param arg user argument pointing to a drm_ctx structure.
413 * \return zero on success or a negative number on failure.
414 *
415 * Calls context_switch_complete().
416 */
417int drm_newctx(struct drm_device *dev, void *data,
418 struct drm_file *file_priv)
419{
420 struct drm_ctx *ctx = data;
421
422 DRM_DEBUG("%d\n", ctx->handle);
423 drm_context_switch_complete(dev, ctx->handle);
424
425 return 0;
426}
427
428/**
429 * Remove context.
430 *
431 * \param inode device inode.
432 * \param file_priv DRM file private.
433 * \param cmd command.
434 * \param arg user argument pointing to a drm_ctx structure.
435 * \return zero on success or a negative number on failure.
436 *
437 * If not the special kernel context, calls ctxbitmap_free() to free the specified context.
438 */
439int drm_rmctx(struct drm_device *dev, void *data,
440 struct drm_file *file_priv)
441{
442 struct drm_ctx *ctx = data;
443
444 DRM_DEBUG("%d\n", ctx->handle);
445 if (ctx->handle == DRM_KERNEL_CONTEXT + 1) {
446 file_priv->remove_auth_on_close = 1;
447 }
448 if (ctx->handle != DRM_KERNEL_CONTEXT) {
449 if (dev->driver->context_dtor)
450 dev->driver->context_dtor(dev, ctx->handle);
451 drm_ctxbitmap_free(dev, ctx->handle);
452 }
453
454 mutex_lock(&dev->ctxlist_mutex);
455 if (!list_empty(&dev->ctxlist)) {
456 struct drm_ctx_list *pos, *n;
457
458 list_for_each_entry_safe(pos, n, &dev->ctxlist, head) {
459 if (pos->handle == ctx->handle) {
460 list_del(&pos->head);
461 drm_free(pos, sizeof(*pos), DRM_MEM_CTXLIST);
462 --dev->ctx_count;
463 }
464 }
465 }
466 mutex_unlock(&dev->ctxlist_mutex);
467
468 return 0;
469}
470
471/*@}*/
diff --git a/drivers/char/drm/drm_core.h b/drivers/char/drm/drm_core.h
deleted file mode 100644
index 316739036079..000000000000
--- a/drivers/char/drm/drm_core.h
+++ /dev/null
@@ -1,34 +0,0 @@
1/*
2 * Copyright 2004 Jon Smirl <jonsmirl@gmail.com>
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sub license,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the
12 * next paragraph) shall be included in all copies or substantial portions
13 * of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18 * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23#define CORE_AUTHOR "Gareth Hughes, Leif Delgass, José Fonseca, Jon Smirl"
24
25#define CORE_NAME "drm"
26#define CORE_DESC "DRM shared core routines"
27#define CORE_DATE "20060810"
28
29#define DRM_IF_MAJOR 1
30#define DRM_IF_MINOR 3
31
32#define CORE_MAJOR 1
33#define CORE_MINOR 1
34#define CORE_PATCHLEVEL 0
diff --git a/drivers/char/drm/drm_dma.c b/drivers/char/drm/drm_dma.c
deleted file mode 100644
index 7a8e2fba4678..000000000000
--- a/drivers/char/drm/drm_dma.c
+++ /dev/null
@@ -1,180 +0,0 @@
1/**
2 * \file drm_dma.c
3 * DMA IOCTL and function support
4 *
5 * \author Rickard E. (Rik) Faith <faith@valinux.com>
6 * \author Gareth Hughes <gareth@valinux.com>
7 */
8
9/*
10 * Created: Fri Mar 19 14:30:16 1999 by faith@valinux.com
11 *
12 * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
13 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
14 * All Rights Reserved.
15 *
16 * Permission is hereby granted, free of charge, to any person obtaining a
17 * copy of this software and associated documentation files (the "Software"),
18 * to deal in the Software without restriction, including without limitation
19 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
20 * and/or sell copies of the Software, and to permit persons to whom the
21 * Software is furnished to do so, subject to the following conditions:
22 *
23 * The above copyright notice and this permission notice (including the next
24 * paragraph) shall be included in all copies or substantial portions of the
25 * Software.
26 *
27 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
30 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
31 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
32 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
33 * OTHER DEALINGS IN THE SOFTWARE.
34 */
35
36#include "drmP.h"
37
38/**
39 * Initialize the DMA data.
40 *
41 * \param dev DRM device.
42 * \return zero on success or a negative value on failure.
43 *
44 * Allocate and initialize a drm_device_dma structure.
45 */
46int drm_dma_setup(struct drm_device *dev)
47{
48 int i;
49
50 dev->dma = drm_alloc(sizeof(*dev->dma), DRM_MEM_DRIVER);
51 if (!dev->dma)
52 return -ENOMEM;
53
54 memset(dev->dma, 0, sizeof(*dev->dma));
55
56 for (i = 0; i <= DRM_MAX_ORDER; i++)
57 memset(&dev->dma->bufs[i], 0, sizeof(dev->dma->bufs[0]));
58
59 return 0;
60}
61
62/**
63 * Cleanup the DMA resources.
64 *
65 * \param dev DRM device.
66 *
67 * Free all pages associated with DMA buffers, the buffers and pages lists, and
68 * finally the drm_device::dma structure itself.
69 */
70void drm_dma_takedown(struct drm_device *dev)
71{
72 struct drm_device_dma *dma = dev->dma;
73 int i, j;
74
75 if (!dma)
76 return;
77
78 /* Clear dma buffers */
79 for (i = 0; i <= DRM_MAX_ORDER; i++) {
80 if (dma->bufs[i].seg_count) {
81 DRM_DEBUG("order %d: buf_count = %d,"
82 " seg_count = %d\n",
83 i,
84 dma->bufs[i].buf_count,
85 dma->bufs[i].seg_count);
86 for (j = 0; j < dma->bufs[i].seg_count; j++) {
87 if (dma->bufs[i].seglist[j]) {
88 drm_pci_free(dev, dma->bufs[i].seglist[j]);
89 }
90 }
91 drm_free(dma->bufs[i].seglist,
92 dma->bufs[i].seg_count
93 * sizeof(*dma->bufs[0].seglist), DRM_MEM_SEGS);
94 }
95 if (dma->bufs[i].buf_count) {
96 for (j = 0; j < dma->bufs[i].buf_count; j++) {
97 if (dma->bufs[i].buflist[j].dev_private) {
98 drm_free(dma->bufs[i].buflist[j].
99 dev_private,
100 dma->bufs[i].buflist[j].
101 dev_priv_size, DRM_MEM_BUFS);
102 }
103 }
104 drm_free(dma->bufs[i].buflist,
105 dma->bufs[i].buf_count *
106 sizeof(*dma->bufs[0].buflist), DRM_MEM_BUFS);
107 }
108 }
109
110 if (dma->buflist) {
111 drm_free(dma->buflist,
112 dma->buf_count * sizeof(*dma->buflist), DRM_MEM_BUFS);
113 }
114
115 if (dma->pagelist) {
116 drm_free(dma->pagelist,
117 dma->page_count * sizeof(*dma->pagelist),
118 DRM_MEM_PAGES);
119 }
120 drm_free(dev->dma, sizeof(*dev->dma), DRM_MEM_DRIVER);
121 dev->dma = NULL;
122}
123
124/**
125 * Free a buffer.
126 *
127 * \param dev DRM device.
128 * \param buf buffer to free.
129 *
130 * Resets the fields of \p buf.
131 */
132void drm_free_buffer(struct drm_device *dev, struct drm_buf * buf)
133{
134 if (!buf)
135 return;
136
137 buf->waiting = 0;
138 buf->pending = 0;
139 buf->file_priv = NULL;
140 buf->used = 0;
141
142 if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE)
143 && waitqueue_active(&buf->dma_wait)) {
144 wake_up_interruptible(&buf->dma_wait);
145 }
146}
147
148/**
149 * Reclaim the buffers.
150 *
151 * \param file_priv DRM file private.
152 *
153 * Frees each buffer associated with \p file_priv not already on the hardware.
154 */
155void drm_core_reclaim_buffers(struct drm_device *dev,
156 struct drm_file *file_priv)
157{
158 struct drm_device_dma *dma = dev->dma;
159 int i;
160
161 if (!dma)
162 return;
163 for (i = 0; i < dma->buf_count; i++) {
164 if (dma->buflist[i]->file_priv == file_priv) {
165 switch (dma->buflist[i]->list) {
166 case DRM_LIST_NONE:
167 drm_free_buffer(dev, dma->buflist[i]);
168 break;
169 case DRM_LIST_WAIT:
170 dma->buflist[i]->list = DRM_LIST_RECLAIM;
171 break;
172 default:
173 /* Buffer already on hardware. */
174 break;
175 }
176 }
177 }
178}
179
180EXPORT_SYMBOL(drm_core_reclaim_buffers);
diff --git a/drivers/char/drm/drm_drawable.c b/drivers/char/drm/drm_drawable.c
deleted file mode 100644
index 1839c57663c5..000000000000
--- a/drivers/char/drm/drm_drawable.c
+++ /dev/null
@@ -1,192 +0,0 @@
1/**
2 * \file drm_drawable.c
3 * IOCTLs for drawables
4 *
5 * \author Rickard E. (Rik) Faith <faith@valinux.com>
6 * \author Gareth Hughes <gareth@valinux.com>
7 * \author Michel Dänzer <michel@tungstengraphics.com>
8 */
9
10/*
11 * Created: Tue Feb 2 08:37:54 1999 by faith@valinux.com
12 *
13 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
14 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
15 * Copyright 2006 Tungsten Graphics, Inc., Bismarck, North Dakota.
16 * All Rights Reserved.
17 *
18 * Permission is hereby granted, free of charge, to any person obtaining a
19 * copy of this software and associated documentation files (the "Software"),
20 * to deal in the Software without restriction, including without limitation
21 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
22 * and/or sell copies of the Software, and to permit persons to whom the
23 * Software is furnished to do so, subject to the following conditions:
24 *
25 * The above copyright notice and this permission notice (including the next
26 * paragraph) shall be included in all copies or substantial portions of the
27 * Software.
28 *
29 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
30 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
31 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
32 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
33 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
34 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
35 * OTHER DEALINGS IN THE SOFTWARE.
36 */
37
38#include "drmP.h"
39
40/**
41 * Allocate drawable ID and memory to store information about it.
42 */
43int drm_adddraw(struct drm_device *dev, void *data, struct drm_file *file_priv)
44{
45 unsigned long irqflags;
46 struct drm_draw *draw = data;
47 int new_id = 0;
48 int ret;
49
50again:
51 if (idr_pre_get(&dev->drw_idr, GFP_KERNEL) == 0) {
52 DRM_ERROR("Out of memory expanding drawable idr\n");
53 return -ENOMEM;
54 }
55
56 spin_lock_irqsave(&dev->drw_lock, irqflags);
57 ret = idr_get_new_above(&dev->drw_idr, NULL, 1, &new_id);
58 if (ret == -EAGAIN) {
59 spin_unlock_irqrestore(&dev->drw_lock, irqflags);
60 goto again;
61 }
62
63 spin_unlock_irqrestore(&dev->drw_lock, irqflags);
64
65 draw->handle = new_id;
66
67 DRM_DEBUG("%d\n", draw->handle);
68
69 return 0;
70}
71
72/**
73 * Free drawable ID and memory to store information about it.
74 */
75int drm_rmdraw(struct drm_device *dev, void *data, struct drm_file *file_priv)
76{
77 struct drm_draw *draw = data;
78 unsigned long irqflags;
79
80 spin_lock_irqsave(&dev->drw_lock, irqflags);
81
82 drm_free(drm_get_drawable_info(dev, draw->handle),
83 sizeof(struct drm_drawable_info), DRM_MEM_BUFS);
84
85 idr_remove(&dev->drw_idr, draw->handle);
86
87 spin_unlock_irqrestore(&dev->drw_lock, irqflags);
88 DRM_DEBUG("%d\n", draw->handle);
89 return 0;
90}
91
92int drm_update_drawable_info(struct drm_device *dev, void *data, struct drm_file *file_priv)
93{
94 struct drm_update_draw *update = data;
95 unsigned long irqflags;
96 struct drm_clip_rect *rects;
97 struct drm_drawable_info *info;
98 int err;
99
100 info = idr_find(&dev->drw_idr, update->handle);
101 if (!info) {
102 info = drm_calloc(1, sizeof(*info), DRM_MEM_BUFS);
103 if (!info)
104 return -ENOMEM;
105 if (IS_ERR(idr_replace(&dev->drw_idr, info, update->handle))) {
106 DRM_ERROR("No such drawable %d\n", update->handle);
107 drm_free(info, sizeof(*info), DRM_MEM_BUFS);
108 return -EINVAL;
109 }
110 }
111
112 switch (update->type) {
113 case DRM_DRAWABLE_CLIPRECTS:
114 if (update->num != info->num_rects) {
115 rects = drm_alloc(update->num * sizeof(struct drm_clip_rect),
116 DRM_MEM_BUFS);
117 } else
118 rects = info->rects;
119
120 if (update->num && !rects) {
121 DRM_ERROR("Failed to allocate cliprect memory\n");
122 err = -ENOMEM;
123 goto error;
124 }
125
126 if (update->num && DRM_COPY_FROM_USER(rects,
127 (struct drm_clip_rect __user *)
128 (unsigned long)update->data,
129 update->num *
130 sizeof(*rects))) {
131 DRM_ERROR("Failed to copy cliprects from userspace\n");
132 err = -EFAULT;
133 goto error;
134 }
135
136 spin_lock_irqsave(&dev->drw_lock, irqflags);
137
138 if (rects != info->rects) {
139 drm_free(info->rects, info->num_rects *
140 sizeof(struct drm_clip_rect), DRM_MEM_BUFS);
141 }
142
143 info->rects = rects;
144 info->num_rects = update->num;
145
146 spin_unlock_irqrestore(&dev->drw_lock, irqflags);
147
148 DRM_DEBUG("Updated %d cliprects for drawable %d\n",
149 info->num_rects, update->handle);
150 break;
151 default:
152 DRM_ERROR("Invalid update type %d\n", update->type);
153 return -EINVAL;
154 }
155
156 return 0;
157
158error:
159 if (rects != info->rects)
160 drm_free(rects, update->num * sizeof(struct drm_clip_rect),
161 DRM_MEM_BUFS);
162
163 return err;
164}
165
166/**
167 * Caller must hold the drawable spinlock!
168 */
169struct drm_drawable_info *drm_get_drawable_info(struct drm_device *dev, drm_drawable_t id)
170{
171 return idr_find(&dev->drw_idr, id);
172}
173EXPORT_SYMBOL(drm_get_drawable_info);
174
175static int drm_drawable_free(int idr, void *p, void *data)
176{
177 struct drm_drawable_info *info = p;
178
179 if (info) {
180 drm_free(info->rects, info->num_rects *
181 sizeof(struct drm_clip_rect), DRM_MEM_BUFS);
182 drm_free(info, sizeof(*info), DRM_MEM_BUFS);
183 }
184
185 return 0;
186}
187
188void drm_drawable_free_all(struct drm_device *dev)
189{
190 idr_for_each(&dev->drw_idr, drm_drawable_free, NULL);
191 idr_remove_all(&dev->drw_idr);
192}
diff --git a/drivers/char/drm/drm_drv.c b/drivers/char/drm/drm_drv.c
deleted file mode 100644
index fc54140551a7..000000000000
--- a/drivers/char/drm/drm_drv.c
+++ /dev/null
@@ -1,539 +0,0 @@
1/**
2 * \file drm_drv.c
3 * Generic driver template
4 *
5 * \author Rickard E. (Rik) Faith <faith@valinux.com>
6 * \author Gareth Hughes <gareth@valinux.com>
7 *
8 * To use this template, you must at least define the following (samples
9 * given for the MGA driver):
10 *
11 * \code
12 * #define DRIVER_AUTHOR "VA Linux Systems, Inc."
13 *
14 * #define DRIVER_NAME "mga"
15 * #define DRIVER_DESC "Matrox G200/G400"
16 * #define DRIVER_DATE "20001127"
17 *
18 * #define drm_x mga_##x
19 * \endcode
20 */
21
22/*
23 * Created: Thu Nov 23 03:10:50 2000 by gareth@valinux.com
24 *
25 * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
26 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
27 * All Rights Reserved.
28 *
29 * Permission is hereby granted, free of charge, to any person obtaining a
30 * copy of this software and associated documentation files (the "Software"),
31 * to deal in the Software without restriction, including without limitation
32 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
33 * and/or sell copies of the Software, and to permit persons to whom the
34 * Software is furnished to do so, subject to the following conditions:
35 *
36 * The above copyright notice and this permission notice (including the next
37 * paragraph) shall be included in all copies or substantial portions of the
38 * Software.
39 *
40 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
41 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
42 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
43 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
44 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
45 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
46 * OTHER DEALINGS IN THE SOFTWARE.
47 */
48
49#include "drmP.h"
50#include "drm_core.h"
51
52static int drm_version(struct drm_device *dev, void *data,
53 struct drm_file *file_priv);
54
55/** Ioctl table */
56static struct drm_ioctl_desc drm_ioctls[] = {
57 DRM_IOCTL_DEF(DRM_IOCTL_VERSION, drm_version, 0),
58 DRM_IOCTL_DEF(DRM_IOCTL_GET_UNIQUE, drm_getunique, 0),
59 DRM_IOCTL_DEF(DRM_IOCTL_GET_MAGIC, drm_getmagic, 0),
60 DRM_IOCTL_DEF(DRM_IOCTL_IRQ_BUSID, drm_irq_by_busid, DRM_MASTER|DRM_ROOT_ONLY),
61 DRM_IOCTL_DEF(DRM_IOCTL_GET_MAP, drm_getmap, 0),
62 DRM_IOCTL_DEF(DRM_IOCTL_GET_CLIENT, drm_getclient, 0),
63 DRM_IOCTL_DEF(DRM_IOCTL_GET_STATS, drm_getstats, 0),
64 DRM_IOCTL_DEF(DRM_IOCTL_SET_VERSION, drm_setversion, DRM_MASTER|DRM_ROOT_ONLY),
65
66 DRM_IOCTL_DEF(DRM_IOCTL_SET_UNIQUE, drm_setunique, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
67 DRM_IOCTL_DEF(DRM_IOCTL_BLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
68 DRM_IOCTL_DEF(DRM_IOCTL_UNBLOCK, drm_noop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
69 DRM_IOCTL_DEF(DRM_IOCTL_AUTH_MAGIC, drm_authmagic, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
70
71 DRM_IOCTL_DEF(DRM_IOCTL_ADD_MAP, drm_addmap_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
72 DRM_IOCTL_DEF(DRM_IOCTL_RM_MAP, drm_rmmap_ioctl, DRM_AUTH),
73
74 DRM_IOCTL_DEF(DRM_IOCTL_SET_SAREA_CTX, drm_setsareactx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
75 DRM_IOCTL_DEF(DRM_IOCTL_GET_SAREA_CTX, drm_getsareactx, DRM_AUTH),
76
77 DRM_IOCTL_DEF(DRM_IOCTL_ADD_CTX, drm_addctx, DRM_AUTH|DRM_ROOT_ONLY),
78 DRM_IOCTL_DEF(DRM_IOCTL_RM_CTX, drm_rmctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
79 DRM_IOCTL_DEF(DRM_IOCTL_MOD_CTX, drm_modctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
80 DRM_IOCTL_DEF(DRM_IOCTL_GET_CTX, drm_getctx, DRM_AUTH),
81 DRM_IOCTL_DEF(DRM_IOCTL_SWITCH_CTX, drm_switchctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
82 DRM_IOCTL_DEF(DRM_IOCTL_NEW_CTX, drm_newctx, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
83 DRM_IOCTL_DEF(DRM_IOCTL_RES_CTX, drm_resctx, DRM_AUTH),
84
85 DRM_IOCTL_DEF(DRM_IOCTL_ADD_DRAW, drm_adddraw, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
86 DRM_IOCTL_DEF(DRM_IOCTL_RM_DRAW, drm_rmdraw, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
87
88 DRM_IOCTL_DEF(DRM_IOCTL_LOCK, drm_lock, DRM_AUTH),
89 DRM_IOCTL_DEF(DRM_IOCTL_UNLOCK, drm_unlock, DRM_AUTH),
90
91 DRM_IOCTL_DEF(DRM_IOCTL_FINISH, drm_noop, DRM_AUTH),
92
93 DRM_IOCTL_DEF(DRM_IOCTL_ADD_BUFS, drm_addbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
94 DRM_IOCTL_DEF(DRM_IOCTL_MARK_BUFS, drm_markbufs, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
95 DRM_IOCTL_DEF(DRM_IOCTL_INFO_BUFS, drm_infobufs, DRM_AUTH),
96 DRM_IOCTL_DEF(DRM_IOCTL_MAP_BUFS, drm_mapbufs, DRM_AUTH),
97 DRM_IOCTL_DEF(DRM_IOCTL_FREE_BUFS, drm_freebufs, DRM_AUTH),
98 /* The DRM_IOCTL_DMA ioctl should be defined by the driver. */
99 DRM_IOCTL_DEF(DRM_IOCTL_DMA, NULL, DRM_AUTH),
100
101 DRM_IOCTL_DEF(DRM_IOCTL_CONTROL, drm_control, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
102
103#if __OS_HAS_AGP
104 DRM_IOCTL_DEF(DRM_IOCTL_AGP_ACQUIRE, drm_agp_acquire_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
105 DRM_IOCTL_DEF(DRM_IOCTL_AGP_RELEASE, drm_agp_release_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
106 DRM_IOCTL_DEF(DRM_IOCTL_AGP_ENABLE, drm_agp_enable_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
107 DRM_IOCTL_DEF(DRM_IOCTL_AGP_INFO, drm_agp_info_ioctl, DRM_AUTH),
108 DRM_IOCTL_DEF(DRM_IOCTL_AGP_ALLOC, drm_agp_alloc_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
109 DRM_IOCTL_DEF(DRM_IOCTL_AGP_FREE, drm_agp_free_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
110 DRM_IOCTL_DEF(DRM_IOCTL_AGP_BIND, drm_agp_bind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
111 DRM_IOCTL_DEF(DRM_IOCTL_AGP_UNBIND, drm_agp_unbind_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
112#endif
113
114 DRM_IOCTL_DEF(DRM_IOCTL_SG_ALLOC, drm_sg_alloc_ioctl, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
115 DRM_IOCTL_DEF(DRM_IOCTL_SG_FREE, drm_sg_free, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
116
117 DRM_IOCTL_DEF(DRM_IOCTL_WAIT_VBLANK, drm_wait_vblank, 0),
118
119 DRM_IOCTL_DEF(DRM_IOCTL_UPDATE_DRAW, drm_update_drawable_info, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
120};
121
122#define DRM_CORE_IOCTL_COUNT ARRAY_SIZE( drm_ioctls )
123
124/**
125 * Take down the DRM device.
126 *
127 * \param dev DRM device structure.
128 *
129 * Frees every resource in \p dev.
130 *
131 * \sa drm_device
132 */
133int drm_lastclose(struct drm_device * dev)
134{
135 struct drm_magic_entry *pt, *next;
136 struct drm_map_list *r_list, *list_t;
137 struct drm_vma_entry *vma, *vma_temp;
138 int i;
139
140 DRM_DEBUG("\n");
141
142 if (dev->driver->lastclose)
143 dev->driver->lastclose(dev);
144 DRM_DEBUG("driver lastclose completed\n");
145
146 if (dev->unique) {
147 drm_free(dev->unique, strlen(dev->unique) + 1, DRM_MEM_DRIVER);
148 dev->unique = NULL;
149 dev->unique_len = 0;
150 }
151
152 if (dev->irq_enabled)
153 drm_irq_uninstall(dev);
154
155 mutex_lock(&dev->struct_mutex);
156
157 /* Free drawable information memory */
158 drm_drawable_free_all(dev);
159 del_timer(&dev->timer);
160
161 /* Clear pid list */
162 if (dev->magicfree.next) {
163 list_for_each_entry_safe(pt, next, &dev->magicfree, head) {
164 list_del(&pt->head);
165 drm_ht_remove_item(&dev->magiclist, &pt->hash_item);
166 drm_free(pt, sizeof(*pt), DRM_MEM_MAGIC);
167 }
168 drm_ht_remove(&dev->magiclist);
169 }
170
171 /* Clear AGP information */
172 if (drm_core_has_AGP(dev) && dev->agp) {
173 struct drm_agp_mem *entry, *tempe;
174
175 /* Remove AGP resources, but leave dev->agp
176 intact until drv_cleanup is called. */
177 list_for_each_entry_safe(entry, tempe, &dev->agp->memory, head) {
178 if (entry->bound)
179 drm_unbind_agp(entry->memory);
180 drm_free_agp(entry->memory, entry->pages);
181 drm_free(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
182 }
183 INIT_LIST_HEAD(&dev->agp->memory);
184
185 if (dev->agp->acquired)
186 drm_agp_release(dev);
187
188 dev->agp->acquired = 0;
189 dev->agp->enabled = 0;
190 }
191 if (drm_core_check_feature(dev, DRIVER_SG) && dev->sg) {
192 drm_sg_cleanup(dev->sg);
193 dev->sg = NULL;
194 }
195
196 /* Clear vma list (only built for debugging) */
197 list_for_each_entry_safe(vma, vma_temp, &dev->vmalist, head) {
198 list_del(&vma->head);
199 drm_free(vma, sizeof(*vma), DRM_MEM_VMAS);
200 }
201
202 list_for_each_entry_safe(r_list, list_t, &dev->maplist, head) {
203 if (!(r_list->map->flags & _DRM_DRIVER)) {
204 drm_rmmap_locked(dev, r_list->map);
205 r_list = NULL;
206 }
207 }
208
209 if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE) && dev->queuelist) {
210 for (i = 0; i < dev->queue_count; i++) {
211 if (dev->queuelist[i]) {
212 drm_free(dev->queuelist[i],
213 sizeof(*dev->queuelist[0]),
214 DRM_MEM_QUEUES);
215 dev->queuelist[i] = NULL;
216 }
217 }
218 drm_free(dev->queuelist,
219 dev->queue_slots * sizeof(*dev->queuelist),
220 DRM_MEM_QUEUES);
221 dev->queuelist = NULL;
222 }
223 dev->queue_count = 0;
224
225 if (drm_core_check_feature(dev, DRIVER_HAVE_DMA))
226 drm_dma_takedown(dev);
227
228 if (dev->lock.hw_lock) {
229 dev->sigdata.lock = dev->lock.hw_lock = NULL; /* SHM removed */
230 dev->lock.file_priv = NULL;
231 wake_up_interruptible(&dev->lock.lock_queue);
232 }
233 mutex_unlock(&dev->struct_mutex);
234
235 DRM_DEBUG("lastclose completed\n");
236 return 0;
237}
238
239/**
240 * Module initialization. Called via init_module at module load time, or via
241 * linux/init/main.c (this is not currently supported).
242 *
243 * \return zero on success or a negative number on failure.
244 *
245 * Initializes an array of drm_device structures, and attempts to
246 * initialize all available devices, using consecutive minors, registering the
247 * stubs and initializing the AGP device.
248 *
249 * Expands the \c DRIVER_PREINIT and \c DRIVER_POST_INIT macros before and
250 * after the initialization for driver customization.
251 */
252int drm_init(struct drm_driver *driver)
253{
254 struct pci_dev *pdev = NULL;
255 struct pci_device_id *pid;
256 int i;
257
258 DRM_DEBUG("\n");
259
260 for (i = 0; driver->pci_driver.id_table[i].vendor != 0; i++) {
261 pid = (struct pci_device_id *)&driver->pci_driver.id_table[i];
262
263 pdev = NULL;
264 /* pass back in pdev to account for multiple identical cards */
265 while ((pdev =
266 pci_get_subsys(pid->vendor, pid->device, pid->subvendor,
267 pid->subdevice, pdev)) != NULL) {
268 /* stealth mode requires a manual probe */
269 pci_dev_get(pdev);
270 drm_get_dev(pdev, pid, driver);
271 }
272 }
273 return 0;
274}
275
276EXPORT_SYMBOL(drm_init);
277
278/**
279 * Called via cleanup_module() at module unload time.
280 *
281 * Cleans up all DRM device, calling drm_lastclose().
282 *
283 * \sa drm_init
284 */
285static void drm_cleanup(struct drm_device * dev)
286{
287 DRM_DEBUG("\n");
288
289 if (!dev) {
290 DRM_ERROR("cleanup called no dev\n");
291 return;
292 }
293
294 drm_lastclose(dev);
295
296 if (drm_core_has_MTRR(dev) && drm_core_has_AGP(dev) &&
297 dev->agp && dev->agp->agp_mtrr >= 0) {
298 int retval;
299 retval = mtrr_del(dev->agp->agp_mtrr,
300 dev->agp->agp_info.aper_base,
301 dev->agp->agp_info.aper_size * 1024 * 1024);
302 DRM_DEBUG("mtrr_del=%d\n", retval);
303 }
304
305 if (drm_core_has_AGP(dev) && dev->agp) {
306 drm_free(dev->agp, sizeof(*dev->agp), DRM_MEM_AGPLISTS);
307 dev->agp = NULL;
308 }
309
310 if (dev->driver->unload)
311 dev->driver->unload(dev);
312
313 drm_ht_remove(&dev->map_hash);
314 drm_ctxbitmap_cleanup(dev);
315
316 drm_put_minor(&dev->primary);
317 if (drm_put_dev(dev))
318 DRM_ERROR("Cannot unload module\n");
319}
320
321int drm_minors_cleanup(int id, void *ptr, void *data)
322{
323 struct drm_minor *minor = ptr;
324 struct drm_device *dev;
325 struct drm_driver *driver = data;
326
327 dev = minor->dev;
328 if (minor->dev->driver != driver)
329 return 0;
330
331 if (minor->type != DRM_MINOR_LEGACY)
332 return 0;
333
334 if (dev)
335 pci_dev_put(dev->pdev);
336 drm_cleanup(dev);
337 return 1;
338}
339
340void drm_exit(struct drm_driver *driver)
341{
342 DRM_DEBUG("\n");
343
344 idr_for_each(&drm_minors_idr, &drm_minors_cleanup, driver);
345
346 DRM_INFO("Module unloaded\n");
347}
348
349EXPORT_SYMBOL(drm_exit);
350
351/** File operations structure */
352static const struct file_operations drm_stub_fops = {
353 .owner = THIS_MODULE,
354 .open = drm_stub_open
355};
356
357static int __init drm_core_init(void)
358{
359 int ret = -ENOMEM;
360
361 idr_init(&drm_minors_idr);
362
363 if (register_chrdev(DRM_MAJOR, "drm", &drm_stub_fops))
364 goto err_p1;
365
366 drm_class = drm_sysfs_create(THIS_MODULE, "drm");
367 if (IS_ERR(drm_class)) {
368 printk(KERN_ERR "DRM: Error creating drm class.\n");
369 ret = PTR_ERR(drm_class);
370 goto err_p2;
371 }
372
373 drm_proc_root = proc_mkdir("dri", NULL);
374 if (!drm_proc_root) {
375 DRM_ERROR("Cannot create /proc/dri\n");
376 ret = -1;
377 goto err_p3;
378 }
379
380 drm_mem_init();
381
382 DRM_INFO("Initialized %s %d.%d.%d %s\n",
383 CORE_NAME, CORE_MAJOR, CORE_MINOR, CORE_PATCHLEVEL, CORE_DATE);
384 return 0;
385err_p3:
386 drm_sysfs_destroy();
387err_p2:
388 unregister_chrdev(DRM_MAJOR, "drm");
389
390 idr_destroy(&drm_minors_idr);
391err_p1:
392 return ret;
393}
394
395static void __exit drm_core_exit(void)
396{
397 remove_proc_entry("dri", NULL);
398 drm_sysfs_destroy();
399
400 unregister_chrdev(DRM_MAJOR, "drm");
401
402 idr_destroy(&drm_minors_idr);
403}
404
405module_init(drm_core_init);
406module_exit(drm_core_exit);
407
408/**
409 * Get version information
410 *
411 * \param inode device inode.
412 * \param filp file pointer.
413 * \param cmd command.
414 * \param arg user argument, pointing to a drm_version structure.
415 * \return zero on success or negative number on failure.
416 *
417 * Fills in the version information in \p arg.
418 */
419static int drm_version(struct drm_device *dev, void *data,
420 struct drm_file *file_priv)
421{
422 struct drm_version *version = data;
423 int len;
424
425 version->version_major = dev->driver->major;
426 version->version_minor = dev->driver->minor;
427 version->version_patchlevel = dev->driver->patchlevel;
428 DRM_COPY(version->name, dev->driver->name);
429 DRM_COPY(version->date, dev->driver->date);
430 DRM_COPY(version->desc, dev->driver->desc);
431
432 return 0;
433}
434
435/**
436 * Called whenever a process performs an ioctl on /dev/drm.
437 *
438 * \param inode device inode.
439 * \param file_priv DRM file private.
440 * \param cmd command.
441 * \param arg user argument.
442 * \return zero on success or negative number on failure.
443 *
444 * Looks up the ioctl function in the ::ioctls table, checking for root
445 * previleges if so required, and dispatches to the respective function.
446 */
447int drm_ioctl(struct inode *inode, struct file *filp,
448 unsigned int cmd, unsigned long arg)
449{
450 struct drm_file *file_priv = filp->private_data;
451 struct drm_device *dev = file_priv->minor->dev;
452 struct drm_ioctl_desc *ioctl;
453 drm_ioctl_t *func;
454 unsigned int nr = DRM_IOCTL_NR(cmd);
455 int retcode = -EINVAL;
456 char *kdata = NULL;
457
458 atomic_inc(&dev->ioctl_count);
459 atomic_inc(&dev->counts[_DRM_STAT_IOCTLS]);
460 ++file_priv->ioctl_count;
461
462 DRM_DEBUG("pid=%d, cmd=0x%02x, nr=0x%02x, dev 0x%lx, auth=%d\n",
463 task_pid_nr(current), cmd, nr,
464 (long)old_encode_dev(file_priv->minor->device),
465 file_priv->authenticated);
466
467 if ((nr >= DRM_CORE_IOCTL_COUNT) &&
468 ((nr < DRM_COMMAND_BASE) || (nr >= DRM_COMMAND_END)))
469 goto err_i1;
470 if ((nr >= DRM_COMMAND_BASE) && (nr < DRM_COMMAND_END) &&
471 (nr < DRM_COMMAND_BASE + dev->driver->num_ioctls))
472 ioctl = &dev->driver->ioctls[nr - DRM_COMMAND_BASE];
473 else if ((nr >= DRM_COMMAND_END) || (nr < DRM_COMMAND_BASE))
474 ioctl = &drm_ioctls[nr];
475 else
476 goto err_i1;
477
478 func = ioctl->func;
479 /* is there a local override? */
480 if ((nr == DRM_IOCTL_NR(DRM_IOCTL_DMA)) && dev->driver->dma_ioctl)
481 func = dev->driver->dma_ioctl;
482
483
484 if (!func) {
485 DRM_DEBUG("no function\n");
486 retcode = -EINVAL;
487 } else if (((ioctl->flags & DRM_ROOT_ONLY) && !capable(CAP_SYS_ADMIN)) ||
488 ((ioctl->flags & DRM_AUTH) && !file_priv->authenticated) ||
489 ((ioctl->flags & DRM_MASTER) && !file_priv->master)) {
490 retcode = -EACCES;
491 } else {
492 if (cmd & (IOC_IN | IOC_OUT)) {
493 kdata = kmalloc(_IOC_SIZE(cmd), GFP_KERNEL);
494 if (!kdata) {
495 retcode = -ENOMEM;
496 goto err_i1;
497 }
498 }
499
500 if (cmd & IOC_IN) {
501 if (copy_from_user(kdata, (void __user *)arg,
502 _IOC_SIZE(cmd)) != 0) {
503 retcode = -EFAULT;
504 goto err_i1;
505 }
506 }
507 retcode = func(dev, kdata, file_priv);
508
509 if ((retcode == 0) && (cmd & IOC_OUT)) {
510 if (copy_to_user((void __user *)arg, kdata,
511 _IOC_SIZE(cmd)) != 0)
512 retcode = -EFAULT;
513 }
514 }
515
516 err_i1:
517 if (kdata)
518 kfree(kdata);
519 atomic_dec(&dev->ioctl_count);
520 if (retcode)
521 DRM_DEBUG("ret = %x\n", retcode);
522 return retcode;
523}
524
525EXPORT_SYMBOL(drm_ioctl);
526
527drm_local_map_t *drm_getsarea(struct drm_device *dev)
528{
529 struct drm_map_list *entry;
530
531 list_for_each_entry(entry, &dev->maplist, head) {
532 if (entry->map && entry->map->type == _DRM_SHM &&
533 (entry->map->flags & _DRM_CONTAINS_LOCK)) {
534 return entry->map;
535 }
536 }
537 return NULL;
538}
539EXPORT_SYMBOL(drm_getsarea);
diff --git a/drivers/char/drm/drm_fops.c b/drivers/char/drm/drm_fops.c
deleted file mode 100644
index 68f0da801ed8..000000000000
--- a/drivers/char/drm/drm_fops.c
+++ /dev/null
@@ -1,469 +0,0 @@
1/**
2 * \file drm_fops.c
3 * File operations for DRM
4 *
5 * \author Rickard E. (Rik) Faith <faith@valinux.com>
6 * \author Daryll Strauss <daryll@valinux.com>
7 * \author Gareth Hughes <gareth@valinux.com>
8 */
9
10/*
11 * Created: Mon Jan 4 08:58:31 1999 by faith@valinux.com
12 *
13 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
14 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
15 * All Rights Reserved.
16 *
17 * Permission is hereby granted, free of charge, to any person obtaining a
18 * copy of this software and associated documentation files (the "Software"),
19 * to deal in the Software without restriction, including without limitation
20 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
21 * and/or sell copies of the Software, and to permit persons to whom the
22 * Software is furnished to do so, subject to the following conditions:
23 *
24 * The above copyright notice and this permission notice (including the next
25 * paragraph) shall be included in all copies or substantial portions of the
26 * Software.
27 *
28 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
29 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
30 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
31 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
32 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
33 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
34 * OTHER DEALINGS IN THE SOFTWARE.
35 */
36
37#include "drmP.h"
38#include "drm_sarea.h"
39#include <linux/poll.h>
40
41static int drm_open_helper(struct inode *inode, struct file *filp,
42 struct drm_device * dev);
43
44static int drm_setup(struct drm_device * dev)
45{
46 drm_local_map_t *map;
47 int i;
48 int ret;
49 u32 sareapage;
50
51 if (dev->driver->firstopen) {
52 ret = dev->driver->firstopen(dev);
53 if (ret != 0)
54 return ret;
55 }
56
57 dev->magicfree.next = NULL;
58
59 /* prebuild the SAREA */
60 sareapage = max_t(unsigned, SAREA_MAX, PAGE_SIZE);
61 i = drm_addmap(dev, 0, sareapage, _DRM_SHM, _DRM_CONTAINS_LOCK, &map);
62 if (i != 0)
63 return i;
64
65 atomic_set(&dev->ioctl_count, 0);
66 atomic_set(&dev->vma_count, 0);
67 dev->buf_use = 0;
68 atomic_set(&dev->buf_alloc, 0);
69
70 if (drm_core_check_feature(dev, DRIVER_HAVE_DMA)) {
71 i = drm_dma_setup(dev);
72 if (i < 0)
73 return i;
74 }
75
76 for (i = 0; i < ARRAY_SIZE(dev->counts); i++)
77 atomic_set(&dev->counts[i], 0);
78
79 drm_ht_create(&dev->magiclist, DRM_MAGIC_HASH_ORDER);
80 INIT_LIST_HEAD(&dev->magicfree);
81
82 dev->sigdata.lock = NULL;
83 init_waitqueue_head(&dev->lock.lock_queue);
84 dev->queue_count = 0;
85 dev->queue_reserved = 0;
86 dev->queue_slots = 0;
87 dev->queuelist = NULL;
88 dev->irq_enabled = 0;
89 dev->context_flag = 0;
90 dev->interrupt_flag = 0;
91 dev->dma_flag = 0;
92 dev->last_context = 0;
93 dev->last_switch = 0;
94 dev->last_checked = 0;
95 init_waitqueue_head(&dev->context_wait);
96 dev->if_version = 0;
97
98 dev->ctx_start = 0;
99 dev->lck_start = 0;
100
101 dev->buf_async = NULL;
102 init_waitqueue_head(&dev->buf_readers);
103 init_waitqueue_head(&dev->buf_writers);
104
105 DRM_DEBUG("\n");
106
107 /*
108 * The kernel's context could be created here, but is now created
109 * in drm_dma_enqueue. This is more resource-efficient for
110 * hardware that does not do DMA, but may mean that
111 * drm_select_queue fails between the time the interrupt is
112 * initialized and the time the queues are initialized.
113 */
114
115 return 0;
116}
117
118/**
119 * Open file.
120 *
121 * \param inode device inode
122 * \param filp file pointer.
123 * \return zero on success or a negative number on failure.
124 *
125 * Searches the DRM device with the same minor number, calls open_helper(), and
126 * increments the device open count. If the open count was previous at zero,
127 * i.e., it's the first that the device is open, then calls setup().
128 */
129int drm_open(struct inode *inode, struct file *filp)
130{
131 struct drm_device *dev = NULL;
132 int minor_id = iminor(inode);
133 struct drm_minor *minor;
134 int retcode = 0;
135
136 minor = idr_find(&drm_minors_idr, minor_id);
137 if (!minor)
138 return -ENODEV;
139
140 if (!(dev = minor->dev))
141 return -ENODEV;
142
143 retcode = drm_open_helper(inode, filp, dev);
144 if (!retcode) {
145 atomic_inc(&dev->counts[_DRM_STAT_OPENS]);
146 spin_lock(&dev->count_lock);
147 if (!dev->open_count++) {
148 spin_unlock(&dev->count_lock);
149 return drm_setup(dev);
150 }
151 spin_unlock(&dev->count_lock);
152 }
153
154 return retcode;
155}
156EXPORT_SYMBOL(drm_open);
157
158/**
159 * File \c open operation.
160 *
161 * \param inode device inode.
162 * \param filp file pointer.
163 *
164 * Puts the dev->fops corresponding to the device minor number into
165 * \p filp, call the \c open method, and restore the file operations.
166 */
167int drm_stub_open(struct inode *inode, struct file *filp)
168{
169 struct drm_device *dev = NULL;
170 struct drm_minor *minor;
171 int minor_id = iminor(inode);
172 int err = -ENODEV;
173 const struct file_operations *old_fops;
174
175 DRM_DEBUG("\n");
176
177 minor = idr_find(&drm_minors_idr, minor_id);
178 if (!minor)
179 return -ENODEV;
180
181 if (!(dev = minor->dev))
182 return -ENODEV;
183
184 old_fops = filp->f_op;
185 filp->f_op = fops_get(&dev->driver->fops);
186 if (filp->f_op->open && (err = filp->f_op->open(inode, filp))) {
187 fops_put(filp->f_op);
188 filp->f_op = fops_get(old_fops);
189 }
190 fops_put(old_fops);
191
192 return err;
193}
194
195/**
196 * Check whether DRI will run on this CPU.
197 *
198 * \return non-zero if the DRI will run on this CPU, or zero otherwise.
199 */
200static int drm_cpu_valid(void)
201{
202#if defined(__i386__)
203 if (boot_cpu_data.x86 == 3)
204 return 0; /* No cmpxchg on a 386 */
205#endif
206#if defined(__sparc__) && !defined(__sparc_v9__)
207 return 0; /* No cmpxchg before v9 sparc. */
208#endif
209 return 1;
210}
211
212/**
213 * Called whenever a process opens /dev/drm.
214 *
215 * \param inode device inode.
216 * \param filp file pointer.
217 * \param dev device.
218 * \return zero on success or a negative number on failure.
219 *
220 * Creates and initializes a drm_file structure for the file private data in \p
221 * filp and add it into the double linked list in \p dev.
222 */
223static int drm_open_helper(struct inode *inode, struct file *filp,
224 struct drm_device * dev)
225{
226 int minor_id = iminor(inode);
227 struct drm_file *priv;
228 int ret;
229
230 if (filp->f_flags & O_EXCL)
231 return -EBUSY; /* No exclusive opens */
232 if (!drm_cpu_valid())
233 return -EINVAL;
234
235 DRM_DEBUG("pid = %d, minor = %d\n", task_pid_nr(current), minor_id);
236
237 priv = drm_alloc(sizeof(*priv), DRM_MEM_FILES);
238 if (!priv)
239 return -ENOMEM;
240
241 memset(priv, 0, sizeof(*priv));
242 filp->private_data = priv;
243 priv->filp = filp;
244 priv->uid = current->euid;
245 priv->pid = task_pid_nr(current);
246 priv->minor = idr_find(&drm_minors_idr, minor_id);
247 priv->ioctl_count = 0;
248 /* for compatibility root is always authenticated */
249 priv->authenticated = capable(CAP_SYS_ADMIN);
250 priv->lock_count = 0;
251
252 INIT_LIST_HEAD(&priv->lhead);
253
254 if (dev->driver->open) {
255 ret = dev->driver->open(dev, priv);
256 if (ret < 0)
257 goto out_free;
258 }
259
260 mutex_lock(&dev->struct_mutex);
261 if (list_empty(&dev->filelist))
262 priv->master = 1;
263
264 list_add(&priv->lhead, &dev->filelist);
265 mutex_unlock(&dev->struct_mutex);
266
267#ifdef __alpha__
268 /*
269 * Default the hose
270 */
271 if (!dev->hose) {
272 struct pci_dev *pci_dev;
273 pci_dev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, NULL);
274 if (pci_dev) {
275 dev->hose = pci_dev->sysdata;
276 pci_dev_put(pci_dev);
277 }
278 if (!dev->hose) {
279 struct pci_bus *b = pci_bus_b(pci_root_buses.next);
280 if (b)
281 dev->hose = b->sysdata;
282 }
283 }
284#endif
285
286 return 0;
287 out_free:
288 drm_free(priv, sizeof(*priv), DRM_MEM_FILES);
289 filp->private_data = NULL;
290 return ret;
291}
292
293/** No-op. */
294int drm_fasync(int fd, struct file *filp, int on)
295{
296 struct drm_file *priv = filp->private_data;
297 struct drm_device *dev = priv->minor->dev;
298 int retcode;
299
300 DRM_DEBUG("fd = %d, device = 0x%lx\n", fd,
301 (long)old_encode_dev(priv->minor->device));
302 retcode = fasync_helper(fd, filp, on, &dev->buf_async);
303 if (retcode < 0)
304 return retcode;
305 return 0;
306}
307EXPORT_SYMBOL(drm_fasync);
308
309/**
310 * Release file.
311 *
312 * \param inode device inode
313 * \param file_priv DRM file private.
314 * \return zero on success or a negative number on failure.
315 *
316 * If the hardware lock is held then free it, and take it again for the kernel
317 * context since it's necessary to reclaim buffers. Unlink the file private
318 * data from its list and free it. Decreases the open count and if it reaches
319 * zero calls drm_lastclose().
320 */
321int drm_release(struct inode *inode, struct file *filp)
322{
323 struct drm_file *file_priv = filp->private_data;
324 struct drm_device *dev = file_priv->minor->dev;
325 int retcode = 0;
326 unsigned long irqflags;
327
328 lock_kernel();
329
330 DRM_DEBUG("open_count = %d\n", dev->open_count);
331
332 if (dev->driver->preclose)
333 dev->driver->preclose(dev, file_priv);
334
335 /* ========================================================
336 * Begin inline drm_release
337 */
338
339 DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n",
340 task_pid_nr(current),
341 (long)old_encode_dev(file_priv->minor->device),
342 dev->open_count);
343
344 if (dev->driver->reclaim_buffers_locked && dev->lock.hw_lock) {
345 if (drm_i_have_hw_lock(dev, file_priv)) {
346 dev->driver->reclaim_buffers_locked(dev, file_priv);
347 } else {
348 unsigned long endtime = jiffies + 3 * DRM_HZ;
349 int locked = 0;
350
351 drm_idlelock_take(&dev->lock);
352
353 /*
354 * Wait for a while.
355 */
356
357 do{
358 spin_lock_irqsave(&dev->lock.spinlock,
359 irqflags);
360 locked = dev->lock.idle_has_lock;
361 spin_unlock_irqrestore(&dev->lock.spinlock,
362 irqflags);
363 if (locked)
364 break;
365 schedule();
366 } while (!time_after_eq(jiffies, endtime));
367
368 if (!locked) {
369 DRM_ERROR("reclaim_buffers_locked() deadlock. Please rework this\n"
370 "\tdriver to use reclaim_buffers_idlelocked() instead.\n"
371 "\tI will go on reclaiming the buffers anyway.\n");
372 }
373
374 dev->driver->reclaim_buffers_locked(dev, file_priv);
375 drm_idlelock_release(&dev->lock);
376 }
377 }
378
379 if (dev->driver->reclaim_buffers_idlelocked && dev->lock.hw_lock) {
380
381 drm_idlelock_take(&dev->lock);
382 dev->driver->reclaim_buffers_idlelocked(dev, file_priv);
383 drm_idlelock_release(&dev->lock);
384
385 }
386
387 if (drm_i_have_hw_lock(dev, file_priv)) {
388 DRM_DEBUG("File %p released, freeing lock for context %d\n",
389 filp, _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
390
391 drm_lock_free(&dev->lock,
392 _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock));
393 }
394
395
396 if (drm_core_check_feature(dev, DRIVER_HAVE_DMA) &&
397 !dev->driver->reclaim_buffers_locked) {
398 dev->driver->reclaim_buffers(dev, file_priv);
399 }
400
401 drm_fasync(-1, filp, 0);
402
403 mutex_lock(&dev->ctxlist_mutex);
404 if (!list_empty(&dev->ctxlist)) {
405 struct drm_ctx_list *pos, *n;
406
407 list_for_each_entry_safe(pos, n, &dev->ctxlist, head) {
408 if (pos->tag == file_priv &&
409 pos->handle != DRM_KERNEL_CONTEXT) {
410 if (dev->driver->context_dtor)
411 dev->driver->context_dtor(dev,
412 pos->handle);
413
414 drm_ctxbitmap_free(dev, pos->handle);
415
416 list_del(&pos->head);
417 drm_free(pos, sizeof(*pos), DRM_MEM_CTXLIST);
418 --dev->ctx_count;
419 }
420 }
421 }
422 mutex_unlock(&dev->ctxlist_mutex);
423
424 mutex_lock(&dev->struct_mutex);
425 if (file_priv->remove_auth_on_close == 1) {
426 struct drm_file *temp;
427
428 list_for_each_entry(temp, &dev->filelist, lhead)
429 temp->authenticated = 0;
430 }
431 list_del(&file_priv->lhead);
432 mutex_unlock(&dev->struct_mutex);
433
434 if (dev->driver->postclose)
435 dev->driver->postclose(dev, file_priv);
436 drm_free(file_priv, sizeof(*file_priv), DRM_MEM_FILES);
437
438 /* ========================================================
439 * End inline drm_release
440 */
441
442 atomic_inc(&dev->counts[_DRM_STAT_CLOSES]);
443 spin_lock(&dev->count_lock);
444 if (!--dev->open_count) {
445 if (atomic_read(&dev->ioctl_count) || dev->blocked) {
446 DRM_ERROR("Device busy: %d %d\n",
447 atomic_read(&dev->ioctl_count), dev->blocked);
448 spin_unlock(&dev->count_lock);
449 unlock_kernel();
450 return -EBUSY;
451 }
452 spin_unlock(&dev->count_lock);
453 unlock_kernel();
454 return drm_lastclose(dev);
455 }
456 spin_unlock(&dev->count_lock);
457
458 unlock_kernel();
459
460 return retcode;
461}
462EXPORT_SYMBOL(drm_release);
463
464/** No-op. */
465unsigned int drm_poll(struct file *filp, struct poll_table_struct *wait)
466{
467 return 0;
468}
469EXPORT_SYMBOL(drm_poll);
diff --git a/drivers/char/drm/drm_hashtab.c b/drivers/char/drm/drm_hashtab.c
deleted file mode 100644
index 33160673a7b7..000000000000
--- a/drivers/char/drm/drm_hashtab.c
+++ /dev/null
@@ -1,202 +0,0 @@
1/**************************************************************************
2 *
3 * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND. USA.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
22 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24 * USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 *
27 **************************************************************************/
28/*
29 * Simple open hash tab implementation.
30 *
31 * Authors:
32 * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
33 */
34
35#include "drmP.h"
36#include "drm_hashtab.h"
37#include <linux/hash.h>
38
39int drm_ht_create(struct drm_open_hash *ht, unsigned int order)
40{
41 unsigned int i;
42
43 ht->size = 1 << order;
44 ht->order = order;
45 ht->fill = 0;
46 ht->table = NULL;
47 ht->use_vmalloc = ((ht->size * sizeof(*ht->table)) > PAGE_SIZE);
48 if (!ht->use_vmalloc) {
49 ht->table = drm_calloc(ht->size, sizeof(*ht->table),
50 DRM_MEM_HASHTAB);
51 }
52 if (!ht->table) {
53 ht->use_vmalloc = 1;
54 ht->table = vmalloc(ht->size*sizeof(*ht->table));
55 }
56 if (!ht->table) {
57 DRM_ERROR("Out of memory for hash table\n");
58 return -ENOMEM;
59 }
60 for (i=0; i< ht->size; ++i) {
61 INIT_HLIST_HEAD(&ht->table[i]);
62 }
63 return 0;
64}
65
66void drm_ht_verbose_list(struct drm_open_hash *ht, unsigned long key)
67{
68 struct drm_hash_item *entry;
69 struct hlist_head *h_list;
70 struct hlist_node *list;
71 unsigned int hashed_key;
72 int count = 0;
73
74 hashed_key = hash_long(key, ht->order);
75 DRM_DEBUG("Key is 0x%08lx, Hashed key is 0x%08x\n", key, hashed_key);
76 h_list = &ht->table[hashed_key];
77 hlist_for_each(list, h_list) {
78 entry = hlist_entry(list, struct drm_hash_item, head);
79 DRM_DEBUG("count %d, key: 0x%08lx\n", count++, entry->key);
80 }
81}
82
83static struct hlist_node *drm_ht_find_key(struct drm_open_hash *ht,
84 unsigned long key)
85{
86 struct drm_hash_item *entry;
87 struct hlist_head *h_list;
88 struct hlist_node *list;
89 unsigned int hashed_key;
90
91 hashed_key = hash_long(key, ht->order);
92 h_list = &ht->table[hashed_key];
93 hlist_for_each(list, h_list) {
94 entry = hlist_entry(list, struct drm_hash_item, head);
95 if (entry->key == key)
96 return list;
97 if (entry->key > key)
98 break;
99 }
100 return NULL;
101}
102
103
104int drm_ht_insert_item(struct drm_open_hash *ht, struct drm_hash_item *item)
105{
106 struct drm_hash_item *entry;
107 struct hlist_head *h_list;
108 struct hlist_node *list, *parent;
109 unsigned int hashed_key;
110 unsigned long key = item->key;
111
112 hashed_key = hash_long(key, ht->order);
113 h_list = &ht->table[hashed_key];
114 parent = NULL;
115 hlist_for_each(list, h_list) {
116 entry = hlist_entry(list, struct drm_hash_item, head);
117 if (entry->key == key)
118 return -EINVAL;
119 if (entry->key > key)
120 break;
121 parent = list;
122 }
123 if (parent) {
124 hlist_add_after(parent, &item->head);
125 } else {
126 hlist_add_head(&item->head, h_list);
127 }
128 return 0;
129}
130
131/*
132 * Just insert an item and return any "bits" bit key that hasn't been
133 * used before.
134 */
135int drm_ht_just_insert_please(struct drm_open_hash *ht, struct drm_hash_item *item,
136 unsigned long seed, int bits, int shift,
137 unsigned long add)
138{
139 int ret;
140 unsigned long mask = (1 << bits) - 1;
141 unsigned long first, unshifted_key;
142
143 unshifted_key = hash_long(seed, bits);
144 first = unshifted_key;
145 do {
146 item->key = (unshifted_key << shift) + add;
147 ret = drm_ht_insert_item(ht, item);
148 if (ret)
149 unshifted_key = (unshifted_key + 1) & mask;
150 } while(ret && (unshifted_key != first));
151
152 if (ret) {
153 DRM_ERROR("Available key bit space exhausted\n");
154 return -EINVAL;
155 }
156 return 0;
157}
158
159int drm_ht_find_item(struct drm_open_hash *ht, unsigned long key,
160 struct drm_hash_item **item)
161{
162 struct hlist_node *list;
163
164 list = drm_ht_find_key(ht, key);
165 if (!list)
166 return -EINVAL;
167
168 *item = hlist_entry(list, struct drm_hash_item, head);
169 return 0;
170}
171
172int drm_ht_remove_key(struct drm_open_hash *ht, unsigned long key)
173{
174 struct hlist_node *list;
175
176 list = drm_ht_find_key(ht, key);
177 if (list) {
178 hlist_del_init(list);
179 ht->fill--;
180 return 0;
181 }
182 return -EINVAL;
183}
184
185int drm_ht_remove_item(struct drm_open_hash *ht, struct drm_hash_item *item)
186{
187 hlist_del_init(&item->head);
188 ht->fill--;
189 return 0;
190}
191
192void drm_ht_remove(struct drm_open_hash *ht)
193{
194 if (ht->table) {
195 if (ht->use_vmalloc)
196 vfree(ht->table);
197 else
198 drm_free(ht->table, ht->size * sizeof(*ht->table),
199 DRM_MEM_HASHTAB);
200 ht->table = NULL;
201 }
202}
diff --git a/drivers/char/drm/drm_hashtab.h b/drivers/char/drm/drm_hashtab.h
deleted file mode 100644
index cd2b189e1be6..000000000000
--- a/drivers/char/drm/drm_hashtab.h
+++ /dev/null
@@ -1,67 +0,0 @@
1/**************************************************************************
2 *
3 * Copyright 2006 Tungsten Graphics, Inc., Bismack, ND. USA.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
22 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24 * USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 *
27 **************************************************************************/
28/*
29 * Simple open hash tab implementation.
30 *
31 * Authors:
32 * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
33 */
34
35#ifndef DRM_HASHTAB_H
36#define DRM_HASHTAB_H
37
38#define drm_hash_entry(_ptr, _type, _member) container_of(_ptr, _type, _member)
39
40struct drm_hash_item {
41 struct hlist_node head;
42 unsigned long key;
43};
44
45struct drm_open_hash {
46 unsigned int size;
47 unsigned int order;
48 unsigned int fill;
49 struct hlist_head *table;
50 int use_vmalloc;
51};
52
53
54extern int drm_ht_create(struct drm_open_hash *ht, unsigned int order);
55extern int drm_ht_insert_item(struct drm_open_hash *ht, struct drm_hash_item *item);
56extern int drm_ht_just_insert_please(struct drm_open_hash *ht, struct drm_hash_item *item,
57 unsigned long seed, int bits, int shift,
58 unsigned long add);
59extern int drm_ht_find_item(struct drm_open_hash *ht, unsigned long key, struct drm_hash_item **item);
60
61extern void drm_ht_verbose_list(struct drm_open_hash *ht, unsigned long key);
62extern int drm_ht_remove_key(struct drm_open_hash *ht, unsigned long key);
63extern int drm_ht_remove_item(struct drm_open_hash *ht, struct drm_hash_item *item);
64extern void drm_ht_remove(struct drm_open_hash *ht);
65
66
67#endif
diff --git a/drivers/char/drm/drm_ioc32.c b/drivers/char/drm/drm_ioc32.c
deleted file mode 100644
index 90f5a8d9bdcb..000000000000
--- a/drivers/char/drm/drm_ioc32.c
+++ /dev/null
@@ -1,1073 +0,0 @@
1/**
2 * \file drm_ioc32.c
3 *
4 * 32-bit ioctl compatibility routines for the DRM.
5 *
6 * \author Paul Mackerras <paulus@samba.org>
7 *
8 * Copyright (C) Paul Mackerras 2005.
9 * All Rights Reserved.
10 *
11 * Permission is hereby granted, free of charge, to any person obtaining a
12 * copy of this software and associated documentation files (the "Software"),
13 * to deal in the Software without restriction, including without limitation
14 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 * and/or sell copies of the Software, and to permit persons to whom the
16 * Software is furnished to do so, subject to the following conditions:
17 *
18 * The above copyright notice and this permission notice (including the next
19 * paragraph) shall be included in all copies or substantial portions of the
20 * Software.
21 *
22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25 * THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
26 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
28 * IN THE SOFTWARE.
29 */
30#include <linux/compat.h>
31
32#include "drmP.h"
33#include "drm_core.h"
34
35#define DRM_IOCTL_VERSION32 DRM_IOWR(0x00, drm_version32_t)
36#define DRM_IOCTL_GET_UNIQUE32 DRM_IOWR(0x01, drm_unique32_t)
37#define DRM_IOCTL_GET_MAP32 DRM_IOWR(0x04, drm_map32_t)
38#define DRM_IOCTL_GET_CLIENT32 DRM_IOWR(0x05, drm_client32_t)
39#define DRM_IOCTL_GET_STATS32 DRM_IOR( 0x06, drm_stats32_t)
40
41#define DRM_IOCTL_SET_UNIQUE32 DRM_IOW( 0x10, drm_unique32_t)
42#define DRM_IOCTL_ADD_MAP32 DRM_IOWR(0x15, drm_map32_t)
43#define DRM_IOCTL_ADD_BUFS32 DRM_IOWR(0x16, drm_buf_desc32_t)
44#define DRM_IOCTL_MARK_BUFS32 DRM_IOW( 0x17, drm_buf_desc32_t)
45#define DRM_IOCTL_INFO_BUFS32 DRM_IOWR(0x18, drm_buf_info32_t)
46#define DRM_IOCTL_MAP_BUFS32 DRM_IOWR(0x19, drm_buf_map32_t)
47#define DRM_IOCTL_FREE_BUFS32 DRM_IOW( 0x1a, drm_buf_free32_t)
48
49#define DRM_IOCTL_RM_MAP32 DRM_IOW( 0x1b, drm_map32_t)
50
51#define DRM_IOCTL_SET_SAREA_CTX32 DRM_IOW( 0x1c, drm_ctx_priv_map32_t)
52#define DRM_IOCTL_GET_SAREA_CTX32 DRM_IOWR(0x1d, drm_ctx_priv_map32_t)
53
54#define DRM_IOCTL_RES_CTX32 DRM_IOWR(0x26, drm_ctx_res32_t)
55#define DRM_IOCTL_DMA32 DRM_IOWR(0x29, drm_dma32_t)
56
57#define DRM_IOCTL_AGP_ENABLE32 DRM_IOW( 0x32, drm_agp_mode32_t)
58#define DRM_IOCTL_AGP_INFO32 DRM_IOR( 0x33, drm_agp_info32_t)
59#define DRM_IOCTL_AGP_ALLOC32 DRM_IOWR(0x34, drm_agp_buffer32_t)
60#define DRM_IOCTL_AGP_FREE32 DRM_IOW( 0x35, drm_agp_buffer32_t)
61#define DRM_IOCTL_AGP_BIND32 DRM_IOW( 0x36, drm_agp_binding32_t)
62#define DRM_IOCTL_AGP_UNBIND32 DRM_IOW( 0x37, drm_agp_binding32_t)
63
64#define DRM_IOCTL_SG_ALLOC32 DRM_IOW( 0x38, drm_scatter_gather32_t)
65#define DRM_IOCTL_SG_FREE32 DRM_IOW( 0x39, drm_scatter_gather32_t)
66
67#define DRM_IOCTL_WAIT_VBLANK32 DRM_IOWR(0x3a, drm_wait_vblank32_t)
68
69typedef struct drm_version_32 {
70 int version_major; /**< Major version */
71 int version_minor; /**< Minor version */
72 int version_patchlevel; /**< Patch level */
73 u32 name_len; /**< Length of name buffer */
74 u32 name; /**< Name of driver */
75 u32 date_len; /**< Length of date buffer */
76 u32 date; /**< User-space buffer to hold date */
77 u32 desc_len; /**< Length of desc buffer */
78 u32 desc; /**< User-space buffer to hold desc */
79} drm_version32_t;
80
81static int compat_drm_version(struct file *file, unsigned int cmd,
82 unsigned long arg)
83{
84 drm_version32_t v32;
85 struct drm_version __user *version;
86 int err;
87
88 if (copy_from_user(&v32, (void __user *)arg, sizeof(v32)))
89 return -EFAULT;
90
91 version = compat_alloc_user_space(sizeof(*version));
92 if (!access_ok(VERIFY_WRITE, version, sizeof(*version)))
93 return -EFAULT;
94 if (__put_user(v32.name_len, &version->name_len)
95 || __put_user((void __user *)(unsigned long)v32.name,
96 &version->name)
97 || __put_user(v32.date_len, &version->date_len)
98 || __put_user((void __user *)(unsigned long)v32.date,
99 &version->date)
100 || __put_user(v32.desc_len, &version->desc_len)
101 || __put_user((void __user *)(unsigned long)v32.desc,
102 &version->desc))
103 return -EFAULT;
104
105 err = drm_ioctl(file->f_path.dentry->d_inode, file,
106 DRM_IOCTL_VERSION, (unsigned long)version);
107 if (err)
108 return err;
109
110 if (__get_user(v32.version_major, &version->version_major)
111 || __get_user(v32.version_minor, &version->version_minor)
112 || __get_user(v32.version_patchlevel, &version->version_patchlevel)
113 || __get_user(v32.name_len, &version->name_len)
114 || __get_user(v32.date_len, &version->date_len)
115 || __get_user(v32.desc_len, &version->desc_len))
116 return -EFAULT;
117
118 if (copy_to_user((void __user *)arg, &v32, sizeof(v32)))
119 return -EFAULT;
120 return 0;
121}
122
123typedef struct drm_unique32 {
124 u32 unique_len; /**< Length of unique */
125 u32 unique; /**< Unique name for driver instantiation */
126} drm_unique32_t;
127
128static int compat_drm_getunique(struct file *file, unsigned int cmd,
129 unsigned long arg)
130{
131 drm_unique32_t uq32;
132 struct drm_unique __user *u;
133 int err;
134
135 if (copy_from_user(&uq32, (void __user *)arg, sizeof(uq32)))
136 return -EFAULT;
137
138 u = compat_alloc_user_space(sizeof(*u));
139 if (!access_ok(VERIFY_WRITE, u, sizeof(*u)))
140 return -EFAULT;
141 if (__put_user(uq32.unique_len, &u->unique_len)
142 || __put_user((void __user *)(unsigned long)uq32.unique,
143 &u->unique))
144 return -EFAULT;
145
146 err = drm_ioctl(file->f_path.dentry->d_inode, file,
147 DRM_IOCTL_GET_UNIQUE, (unsigned long)u);
148 if (err)
149 return err;
150
151 if (__get_user(uq32.unique_len, &u->unique_len))
152 return -EFAULT;
153 if (copy_to_user((void __user *)arg, &uq32, sizeof(uq32)))
154 return -EFAULT;
155 return 0;
156}
157
158static int compat_drm_setunique(struct file *file, unsigned int cmd,
159 unsigned long arg)
160{
161 drm_unique32_t uq32;
162 struct drm_unique __user *u;
163
164 if (copy_from_user(&uq32, (void __user *)arg, sizeof(uq32)))
165 return -EFAULT;
166
167 u = compat_alloc_user_space(sizeof(*u));
168 if (!access_ok(VERIFY_WRITE, u, sizeof(*u)))
169 return -EFAULT;
170 if (__put_user(uq32.unique_len, &u->unique_len)
171 || __put_user((void __user *)(unsigned long)uq32.unique,
172 &u->unique))
173 return -EFAULT;
174
175 return drm_ioctl(file->f_path.dentry->d_inode, file,
176 DRM_IOCTL_SET_UNIQUE, (unsigned long)u);
177}
178
179typedef struct drm_map32 {
180 u32 offset; /**< Requested physical address (0 for SAREA)*/
181 u32 size; /**< Requested physical size (bytes) */
182 enum drm_map_type type; /**< Type of memory to map */
183 enum drm_map_flags flags; /**< Flags */
184 u32 handle; /**< User-space: "Handle" to pass to mmap() */
185 int mtrr; /**< MTRR slot used */
186} drm_map32_t;
187
188static int compat_drm_getmap(struct file *file, unsigned int cmd,
189 unsigned long arg)
190{
191 drm_map32_t __user *argp = (void __user *)arg;
192 drm_map32_t m32;
193 struct drm_map __user *map;
194 int idx, err;
195 void *handle;
196
197 if (get_user(idx, &argp->offset))
198 return -EFAULT;
199
200 map = compat_alloc_user_space(sizeof(*map));
201 if (!access_ok(VERIFY_WRITE, map, sizeof(*map)))
202 return -EFAULT;
203 if (__put_user(idx, &map->offset))
204 return -EFAULT;
205
206 err = drm_ioctl(file->f_path.dentry->d_inode, file,
207 DRM_IOCTL_GET_MAP, (unsigned long)map);
208 if (err)
209 return err;
210
211 if (__get_user(m32.offset, &map->offset)
212 || __get_user(m32.size, &map->size)
213 || __get_user(m32.type, &map->type)
214 || __get_user(m32.flags, &map->flags)
215 || __get_user(handle, &map->handle)
216 || __get_user(m32.mtrr, &map->mtrr))
217 return -EFAULT;
218
219 m32.handle = (unsigned long)handle;
220 if (copy_to_user(argp, &m32, sizeof(m32)))
221 return -EFAULT;
222 return 0;
223
224}
225
226static int compat_drm_addmap(struct file *file, unsigned int cmd,
227 unsigned long arg)
228{
229 drm_map32_t __user *argp = (void __user *)arg;
230 drm_map32_t m32;
231 struct drm_map __user *map;
232 int err;
233 void *handle;
234
235 if (copy_from_user(&m32, argp, sizeof(m32)))
236 return -EFAULT;
237
238 map = compat_alloc_user_space(sizeof(*map));
239 if (!access_ok(VERIFY_WRITE, map, sizeof(*map)))
240 return -EFAULT;
241 if (__put_user(m32.offset, &map->offset)
242 || __put_user(m32.size, &map->size)
243 || __put_user(m32.type, &map->type)
244 || __put_user(m32.flags, &map->flags))
245 return -EFAULT;
246
247 err = drm_ioctl(file->f_path.dentry->d_inode, file,
248 DRM_IOCTL_ADD_MAP, (unsigned long)map);
249 if (err)
250 return err;
251
252 if (__get_user(m32.offset, &map->offset)
253 || __get_user(m32.mtrr, &map->mtrr)
254 || __get_user(handle, &map->handle))
255 return -EFAULT;
256
257 m32.handle = (unsigned long)handle;
258 if (m32.handle != (unsigned long)handle && printk_ratelimit())
259 printk(KERN_ERR "compat_drm_addmap truncated handle"
260 " %p for type %d offset %x\n",
261 handle, m32.type, m32.offset);
262
263 if (copy_to_user(argp, &m32, sizeof(m32)))
264 return -EFAULT;
265
266 return 0;
267}
268
269static int compat_drm_rmmap(struct file *file, unsigned int cmd,
270 unsigned long arg)
271{
272 drm_map32_t __user *argp = (void __user *)arg;
273 struct drm_map __user *map;
274 u32 handle;
275
276 if (get_user(handle, &argp->handle))
277 return -EFAULT;
278
279 map = compat_alloc_user_space(sizeof(*map));
280 if (!access_ok(VERIFY_WRITE, map, sizeof(*map)))
281 return -EFAULT;
282 if (__put_user((void *)(unsigned long)handle, &map->handle))
283 return -EFAULT;
284
285 return drm_ioctl(file->f_path.dentry->d_inode, file,
286 DRM_IOCTL_RM_MAP, (unsigned long)map);
287}
288
289typedef struct drm_client32 {
290 int idx; /**< Which client desired? */
291 int auth; /**< Is client authenticated? */
292 u32 pid; /**< Process ID */
293 u32 uid; /**< User ID */
294 u32 magic; /**< Magic */
295 u32 iocs; /**< Ioctl count */
296} drm_client32_t;
297
298static int compat_drm_getclient(struct file *file, unsigned int cmd,
299 unsigned long arg)
300{
301 drm_client32_t c32;
302 drm_client32_t __user *argp = (void __user *)arg;
303 struct drm_client __user *client;
304 int idx, err;
305
306 if (get_user(idx, &argp->idx))
307 return -EFAULT;
308
309 client = compat_alloc_user_space(sizeof(*client));
310 if (!access_ok(VERIFY_WRITE, client, sizeof(*client)))
311 return -EFAULT;
312 if (__put_user(idx, &client->idx))
313 return -EFAULT;
314
315 err = drm_ioctl(file->f_path.dentry->d_inode, file,
316 DRM_IOCTL_GET_CLIENT, (unsigned long)client);
317 if (err)
318 return err;
319
320 if (__get_user(c32.auth, &client->auth)
321 || __get_user(c32.pid, &client->pid)
322 || __get_user(c32.uid, &client->uid)
323 || __get_user(c32.magic, &client->magic)
324 || __get_user(c32.iocs, &client->iocs))
325 return -EFAULT;
326
327 if (copy_to_user(argp, &c32, sizeof(c32)))
328 return -EFAULT;
329 return 0;
330}
331
332typedef struct drm_stats32 {
333 u32 count;
334 struct {
335 u32 value;
336 enum drm_stat_type type;
337 } data[15];
338} drm_stats32_t;
339
340static int compat_drm_getstats(struct file *file, unsigned int cmd,
341 unsigned long arg)
342{
343 drm_stats32_t s32;
344 drm_stats32_t __user *argp = (void __user *)arg;
345 struct drm_stats __user *stats;
346 int i, err;
347
348 stats = compat_alloc_user_space(sizeof(*stats));
349 if (!access_ok(VERIFY_WRITE, stats, sizeof(*stats)))
350 return -EFAULT;
351
352 err = drm_ioctl(file->f_path.dentry->d_inode, file,
353 DRM_IOCTL_GET_STATS, (unsigned long)stats);
354 if (err)
355 return err;
356
357 if (__get_user(s32.count, &stats->count))
358 return -EFAULT;
359 for (i = 0; i < 15; ++i)
360 if (__get_user(s32.data[i].value, &stats->data[i].value)
361 || __get_user(s32.data[i].type, &stats->data[i].type))
362 return -EFAULT;
363
364 if (copy_to_user(argp, &s32, sizeof(s32)))
365 return -EFAULT;
366 return 0;
367}
368
369typedef struct drm_buf_desc32 {
370 int count; /**< Number of buffers of this size */
371 int size; /**< Size in bytes */
372 int low_mark; /**< Low water mark */
373 int high_mark; /**< High water mark */
374 int flags;
375 u32 agp_start; /**< Start address in the AGP aperture */
376} drm_buf_desc32_t;
377
378static int compat_drm_addbufs(struct file *file, unsigned int cmd,
379 unsigned long arg)
380{
381 drm_buf_desc32_t __user *argp = (void __user *)arg;
382 struct drm_buf_desc __user *buf;
383 int err;
384 unsigned long agp_start;
385
386 buf = compat_alloc_user_space(sizeof(*buf));
387 if (!access_ok(VERIFY_WRITE, buf, sizeof(*buf))
388 || !access_ok(VERIFY_WRITE, argp, sizeof(*argp)))
389 return -EFAULT;
390
391 if (__copy_in_user(buf, argp, offsetof(drm_buf_desc32_t, agp_start))
392 || __get_user(agp_start, &argp->agp_start)
393 || __put_user(agp_start, &buf->agp_start))
394 return -EFAULT;
395
396 err = drm_ioctl(file->f_path.dentry->d_inode, file,
397 DRM_IOCTL_ADD_BUFS, (unsigned long)buf);
398 if (err)
399 return err;
400
401 if (__copy_in_user(argp, buf, offsetof(drm_buf_desc32_t, agp_start))
402 || __get_user(agp_start, &buf->agp_start)
403 || __put_user(agp_start, &argp->agp_start))
404 return -EFAULT;
405
406 return 0;
407}
408
409static int compat_drm_markbufs(struct file *file, unsigned int cmd,
410 unsigned long arg)
411{
412 drm_buf_desc32_t b32;
413 drm_buf_desc32_t __user *argp = (void __user *)arg;
414 struct drm_buf_desc __user *buf;
415
416 if (copy_from_user(&b32, argp, sizeof(b32)))
417 return -EFAULT;
418
419 buf = compat_alloc_user_space(sizeof(*buf));
420 if (!access_ok(VERIFY_WRITE, buf, sizeof(*buf)))
421 return -EFAULT;
422
423 if (__put_user(b32.size, &buf->size)
424 || __put_user(b32.low_mark, &buf->low_mark)
425 || __put_user(b32.high_mark, &buf->high_mark))
426 return -EFAULT;
427
428 return drm_ioctl(file->f_path.dentry->d_inode, file,
429 DRM_IOCTL_MARK_BUFS, (unsigned long)buf);
430}
431
432typedef struct drm_buf_info32 {
433 int count; /**< Entries in list */
434 u32 list;
435} drm_buf_info32_t;
436
437static int compat_drm_infobufs(struct file *file, unsigned int cmd,
438 unsigned long arg)
439{
440 drm_buf_info32_t req32;
441 drm_buf_info32_t __user *argp = (void __user *)arg;
442 drm_buf_desc32_t __user *to;
443 struct drm_buf_info __user *request;
444 struct drm_buf_desc __user *list;
445 size_t nbytes;
446 int i, err;
447 int count, actual;
448
449 if (copy_from_user(&req32, argp, sizeof(req32)))
450 return -EFAULT;
451
452 count = req32.count;
453 to = (drm_buf_desc32_t __user *) (unsigned long)req32.list;
454 if (count < 0)
455 count = 0;
456 if (count > 0
457 && !access_ok(VERIFY_WRITE, to, count * sizeof(drm_buf_desc32_t)))
458 return -EFAULT;
459
460 nbytes = sizeof(*request) + count * sizeof(struct drm_buf_desc);
461 request = compat_alloc_user_space(nbytes);
462 if (!access_ok(VERIFY_WRITE, request, nbytes))
463 return -EFAULT;
464 list = (struct drm_buf_desc *) (request + 1);
465
466 if (__put_user(count, &request->count)
467 || __put_user(list, &request->list))
468 return -EFAULT;
469
470 err = drm_ioctl(file->f_path.dentry->d_inode, file,
471 DRM_IOCTL_INFO_BUFS, (unsigned long)request);
472 if (err)
473 return err;
474
475 if (__get_user(actual, &request->count))
476 return -EFAULT;
477 if (count >= actual)
478 for (i = 0; i < actual; ++i)
479 if (__copy_in_user(&to[i], &list[i],
480 offsetof(struct drm_buf_desc, flags)))
481 return -EFAULT;
482
483 if (__put_user(actual, &argp->count))
484 return -EFAULT;
485
486 return 0;
487}
488
489typedef struct drm_buf_pub32 {
490 int idx; /**< Index into the master buffer list */
491 int total; /**< Buffer size */
492 int used; /**< Amount of buffer in use (for DMA) */
493 u32 address; /**< Address of buffer */
494} drm_buf_pub32_t;
495
496typedef struct drm_buf_map32 {
497 int count; /**< Length of the buffer list */
498 u32 virtual; /**< Mmap'd area in user-virtual */
499 u32 list; /**< Buffer information */
500} drm_buf_map32_t;
501
502static int compat_drm_mapbufs(struct file *file, unsigned int cmd,
503 unsigned long arg)
504{
505 drm_buf_map32_t __user *argp = (void __user *)arg;
506 drm_buf_map32_t req32;
507 drm_buf_pub32_t __user *list32;
508 struct drm_buf_map __user *request;
509 struct drm_buf_pub __user *list;
510 int i, err;
511 int count, actual;
512 size_t nbytes;
513 void __user *addr;
514
515 if (copy_from_user(&req32, argp, sizeof(req32)))
516 return -EFAULT;
517 count = req32.count;
518 list32 = (void __user *)(unsigned long)req32.list;
519
520 if (count < 0)
521 return -EINVAL;
522 nbytes = sizeof(*request) + count * sizeof(struct drm_buf_pub);
523 request = compat_alloc_user_space(nbytes);
524 if (!access_ok(VERIFY_WRITE, request, nbytes))
525 return -EFAULT;
526 list = (struct drm_buf_pub *) (request + 1);
527
528 if (__put_user(count, &request->count)
529 || __put_user(list, &request->list))
530 return -EFAULT;
531
532 err = drm_ioctl(file->f_path.dentry->d_inode, file,
533 DRM_IOCTL_MAP_BUFS, (unsigned long)request);
534 if (err)
535 return err;
536
537 if (__get_user(actual, &request->count))
538 return -EFAULT;
539 if (count >= actual)
540 for (i = 0; i < actual; ++i)
541 if (__copy_in_user(&list32[i], &list[i],
542 offsetof(struct drm_buf_pub, address))
543 || __get_user(addr, &list[i].address)
544 || __put_user((unsigned long)addr,
545 &list32[i].address))
546 return -EFAULT;
547
548 if (__put_user(actual, &argp->count)
549 || __get_user(addr, &request->virtual)
550 || __put_user((unsigned long)addr, &argp->virtual))
551 return -EFAULT;
552
553 return 0;
554}
555
556typedef struct drm_buf_free32 {
557 int count;
558 u32 list;
559} drm_buf_free32_t;
560
561static int compat_drm_freebufs(struct file *file, unsigned int cmd,
562 unsigned long arg)
563{
564 drm_buf_free32_t req32;
565 struct drm_buf_free __user *request;
566 drm_buf_free32_t __user *argp = (void __user *)arg;
567
568 if (copy_from_user(&req32, argp, sizeof(req32)))
569 return -EFAULT;
570
571 request = compat_alloc_user_space(sizeof(*request));
572 if (!access_ok(VERIFY_WRITE, request, sizeof(*request)))
573 return -EFAULT;
574 if (__put_user(req32.count, &request->count)
575 || __put_user((int __user *)(unsigned long)req32.list,
576 &request->list))
577 return -EFAULT;
578
579 return drm_ioctl(file->f_path.dentry->d_inode, file,
580 DRM_IOCTL_FREE_BUFS, (unsigned long)request);
581}
582
583typedef struct drm_ctx_priv_map32 {
584 unsigned int ctx_id; /**< Context requesting private mapping */
585 u32 handle; /**< Handle of map */
586} drm_ctx_priv_map32_t;
587
588static int compat_drm_setsareactx(struct file *file, unsigned int cmd,
589 unsigned long arg)
590{
591 drm_ctx_priv_map32_t req32;
592 struct drm_ctx_priv_map __user *request;
593 drm_ctx_priv_map32_t __user *argp = (void __user *)arg;
594
595 if (copy_from_user(&req32, argp, sizeof(req32)))
596 return -EFAULT;
597
598 request = compat_alloc_user_space(sizeof(*request));
599 if (!access_ok(VERIFY_WRITE, request, sizeof(*request)))
600 return -EFAULT;
601 if (__put_user(req32.ctx_id, &request->ctx_id)
602 || __put_user((void *)(unsigned long)req32.handle,
603 &request->handle))
604 return -EFAULT;
605
606 return drm_ioctl(file->f_path.dentry->d_inode, file,
607 DRM_IOCTL_SET_SAREA_CTX, (unsigned long)request);
608}
609
610static int compat_drm_getsareactx(struct file *file, unsigned int cmd,
611 unsigned long arg)
612{
613 struct drm_ctx_priv_map __user *request;
614 drm_ctx_priv_map32_t __user *argp = (void __user *)arg;
615 int err;
616 unsigned int ctx_id;
617 void *handle;
618
619 if (!access_ok(VERIFY_WRITE, argp, sizeof(*argp))
620 || __get_user(ctx_id, &argp->ctx_id))
621 return -EFAULT;
622
623 request = compat_alloc_user_space(sizeof(*request));
624 if (!access_ok(VERIFY_WRITE, request, sizeof(*request)))
625 return -EFAULT;
626 if (__put_user(ctx_id, &request->ctx_id))
627 return -EFAULT;
628
629 err = drm_ioctl(file->f_path.dentry->d_inode, file,
630 DRM_IOCTL_GET_SAREA_CTX, (unsigned long)request);
631 if (err)
632 return err;
633
634 if (__get_user(handle, &request->handle)
635 || __put_user((unsigned long)handle, &argp->handle))
636 return -EFAULT;
637
638 return 0;
639}
640
641typedef struct drm_ctx_res32 {
642 int count;
643 u32 contexts;
644} drm_ctx_res32_t;
645
646static int compat_drm_resctx(struct file *file, unsigned int cmd,
647 unsigned long arg)
648{
649 drm_ctx_res32_t __user *argp = (void __user *)arg;
650 drm_ctx_res32_t res32;
651 struct drm_ctx_res __user *res;
652 int err;
653
654 if (copy_from_user(&res32, argp, sizeof(res32)))
655 return -EFAULT;
656
657 res = compat_alloc_user_space(sizeof(*res));
658 if (!access_ok(VERIFY_WRITE, res, sizeof(*res)))
659 return -EFAULT;
660 if (__put_user(res32.count, &res->count)
661 || __put_user((struct drm_ctx __user *) (unsigned long)res32.contexts,
662 &res->contexts))
663 return -EFAULT;
664
665 err = drm_ioctl(file->f_path.dentry->d_inode, file,
666 DRM_IOCTL_RES_CTX, (unsigned long)res);
667 if (err)
668 return err;
669
670 if (__get_user(res32.count, &res->count)
671 || __put_user(res32.count, &argp->count))
672 return -EFAULT;
673
674 return 0;
675}
676
677typedef struct drm_dma32 {
678 int context; /**< Context handle */
679 int send_count; /**< Number of buffers to send */
680 u32 send_indices; /**< List of handles to buffers */
681 u32 send_sizes; /**< Lengths of data to send */
682 enum drm_dma_flags flags; /**< Flags */
683 int request_count; /**< Number of buffers requested */
684 int request_size; /**< Desired size for buffers */
685 u32 request_indices; /**< Buffer information */
686 u32 request_sizes;
687 int granted_count; /**< Number of buffers granted */
688} drm_dma32_t;
689
690static int compat_drm_dma(struct file *file, unsigned int cmd,
691 unsigned long arg)
692{
693 drm_dma32_t d32;
694 drm_dma32_t __user *argp = (void __user *)arg;
695 struct drm_dma __user *d;
696 int err;
697
698 if (copy_from_user(&d32, argp, sizeof(d32)))
699 return -EFAULT;
700
701 d = compat_alloc_user_space(sizeof(*d));
702 if (!access_ok(VERIFY_WRITE, d, sizeof(*d)))
703 return -EFAULT;
704
705 if (__put_user(d32.context, &d->context)
706 || __put_user(d32.send_count, &d->send_count)
707 || __put_user((int __user *)(unsigned long)d32.send_indices,
708 &d->send_indices)
709 || __put_user((int __user *)(unsigned long)d32.send_sizes,
710 &d->send_sizes)
711 || __put_user(d32.flags, &d->flags)
712 || __put_user(d32.request_count, &d->request_count)
713 || __put_user((int __user *)(unsigned long)d32.request_indices,
714 &d->request_indices)
715 || __put_user((int __user *)(unsigned long)d32.request_sizes,
716 &d->request_sizes))
717 return -EFAULT;
718
719 err = drm_ioctl(file->f_path.dentry->d_inode, file,
720 DRM_IOCTL_DMA, (unsigned long)d);
721 if (err)
722 return err;
723
724 if (__get_user(d32.request_size, &d->request_size)
725 || __get_user(d32.granted_count, &d->granted_count)
726 || __put_user(d32.request_size, &argp->request_size)
727 || __put_user(d32.granted_count, &argp->granted_count))
728 return -EFAULT;
729
730 return 0;
731}
732
733#if __OS_HAS_AGP
734typedef struct drm_agp_mode32 {
735 u32 mode; /**< AGP mode */
736} drm_agp_mode32_t;
737
738static int compat_drm_agp_enable(struct file *file, unsigned int cmd,
739 unsigned long arg)
740{
741 drm_agp_mode32_t __user *argp = (void __user *)arg;
742 drm_agp_mode32_t m32;
743 struct drm_agp_mode __user *mode;
744
745 if (get_user(m32.mode, &argp->mode))
746 return -EFAULT;
747
748 mode = compat_alloc_user_space(sizeof(*mode));
749 if (put_user(m32.mode, &mode->mode))
750 return -EFAULT;
751
752 return drm_ioctl(file->f_path.dentry->d_inode, file,
753 DRM_IOCTL_AGP_ENABLE, (unsigned long)mode);
754}
755
756typedef struct drm_agp_info32 {
757 int agp_version_major;
758 int agp_version_minor;
759 u32 mode;
760 u32 aperture_base; /* physical address */
761 u32 aperture_size; /* bytes */
762 u32 memory_allowed; /* bytes */
763 u32 memory_used;
764
765 /* PCI information */
766 unsigned short id_vendor;
767 unsigned short id_device;
768} drm_agp_info32_t;
769
770static int compat_drm_agp_info(struct file *file, unsigned int cmd,
771 unsigned long arg)
772{
773 drm_agp_info32_t __user *argp = (void __user *)arg;
774 drm_agp_info32_t i32;
775 struct drm_agp_info __user *info;
776 int err;
777
778 info = compat_alloc_user_space(sizeof(*info));
779 if (!access_ok(VERIFY_WRITE, info, sizeof(*info)))
780 return -EFAULT;
781
782 err = drm_ioctl(file->f_path.dentry->d_inode, file,
783 DRM_IOCTL_AGP_INFO, (unsigned long)info);
784 if (err)
785 return err;
786
787 if (__get_user(i32.agp_version_major, &info->agp_version_major)
788 || __get_user(i32.agp_version_minor, &info->agp_version_minor)
789 || __get_user(i32.mode, &info->mode)
790 || __get_user(i32.aperture_base, &info->aperture_base)
791 || __get_user(i32.aperture_size, &info->aperture_size)
792 || __get_user(i32.memory_allowed, &info->memory_allowed)
793 || __get_user(i32.memory_used, &info->memory_used)
794 || __get_user(i32.id_vendor, &info->id_vendor)
795 || __get_user(i32.id_device, &info->id_device))
796 return -EFAULT;
797
798 if (copy_to_user(argp, &i32, sizeof(i32)))
799 return -EFAULT;
800
801 return 0;
802}
803
804typedef struct drm_agp_buffer32 {
805 u32 size; /**< In bytes -- will round to page boundary */
806 u32 handle; /**< Used for binding / unbinding */
807 u32 type; /**< Type of memory to allocate */
808 u32 physical; /**< Physical used by i810 */
809} drm_agp_buffer32_t;
810
811static int compat_drm_agp_alloc(struct file *file, unsigned int cmd,
812 unsigned long arg)
813{
814 drm_agp_buffer32_t __user *argp = (void __user *)arg;
815 drm_agp_buffer32_t req32;
816 struct drm_agp_buffer __user *request;
817 int err;
818
819 if (copy_from_user(&req32, argp, sizeof(req32)))
820 return -EFAULT;
821
822 request = compat_alloc_user_space(sizeof(*request));
823 if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
824 || __put_user(req32.size, &request->size)
825 || __put_user(req32.type, &request->type))
826 return -EFAULT;
827
828 err = drm_ioctl(file->f_path.dentry->d_inode, file,
829 DRM_IOCTL_AGP_ALLOC, (unsigned long)request);
830 if (err)
831 return err;
832
833 if (__get_user(req32.handle, &request->handle)
834 || __get_user(req32.physical, &request->physical)
835 || copy_to_user(argp, &req32, sizeof(req32))) {
836 drm_ioctl(file->f_path.dentry->d_inode, file,
837 DRM_IOCTL_AGP_FREE, (unsigned long)request);
838 return -EFAULT;
839 }
840
841 return 0;
842}
843
844static int compat_drm_agp_free(struct file *file, unsigned int cmd,
845 unsigned long arg)
846{
847 drm_agp_buffer32_t __user *argp = (void __user *)arg;
848 struct drm_agp_buffer __user *request;
849 u32 handle;
850
851 request = compat_alloc_user_space(sizeof(*request));
852 if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
853 || get_user(handle, &argp->handle)
854 || __put_user(handle, &request->handle))
855 return -EFAULT;
856
857 return drm_ioctl(file->f_path.dentry->d_inode, file,
858 DRM_IOCTL_AGP_FREE, (unsigned long)request);
859}
860
861typedef struct drm_agp_binding32 {
862 u32 handle; /**< From drm_agp_buffer */
863 u32 offset; /**< In bytes -- will round to page boundary */
864} drm_agp_binding32_t;
865
866static int compat_drm_agp_bind(struct file *file, unsigned int cmd,
867 unsigned long arg)
868{
869 drm_agp_binding32_t __user *argp = (void __user *)arg;
870 drm_agp_binding32_t req32;
871 struct drm_agp_binding __user *request;
872
873 if (copy_from_user(&req32, argp, sizeof(req32)))
874 return -EFAULT;
875
876 request = compat_alloc_user_space(sizeof(*request));
877 if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
878 || __put_user(req32.handle, &request->handle)
879 || __put_user(req32.offset, &request->offset))
880 return -EFAULT;
881
882 return drm_ioctl(file->f_path.dentry->d_inode, file,
883 DRM_IOCTL_AGP_BIND, (unsigned long)request);
884}
885
886static int compat_drm_agp_unbind(struct file *file, unsigned int cmd,
887 unsigned long arg)
888{
889 drm_agp_binding32_t __user *argp = (void __user *)arg;
890 struct drm_agp_binding __user *request;
891 u32 handle;
892
893 request = compat_alloc_user_space(sizeof(*request));
894 if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
895 || get_user(handle, &argp->handle)
896 || __put_user(handle, &request->handle))
897 return -EFAULT;
898
899 return drm_ioctl(file->f_path.dentry->d_inode, file,
900 DRM_IOCTL_AGP_UNBIND, (unsigned long)request);
901}
902#endif /* __OS_HAS_AGP */
903
904typedef struct drm_scatter_gather32 {
905 u32 size; /**< In bytes -- will round to page boundary */
906 u32 handle; /**< Used for mapping / unmapping */
907} drm_scatter_gather32_t;
908
909static int compat_drm_sg_alloc(struct file *file, unsigned int cmd,
910 unsigned long arg)
911{
912 drm_scatter_gather32_t __user *argp = (void __user *)arg;
913 struct drm_scatter_gather __user *request;
914 int err;
915 unsigned long x;
916
917 request = compat_alloc_user_space(sizeof(*request));
918 if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
919 || !access_ok(VERIFY_WRITE, argp, sizeof(*argp))
920 || __get_user(x, &argp->size)
921 || __put_user(x, &request->size))
922 return -EFAULT;
923
924 err = drm_ioctl(file->f_path.dentry->d_inode, file,
925 DRM_IOCTL_SG_ALLOC, (unsigned long)request);
926 if (err)
927 return err;
928
929 /* XXX not sure about the handle conversion here... */
930 if (__get_user(x, &request->handle)
931 || __put_user(x >> PAGE_SHIFT, &argp->handle))
932 return -EFAULT;
933
934 return 0;
935}
936
937static int compat_drm_sg_free(struct file *file, unsigned int cmd,
938 unsigned long arg)
939{
940 drm_scatter_gather32_t __user *argp = (void __user *)arg;
941 struct drm_scatter_gather __user *request;
942 unsigned long x;
943
944 request = compat_alloc_user_space(sizeof(*request));
945 if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
946 || !access_ok(VERIFY_WRITE, argp, sizeof(*argp))
947 || __get_user(x, &argp->handle)
948 || __put_user(x << PAGE_SHIFT, &request->handle))
949 return -EFAULT;
950
951 return drm_ioctl(file->f_path.dentry->d_inode, file,
952 DRM_IOCTL_SG_FREE, (unsigned long)request);
953}
954
955struct drm_wait_vblank_request32 {
956 enum drm_vblank_seq_type type;
957 unsigned int sequence;
958 u32 signal;
959};
960
961struct drm_wait_vblank_reply32 {
962 enum drm_vblank_seq_type type;
963 unsigned int sequence;
964 s32 tval_sec;
965 s32 tval_usec;
966};
967
968typedef union drm_wait_vblank32 {
969 struct drm_wait_vblank_request32 request;
970 struct drm_wait_vblank_reply32 reply;
971} drm_wait_vblank32_t;
972
973static int compat_drm_wait_vblank(struct file *file, unsigned int cmd,
974 unsigned long arg)
975{
976 drm_wait_vblank32_t __user *argp = (void __user *)arg;
977 drm_wait_vblank32_t req32;
978 union drm_wait_vblank __user *request;
979 int err;
980
981 if (copy_from_user(&req32, argp, sizeof(req32)))
982 return -EFAULT;
983
984 request = compat_alloc_user_space(sizeof(*request));
985 if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
986 || __put_user(req32.request.type, &request->request.type)
987 || __put_user(req32.request.sequence, &request->request.sequence)
988 || __put_user(req32.request.signal, &request->request.signal))
989 return -EFAULT;
990
991 err = drm_ioctl(file->f_path.dentry->d_inode, file,
992 DRM_IOCTL_WAIT_VBLANK, (unsigned long)request);
993 if (err)
994 return err;
995
996 if (__get_user(req32.reply.type, &request->reply.type)
997 || __get_user(req32.reply.sequence, &request->reply.sequence)
998 || __get_user(req32.reply.tval_sec, &request->reply.tval_sec)
999 || __get_user(req32.reply.tval_usec, &request->reply.tval_usec))
1000 return -EFAULT;
1001
1002 if (copy_to_user(argp, &req32, sizeof(req32)))
1003 return -EFAULT;
1004
1005 return 0;
1006}
1007
1008drm_ioctl_compat_t *drm_compat_ioctls[] = {
1009 [DRM_IOCTL_NR(DRM_IOCTL_VERSION32)] = compat_drm_version,
1010 [DRM_IOCTL_NR(DRM_IOCTL_GET_UNIQUE32)] = compat_drm_getunique,
1011 [DRM_IOCTL_NR(DRM_IOCTL_GET_MAP32)] = compat_drm_getmap,
1012 [DRM_IOCTL_NR(DRM_IOCTL_GET_CLIENT32)] = compat_drm_getclient,
1013 [DRM_IOCTL_NR(DRM_IOCTL_GET_STATS32)] = compat_drm_getstats,
1014 [DRM_IOCTL_NR(DRM_IOCTL_SET_UNIQUE32)] = compat_drm_setunique,
1015 [DRM_IOCTL_NR(DRM_IOCTL_ADD_MAP32)] = compat_drm_addmap,
1016 [DRM_IOCTL_NR(DRM_IOCTL_ADD_BUFS32)] = compat_drm_addbufs,
1017 [DRM_IOCTL_NR(DRM_IOCTL_MARK_BUFS32)] = compat_drm_markbufs,
1018 [DRM_IOCTL_NR(DRM_IOCTL_INFO_BUFS32)] = compat_drm_infobufs,
1019 [DRM_IOCTL_NR(DRM_IOCTL_MAP_BUFS32)] = compat_drm_mapbufs,
1020 [DRM_IOCTL_NR(DRM_IOCTL_FREE_BUFS32)] = compat_drm_freebufs,
1021 [DRM_IOCTL_NR(DRM_IOCTL_RM_MAP32)] = compat_drm_rmmap,
1022 [DRM_IOCTL_NR(DRM_IOCTL_SET_SAREA_CTX32)] = compat_drm_setsareactx,
1023 [DRM_IOCTL_NR(DRM_IOCTL_GET_SAREA_CTX32)] = compat_drm_getsareactx,
1024 [DRM_IOCTL_NR(DRM_IOCTL_RES_CTX32)] = compat_drm_resctx,
1025 [DRM_IOCTL_NR(DRM_IOCTL_DMA32)] = compat_drm_dma,
1026#if __OS_HAS_AGP
1027 [DRM_IOCTL_NR(DRM_IOCTL_AGP_ENABLE32)] = compat_drm_agp_enable,
1028 [DRM_IOCTL_NR(DRM_IOCTL_AGP_INFO32)] = compat_drm_agp_info,
1029 [DRM_IOCTL_NR(DRM_IOCTL_AGP_ALLOC32)] = compat_drm_agp_alloc,
1030 [DRM_IOCTL_NR(DRM_IOCTL_AGP_FREE32)] = compat_drm_agp_free,
1031 [DRM_IOCTL_NR(DRM_IOCTL_AGP_BIND32)] = compat_drm_agp_bind,
1032 [DRM_IOCTL_NR(DRM_IOCTL_AGP_UNBIND32)] = compat_drm_agp_unbind,
1033#endif
1034 [DRM_IOCTL_NR(DRM_IOCTL_SG_ALLOC32)] = compat_drm_sg_alloc,
1035 [DRM_IOCTL_NR(DRM_IOCTL_SG_FREE32)] = compat_drm_sg_free,
1036 [DRM_IOCTL_NR(DRM_IOCTL_WAIT_VBLANK32)] = compat_drm_wait_vblank,
1037};
1038
1039/**
1040 * Called whenever a 32-bit process running under a 64-bit kernel
1041 * performs an ioctl on /dev/drm.
1042 *
1043 * \param file_priv DRM file private.
1044 * \param cmd command.
1045 * \param arg user argument.
1046 * \return zero on success or negative number on failure.
1047 */
1048long drm_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
1049{
1050 unsigned int nr = DRM_IOCTL_NR(cmd);
1051 drm_ioctl_compat_t *fn;
1052 int ret;
1053
1054 /* Assume that ioctls without an explicit compat routine will just
1055 * work. This may not always be a good assumption, but it's better
1056 * than always failing.
1057 */
1058 if (nr >= ARRAY_SIZE(drm_compat_ioctls))
1059 return drm_ioctl(filp->f_dentry->d_inode, filp, cmd, arg);
1060
1061 fn = drm_compat_ioctls[nr];
1062
1063 lock_kernel(); /* XXX for now */
1064 if (fn != NULL)
1065 ret = (*fn) (filp, cmd, arg);
1066 else
1067 ret = drm_ioctl(filp->f_path.dentry->d_inode, filp, cmd, arg);
1068 unlock_kernel();
1069
1070 return ret;
1071}
1072
1073EXPORT_SYMBOL(drm_compat_ioctl);
diff --git a/drivers/char/drm/drm_ioctl.c b/drivers/char/drm/drm_ioctl.c
deleted file mode 100644
index 16829fb3089d..000000000000
--- a/drivers/char/drm/drm_ioctl.c
+++ /dev/null
@@ -1,352 +0,0 @@
1/**
2 * \file drm_ioctl.c
3 * IOCTL processing for DRM
4 *
5 * \author Rickard E. (Rik) Faith <faith@valinux.com>
6 * \author Gareth Hughes <gareth@valinux.com>
7 */
8
9/*
10 * Created: Fri Jan 8 09:01:26 1999 by faith@valinux.com
11 *
12 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
13 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
14 * All Rights Reserved.
15 *
16 * Permission is hereby granted, free of charge, to any person obtaining a
17 * copy of this software and associated documentation files (the "Software"),
18 * to deal in the Software without restriction, including without limitation
19 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
20 * and/or sell copies of the Software, and to permit persons to whom the
21 * Software is furnished to do so, subject to the following conditions:
22 *
23 * The above copyright notice and this permission notice (including the next
24 * paragraph) shall be included in all copies or substantial portions of the
25 * Software.
26 *
27 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
30 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
31 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
32 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
33 * OTHER DEALINGS IN THE SOFTWARE.
34 */
35
36#include "drmP.h"
37#include "drm_core.h"
38
39#include "linux/pci.h"
40
41/**
42 * Get the bus id.
43 *
44 * \param inode device inode.
45 * \param file_priv DRM file private.
46 * \param cmd command.
47 * \param arg user argument, pointing to a drm_unique structure.
48 * \return zero on success or a negative number on failure.
49 *
50 * Copies the bus id from drm_device::unique into user space.
51 */
52int drm_getunique(struct drm_device *dev, void *data,
53 struct drm_file *file_priv)
54{
55 struct drm_unique *u = data;
56
57 if (u->unique_len >= dev->unique_len) {
58 if (copy_to_user(u->unique, dev->unique, dev->unique_len))
59 return -EFAULT;
60 }
61 u->unique_len = dev->unique_len;
62
63 return 0;
64}
65
66/**
67 * Set the bus id.
68 *
69 * \param inode device inode.
70 * \param file_priv DRM file private.
71 * \param cmd command.
72 * \param arg user argument, pointing to a drm_unique structure.
73 * \return zero on success or a negative number on failure.
74 *
75 * Copies the bus id from userspace into drm_device::unique, and verifies that
76 * it matches the device this DRM is attached to (EINVAL otherwise). Deprecated
77 * in interface version 1.1 and will return EBUSY when setversion has requested
78 * version 1.1 or greater.
79 */
80int drm_setunique(struct drm_device *dev, void *data,
81 struct drm_file *file_priv)
82{
83 struct drm_unique *u = data;
84 int domain, bus, slot, func, ret;
85
86 if (dev->unique_len || dev->unique)
87 return -EBUSY;
88
89 if (!u->unique_len || u->unique_len > 1024)
90 return -EINVAL;
91
92 dev->unique_len = u->unique_len;
93 dev->unique = drm_alloc(u->unique_len + 1, DRM_MEM_DRIVER);
94 if (!dev->unique)
95 return -ENOMEM;
96 if (copy_from_user(dev->unique, u->unique, dev->unique_len))
97 return -EFAULT;
98
99 dev->unique[dev->unique_len] = '\0';
100
101 dev->devname =
102 drm_alloc(strlen(dev->driver->pci_driver.name) +
103 strlen(dev->unique) + 2, DRM_MEM_DRIVER);
104 if (!dev->devname)
105 return -ENOMEM;
106
107 sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name,
108 dev->unique);
109
110 /* Return error if the busid submitted doesn't match the device's actual
111 * busid.
112 */
113 ret = sscanf(dev->unique, "PCI:%d:%d:%d", &bus, &slot, &func);
114 if (ret != 3)
115 return -EINVAL;
116 domain = bus >> 8;
117 bus &= 0xff;
118
119 if ((domain != drm_get_pci_domain(dev)) ||
120 (bus != dev->pdev->bus->number) ||
121 (slot != PCI_SLOT(dev->pdev->devfn)) ||
122 (func != PCI_FUNC(dev->pdev->devfn)))
123 return -EINVAL;
124
125 return 0;
126}
127
128static int drm_set_busid(struct drm_device * dev)
129{
130 int len;
131
132 if (dev->unique != NULL)
133 return 0;
134
135 dev->unique_len = 40;
136 dev->unique = drm_alloc(dev->unique_len + 1, DRM_MEM_DRIVER);
137 if (dev->unique == NULL)
138 return -ENOMEM;
139
140 len = snprintf(dev->unique, dev->unique_len, "pci:%04x:%02x:%02x.%d",
141 drm_get_pci_domain(dev), dev->pdev->bus->number,
142 PCI_SLOT(dev->pdev->devfn),
143 PCI_FUNC(dev->pdev->devfn));
144
145 if (len > dev->unique_len)
146 DRM_ERROR("Unique buffer overflowed\n");
147
148 dev->devname =
149 drm_alloc(strlen(dev->driver->pci_driver.name) + dev->unique_len +
150 2, DRM_MEM_DRIVER);
151 if (dev->devname == NULL)
152 return -ENOMEM;
153
154 sprintf(dev->devname, "%s@%s", dev->driver->pci_driver.name,
155 dev->unique);
156
157 return 0;
158}
159
160/**
161 * Get a mapping information.
162 *
163 * \param inode device inode.
164 * \param file_priv DRM file private.
165 * \param cmd command.
166 * \param arg user argument, pointing to a drm_map structure.
167 *
168 * \return zero on success or a negative number on failure.
169 *
170 * Searches for the mapping with the specified offset and copies its information
171 * into userspace
172 */
173int drm_getmap(struct drm_device *dev, void *data,
174 struct drm_file *file_priv)
175{
176 struct drm_map *map = data;
177 struct drm_map_list *r_list = NULL;
178 struct list_head *list;
179 int idx;
180 int i;
181
182 idx = map->offset;
183
184 mutex_lock(&dev->struct_mutex);
185 if (idx < 0) {
186 mutex_unlock(&dev->struct_mutex);
187 return -EINVAL;
188 }
189
190 i = 0;
191 list_for_each(list, &dev->maplist) {
192 if (i == idx) {
193 r_list = list_entry(list, struct drm_map_list, head);
194 break;
195 }
196 i++;
197 }
198 if (!r_list || !r_list->map) {
199 mutex_unlock(&dev->struct_mutex);
200 return -EINVAL;
201 }
202
203 map->offset = r_list->map->offset;
204 map->size = r_list->map->size;
205 map->type = r_list->map->type;
206 map->flags = r_list->map->flags;
207 map->handle = (void *)(unsigned long) r_list->user_token;
208 map->mtrr = r_list->map->mtrr;
209 mutex_unlock(&dev->struct_mutex);
210
211 return 0;
212}
213
214/**
215 * Get client information.
216 *
217 * \param inode device inode.
218 * \param file_priv DRM file private.
219 * \param cmd command.
220 * \param arg user argument, pointing to a drm_client structure.
221 *
222 * \return zero on success or a negative number on failure.
223 *
224 * Searches for the client with the specified index and copies its information
225 * into userspace
226 */
227int drm_getclient(struct drm_device *dev, void *data,
228 struct drm_file *file_priv)
229{
230 struct drm_client *client = data;
231 struct drm_file *pt;
232 int idx;
233 int i;
234
235 idx = client->idx;
236 mutex_lock(&dev->struct_mutex);
237
238 i = 0;
239 list_for_each_entry(pt, &dev->filelist, lhead) {
240 if (i++ >= idx) {
241 client->auth = pt->authenticated;
242 client->pid = pt->pid;
243 client->uid = pt->uid;
244 client->magic = pt->magic;
245 client->iocs = pt->ioctl_count;
246 mutex_unlock(&dev->struct_mutex);
247
248 return 0;
249 }
250 }
251 mutex_unlock(&dev->struct_mutex);
252
253 return -EINVAL;
254}
255
256/**
257 * Get statistics information.
258 *
259 * \param inode device inode.
260 * \param file_priv DRM file private.
261 * \param cmd command.
262 * \param arg user argument, pointing to a drm_stats structure.
263 *
264 * \return zero on success or a negative number on failure.
265 */
266int drm_getstats(struct drm_device *dev, void *data,
267 struct drm_file *file_priv)
268{
269 struct drm_stats *stats = data;
270 int i;
271
272 memset(stats, 0, sizeof(*stats));
273
274 mutex_lock(&dev->struct_mutex);
275
276 for (i = 0; i < dev->counters; i++) {
277 if (dev->types[i] == _DRM_STAT_LOCK)
278 stats->data[i].value =
279 (dev->lock.hw_lock ? dev->lock.hw_lock->lock : 0);
280 else
281 stats->data[i].value = atomic_read(&dev->counts[i]);
282 stats->data[i].type = dev->types[i];
283 }
284
285 stats->count = dev->counters;
286
287 mutex_unlock(&dev->struct_mutex);
288
289 return 0;
290}
291
292/**
293 * Setversion ioctl.
294 *
295 * \param inode device inode.
296 * \param file_priv DRM file private.
297 * \param cmd command.
298 * \param arg user argument, pointing to a drm_lock structure.
299 * \return zero on success or negative number on failure.
300 *
301 * Sets the requested interface version
302 */
303int drm_setversion(struct drm_device *dev, void *data, struct drm_file *file_priv)
304{
305 struct drm_set_version *sv = data;
306 int if_version, retcode = 0;
307
308 if (sv->drm_di_major != -1) {
309 if (sv->drm_di_major != DRM_IF_MAJOR ||
310 sv->drm_di_minor < 0 || sv->drm_di_minor > DRM_IF_MINOR) {
311 retcode = -EINVAL;
312 goto done;
313 }
314 if_version = DRM_IF_VERSION(sv->drm_di_major,
315 sv->drm_di_minor);
316 dev->if_version = max(if_version, dev->if_version);
317 if (sv->drm_di_minor >= 1) {
318 /*
319 * Version 1.1 includes tying of DRM to specific device
320 */
321 drm_set_busid(dev);
322 }
323 }
324
325 if (sv->drm_dd_major != -1) {
326 if (sv->drm_dd_major != dev->driver->major ||
327 sv->drm_dd_minor < 0 || sv->drm_dd_minor >
328 dev->driver->minor) {
329 retcode = -EINVAL;
330 goto done;
331 }
332
333 if (dev->driver->set_version)
334 dev->driver->set_version(dev, sv);
335 }
336
337done:
338 sv->drm_di_major = DRM_IF_MAJOR;
339 sv->drm_di_minor = DRM_IF_MINOR;
340 sv->drm_dd_major = dev->driver->major;
341 sv->drm_dd_minor = dev->driver->minor;
342
343 return retcode;
344}
345
346/** No-op ioctl. */
347int drm_noop(struct drm_device *dev, void *data,
348 struct drm_file *file_priv)
349{
350 DRM_DEBUG("\n");
351 return 0;
352}
diff --git a/drivers/char/drm/drm_irq.c b/drivers/char/drm/drm_irq.c
deleted file mode 100644
index 286f9d61e7d5..000000000000
--- a/drivers/char/drm/drm_irq.c
+++ /dev/null
@@ -1,731 +0,0 @@
1/**
2 * \file drm_irq.c
3 * IRQ support
4 *
5 * \author Rickard E. (Rik) Faith <faith@valinux.com>
6 * \author Gareth Hughes <gareth@valinux.com>
7 */
8
9/*
10 * Created: Fri Mar 19 14:30:16 1999 by faith@valinux.com
11 *
12 * Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
13 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
14 * All Rights Reserved.
15 *
16 * Permission is hereby granted, free of charge, to any person obtaining a
17 * copy of this software and associated documentation files (the "Software"),
18 * to deal in the Software without restriction, including without limitation
19 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
20 * and/or sell copies of the Software, and to permit persons to whom the
21 * Software is furnished to do so, subject to the following conditions:
22 *
23 * The above copyright notice and this permission notice (including the next
24 * paragraph) shall be included in all copies or substantial portions of the
25 * Software.
26 *
27 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
30 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
31 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
32 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
33 * OTHER DEALINGS IN THE SOFTWARE.
34 */
35
36#include "drmP.h"
37
38#include <linux/interrupt.h> /* For task queue support */
39
40/**
41 * Get interrupt from bus id.
42 *
43 * \param inode device inode.
44 * \param file_priv DRM file private.
45 * \param cmd command.
46 * \param arg user argument, pointing to a drm_irq_busid structure.
47 * \return zero on success or a negative number on failure.
48 *
49 * Finds the PCI device with the specified bus id and gets its IRQ number.
50 * This IOCTL is deprecated, and will now return EINVAL for any busid not equal
51 * to that of the device that this DRM instance attached to.
52 */
53int drm_irq_by_busid(struct drm_device *dev, void *data,
54 struct drm_file *file_priv)
55{
56 struct drm_irq_busid *p = data;
57
58 if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
59 return -EINVAL;
60
61 if ((p->busnum >> 8) != drm_get_pci_domain(dev) ||
62 (p->busnum & 0xff) != dev->pdev->bus->number ||
63 p->devnum != PCI_SLOT(dev->pdev->devfn) || p->funcnum != PCI_FUNC(dev->pdev->devfn))
64 return -EINVAL;
65
66 p->irq = dev->irq;
67
68 DRM_DEBUG("%d:%d:%d => IRQ %d\n", p->busnum, p->devnum, p->funcnum,
69 p->irq);
70
71 return 0;
72}
73
74static void vblank_disable_fn(unsigned long arg)
75{
76 struct drm_device *dev = (struct drm_device *)arg;
77 unsigned long irqflags;
78 int i;
79
80 for (i = 0; i < dev->num_crtcs; i++) {
81 spin_lock_irqsave(&dev->vbl_lock, irqflags);
82 if (atomic_read(&dev->vblank_refcount[i]) == 0 &&
83 dev->vblank_enabled[i]) {
84 dev->driver->disable_vblank(dev, i);
85 dev->vblank_enabled[i] = 0;
86 }
87 spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
88 }
89}
90
91static void drm_vblank_cleanup(struct drm_device *dev)
92{
93 /* Bail if the driver didn't call drm_vblank_init() */
94 if (dev->num_crtcs == 0)
95 return;
96
97 del_timer(&dev->vblank_disable_timer);
98
99 vblank_disable_fn((unsigned long)dev);
100
101 drm_free(dev->vbl_queue, sizeof(*dev->vbl_queue) * dev->num_crtcs,
102 DRM_MEM_DRIVER);
103 drm_free(dev->vbl_sigs, sizeof(*dev->vbl_sigs) * dev->num_crtcs,
104 DRM_MEM_DRIVER);
105 drm_free(dev->_vblank_count, sizeof(*dev->_vblank_count) *
106 dev->num_crtcs, DRM_MEM_DRIVER);
107 drm_free(dev->vblank_refcount, sizeof(*dev->vblank_refcount) *
108 dev->num_crtcs, DRM_MEM_DRIVER);
109 drm_free(dev->vblank_enabled, sizeof(*dev->vblank_enabled) *
110 dev->num_crtcs, DRM_MEM_DRIVER);
111 drm_free(dev->last_vblank, sizeof(*dev->last_vblank) * dev->num_crtcs,
112 DRM_MEM_DRIVER);
113 drm_free(dev->vblank_premodeset, sizeof(*dev->vblank_premodeset) *
114 dev->num_crtcs, DRM_MEM_DRIVER);
115 drm_free(dev->vblank_offset, sizeof(*dev->vblank_offset) * dev->num_crtcs,
116 DRM_MEM_DRIVER);
117
118 dev->num_crtcs = 0;
119}
120
121int drm_vblank_init(struct drm_device *dev, int num_crtcs)
122{
123 int i, ret = -ENOMEM;
124
125 setup_timer(&dev->vblank_disable_timer, vblank_disable_fn,
126 (unsigned long)dev);
127 spin_lock_init(&dev->vbl_lock);
128 atomic_set(&dev->vbl_signal_pending, 0);
129 dev->num_crtcs = num_crtcs;
130
131 dev->vbl_queue = drm_alloc(sizeof(wait_queue_head_t) * num_crtcs,
132 DRM_MEM_DRIVER);
133 if (!dev->vbl_queue)
134 goto err;
135
136 dev->vbl_sigs = drm_alloc(sizeof(struct list_head) * num_crtcs,
137 DRM_MEM_DRIVER);
138 if (!dev->vbl_sigs)
139 goto err;
140
141 dev->_vblank_count = drm_alloc(sizeof(atomic_t) * num_crtcs,
142 DRM_MEM_DRIVER);
143 if (!dev->_vblank_count)
144 goto err;
145
146 dev->vblank_refcount = drm_alloc(sizeof(atomic_t) * num_crtcs,
147 DRM_MEM_DRIVER);
148 if (!dev->vblank_refcount)
149 goto err;
150
151 dev->vblank_enabled = drm_calloc(num_crtcs, sizeof(int),
152 DRM_MEM_DRIVER);
153 if (!dev->vblank_enabled)
154 goto err;
155
156 dev->last_vblank = drm_calloc(num_crtcs, sizeof(u32), DRM_MEM_DRIVER);
157 if (!dev->last_vblank)
158 goto err;
159
160 dev->vblank_premodeset = drm_calloc(num_crtcs, sizeof(u32),
161 DRM_MEM_DRIVER);
162 if (!dev->vblank_premodeset)
163 goto err;
164
165 dev->vblank_offset = drm_calloc(num_crtcs, sizeof(u32), DRM_MEM_DRIVER);
166 if (!dev->vblank_offset)
167 goto err;
168
169 /* Zero per-crtc vblank stuff */
170 for (i = 0; i < num_crtcs; i++) {
171 init_waitqueue_head(&dev->vbl_queue[i]);
172 INIT_LIST_HEAD(&dev->vbl_sigs[i]);
173 atomic_set(&dev->_vblank_count[i], 0);
174 atomic_set(&dev->vblank_refcount[i], 0);
175 }
176
177 return 0;
178
179err:
180 drm_vblank_cleanup(dev);
181 return ret;
182}
183EXPORT_SYMBOL(drm_vblank_init);
184
185/**
186 * Install IRQ handler.
187 *
188 * \param dev DRM device.
189 * \param irq IRQ number.
190 *
191 * Initializes the IRQ related data, and setups drm_device::vbl_queue. Installs the handler, calling the driver
192 * \c drm_driver_irq_preinstall() and \c drm_driver_irq_postinstall() functions
193 * before and after the installation.
194 */
195static int drm_irq_install(struct drm_device * dev)
196{
197 int ret;
198 unsigned long sh_flags = 0;
199
200 if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
201 return -EINVAL;
202
203 if (dev->irq == 0)
204 return -EINVAL;
205
206 mutex_lock(&dev->struct_mutex);
207
208 /* Driver must have been initialized */
209 if (!dev->dev_private) {
210 mutex_unlock(&dev->struct_mutex);
211 return -EINVAL;
212 }
213
214 if (dev->irq_enabled) {
215 mutex_unlock(&dev->struct_mutex);
216 return -EBUSY;
217 }
218 dev->irq_enabled = 1;
219 mutex_unlock(&dev->struct_mutex);
220
221 DRM_DEBUG("irq=%d\n", dev->irq);
222
223 /* Before installing handler */
224 dev->driver->irq_preinstall(dev);
225
226 /* Install handler */
227 if (drm_core_check_feature(dev, DRIVER_IRQ_SHARED))
228 sh_flags = IRQF_SHARED;
229
230 ret = request_irq(dev->irq, dev->driver->irq_handler,
231 sh_flags, dev->devname, dev);
232 if (ret < 0) {
233 mutex_lock(&dev->struct_mutex);
234 dev->irq_enabled = 0;
235 mutex_unlock(&dev->struct_mutex);
236 return ret;
237 }
238
239 /* After installing handler */
240 ret = dev->driver->irq_postinstall(dev);
241 if (ret < 0) {
242 mutex_lock(&dev->struct_mutex);
243 dev->irq_enabled = 0;
244 mutex_unlock(&dev->struct_mutex);
245 }
246
247 return ret;
248}
249
250/**
251 * Uninstall the IRQ handler.
252 *
253 * \param dev DRM device.
254 *
255 * Calls the driver's \c drm_driver_irq_uninstall() function, and stops the irq.
256 */
257int drm_irq_uninstall(struct drm_device * dev)
258{
259 int irq_enabled;
260
261 if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
262 return -EINVAL;
263
264 mutex_lock(&dev->struct_mutex);
265 irq_enabled = dev->irq_enabled;
266 dev->irq_enabled = 0;
267 mutex_unlock(&dev->struct_mutex);
268
269 if (!irq_enabled)
270 return -EINVAL;
271
272 DRM_DEBUG("irq=%d\n", dev->irq);
273
274 dev->driver->irq_uninstall(dev);
275
276 free_irq(dev->irq, dev);
277
278 drm_vblank_cleanup(dev);
279
280 dev->locked_tasklet_func = NULL;
281
282 return 0;
283}
284
285EXPORT_SYMBOL(drm_irq_uninstall);
286
287/**
288 * IRQ control ioctl.
289 *
290 * \param inode device inode.
291 * \param file_priv DRM file private.
292 * \param cmd command.
293 * \param arg user argument, pointing to a drm_control structure.
294 * \return zero on success or a negative number on failure.
295 *
296 * Calls irq_install() or irq_uninstall() according to \p arg.
297 */
298int drm_control(struct drm_device *dev, void *data,
299 struct drm_file *file_priv)
300{
301 struct drm_control *ctl = data;
302
303 /* if we haven't irq we fallback for compatibility reasons - this used to be a separate function in drm_dma.h */
304
305
306 switch (ctl->func) {
307 case DRM_INST_HANDLER:
308 if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
309 return 0;
310 if (dev->if_version < DRM_IF_VERSION(1, 2) &&
311 ctl->irq != dev->irq)
312 return -EINVAL;
313 return drm_irq_install(dev);
314 case DRM_UNINST_HANDLER:
315 if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
316 return 0;
317 return drm_irq_uninstall(dev);
318 default:
319 return -EINVAL;
320 }
321}
322
323/**
324 * drm_vblank_count - retrieve "cooked" vblank counter value
325 * @dev: DRM device
326 * @crtc: which counter to retrieve
327 *
328 * Fetches the "cooked" vblank count value that represents the number of
329 * vblank events since the system was booted, including lost events due to
330 * modesetting activity.
331 */
332u32 drm_vblank_count(struct drm_device *dev, int crtc)
333{
334 return atomic_read(&dev->_vblank_count[crtc]) +
335 dev->vblank_offset[crtc];
336}
337EXPORT_SYMBOL(drm_vblank_count);
338
339/**
340 * drm_update_vblank_count - update the master vblank counter
341 * @dev: DRM device
342 * @crtc: counter to update
343 *
344 * Call back into the driver to update the appropriate vblank counter
345 * (specified by @crtc). Deal with wraparound, if it occurred, and
346 * update the last read value so we can deal with wraparound on the next
347 * call if necessary.
348 */
349void drm_update_vblank_count(struct drm_device *dev, int crtc)
350{
351 unsigned long irqflags;
352 u32 cur_vblank, diff;
353
354 /*
355 * Interrupts were disabled prior to this call, so deal with counter
356 * wrap if needed.
357 * NOTE! It's possible we lost a full dev->max_vblank_count events
358 * here if the register is small or we had vblank interrupts off for
359 * a long time.
360 */
361 cur_vblank = dev->driver->get_vblank_counter(dev, crtc);
362 spin_lock_irqsave(&dev->vbl_lock, irqflags);
363 if (cur_vblank < dev->last_vblank[crtc]) {
364 diff = dev->max_vblank_count -
365 dev->last_vblank[crtc];
366 diff += cur_vblank;
367 } else {
368 diff = cur_vblank - dev->last_vblank[crtc];
369 }
370 dev->last_vblank[crtc] = cur_vblank;
371 spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
372
373 atomic_add(diff, &dev->_vblank_count[crtc]);
374}
375EXPORT_SYMBOL(drm_update_vblank_count);
376
377/**
378 * drm_vblank_get - get a reference count on vblank events
379 * @dev: DRM device
380 * @crtc: which CRTC to own
381 *
382 * Acquire a reference count on vblank events to avoid having them disabled
383 * while in use. Note callers will probably want to update the master counter
384 * using drm_update_vblank_count() above before calling this routine so that
385 * wakeups occur on the right vblank event.
386 *
387 * RETURNS
388 * Zero on success, nonzero on failure.
389 */
390int drm_vblank_get(struct drm_device *dev, int crtc)
391{
392 unsigned long irqflags;
393 int ret = 0;
394
395 spin_lock_irqsave(&dev->vbl_lock, irqflags);
396 /* Going from 0->1 means we have to enable interrupts again */
397 if (atomic_add_return(1, &dev->vblank_refcount[crtc]) == 1 &&
398 !dev->vblank_enabled[crtc]) {
399 ret = dev->driver->enable_vblank(dev, crtc);
400 if (ret)
401 atomic_dec(&dev->vblank_refcount[crtc]);
402 else
403 dev->vblank_enabled[crtc] = 1;
404 }
405 spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
406
407 return ret;
408}
409EXPORT_SYMBOL(drm_vblank_get);
410
411/**
412 * drm_vblank_put - give up ownership of vblank events
413 * @dev: DRM device
414 * @crtc: which counter to give up
415 *
416 * Release ownership of a given vblank counter, turning off interrupts
417 * if possible.
418 */
419void drm_vblank_put(struct drm_device *dev, int crtc)
420{
421 /* Last user schedules interrupt disable */
422 if (atomic_dec_and_test(&dev->vblank_refcount[crtc]))
423 mod_timer(&dev->vblank_disable_timer, jiffies + 5*DRM_HZ);
424}
425EXPORT_SYMBOL(drm_vblank_put);
426
427/**
428 * drm_modeset_ctl - handle vblank event counter changes across mode switch
429 * @DRM_IOCTL_ARGS: standard ioctl arguments
430 *
431 * Applications should call the %_DRM_PRE_MODESET and %_DRM_POST_MODESET
432 * ioctls around modesetting so that any lost vblank events are accounted for.
433 */
434int drm_modeset_ctl(struct drm_device *dev, void *data,
435 struct drm_file *file_priv)
436{
437 struct drm_modeset_ctl *modeset = data;
438 int crtc, ret = 0;
439 u32 new;
440
441 crtc = modeset->arg;
442 if (crtc >= dev->num_crtcs) {
443 ret = -EINVAL;
444 goto out;
445 }
446
447 switch (modeset->cmd) {
448 case _DRM_PRE_MODESET:
449 dev->vblank_premodeset[crtc] =
450 dev->driver->get_vblank_counter(dev, crtc);
451 break;
452 case _DRM_POST_MODESET:
453 new = dev->driver->get_vblank_counter(dev, crtc);
454 dev->vblank_offset[crtc] = dev->vblank_premodeset[crtc] - new;
455 break;
456 default:
457 ret = -EINVAL;
458 break;
459 }
460
461out:
462 return ret;
463}
464
465/**
466 * Wait for VBLANK.
467 *
468 * \param inode device inode.
469 * \param file_priv DRM file private.
470 * \param cmd command.
471 * \param data user argument, pointing to a drm_wait_vblank structure.
472 * \return zero on success or a negative number on failure.
473 *
474 * Verifies the IRQ is installed.
475 *
476 * If a signal is requested checks if this task has already scheduled the same signal
477 * for the same vblank sequence number - nothing to be done in
478 * that case. If the number of tasks waiting for the interrupt exceeds 100 the
479 * function fails. Otherwise adds a new entry to drm_device::vbl_sigs for this
480 * task.
481 *
482 * If a signal is not requested, then calls vblank_wait().
483 */
484int drm_wait_vblank(struct drm_device *dev, void *data,
485 struct drm_file *file_priv)
486{
487 union drm_wait_vblank *vblwait = data;
488 struct timeval now;
489 int ret = 0;
490 unsigned int flags, seq, crtc;
491
492 if ((!dev->irq) || (!dev->irq_enabled))
493 return -EINVAL;
494
495 if (vblwait->request.type &
496 ~(_DRM_VBLANK_TYPES_MASK | _DRM_VBLANK_FLAGS_MASK)) {
497 DRM_ERROR("Unsupported type value 0x%x, supported mask 0x%x\n",
498 vblwait->request.type,
499 (_DRM_VBLANK_TYPES_MASK | _DRM_VBLANK_FLAGS_MASK));
500 return -EINVAL;
501 }
502
503 flags = vblwait->request.type & _DRM_VBLANK_FLAGS_MASK;
504 crtc = flags & _DRM_VBLANK_SECONDARY ? 1 : 0;
505
506 if (crtc >= dev->num_crtcs)
507 return -EINVAL;
508
509 drm_update_vblank_count(dev, crtc);
510 seq = drm_vblank_count(dev, crtc);
511
512 switch (vblwait->request.type & _DRM_VBLANK_TYPES_MASK) {
513 case _DRM_VBLANK_RELATIVE:
514 vblwait->request.sequence += seq;
515 vblwait->request.type &= ~_DRM_VBLANK_RELATIVE;
516 case _DRM_VBLANK_ABSOLUTE:
517 break;
518 default:
519 return -EINVAL;
520 }
521
522 if ((flags & _DRM_VBLANK_NEXTONMISS) &&
523 (seq - vblwait->request.sequence) <= (1<<23)) {
524 vblwait->request.sequence = seq + 1;
525 }
526
527 if (flags & _DRM_VBLANK_SIGNAL) {
528 unsigned long irqflags;
529 struct list_head *vbl_sigs = &dev->vbl_sigs[crtc];
530 struct drm_vbl_sig *vbl_sig;
531
532 spin_lock_irqsave(&dev->vbl_lock, irqflags);
533
534 /* Check if this task has already scheduled the same signal
535 * for the same vblank sequence number; nothing to be done in
536 * that case
537 */
538 list_for_each_entry(vbl_sig, vbl_sigs, head) {
539 if (vbl_sig->sequence == vblwait->request.sequence
540 && vbl_sig->info.si_signo ==
541 vblwait->request.signal
542 && vbl_sig->task == current) {
543 spin_unlock_irqrestore(&dev->vbl_lock,
544 irqflags);
545 vblwait->reply.sequence = seq;
546 goto done;
547 }
548 }
549
550 if (atomic_read(&dev->vbl_signal_pending) >= 100) {
551 spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
552 return -EBUSY;
553 }
554
555 spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
556
557 vbl_sig = drm_calloc(1, sizeof(struct drm_vbl_sig),
558 DRM_MEM_DRIVER);
559 if (!vbl_sig)
560 return -ENOMEM;
561
562 ret = drm_vblank_get(dev, crtc);
563 if (ret) {
564 drm_free(vbl_sig, sizeof(struct drm_vbl_sig),
565 DRM_MEM_DRIVER);
566 return ret;
567 }
568
569 atomic_inc(&dev->vbl_signal_pending);
570
571 vbl_sig->sequence = vblwait->request.sequence;
572 vbl_sig->info.si_signo = vblwait->request.signal;
573 vbl_sig->task = current;
574
575 spin_lock_irqsave(&dev->vbl_lock, irqflags);
576
577 list_add_tail(&vbl_sig->head, vbl_sigs);
578
579 spin_unlock_irqrestore(&dev->vbl_lock, irqflags);
580
581 vblwait->reply.sequence = seq;
582 } else {
583 unsigned long cur_vblank;
584
585 ret = drm_vblank_get(dev, crtc);
586 if (ret)
587 return ret;
588 DRM_WAIT_ON(ret, dev->vbl_queue[crtc], 3 * DRM_HZ,
589 (((cur_vblank = drm_vblank_count(dev, crtc))
590 - vblwait->request.sequence) <= (1 << 23)));
591 drm_vblank_put(dev, crtc);
592 do_gettimeofday(&now);
593
594 vblwait->reply.tval_sec = now.tv_sec;
595 vblwait->reply.tval_usec = now.tv_usec;
596 vblwait->reply.sequence = cur_vblank;
597 }
598
599 done:
600 return ret;
601}
602
603/**
604 * Send the VBLANK signals.
605 *
606 * \param dev DRM device.
607 * \param crtc CRTC where the vblank event occurred
608 *
609 * Sends a signal for each task in drm_device::vbl_sigs and empties the list.
610 *
611 * If a signal is not requested, then calls vblank_wait().
612 */
613static void drm_vbl_send_signals(struct drm_device * dev, int crtc)
614{
615 struct drm_vbl_sig *vbl_sig, *tmp;
616 struct list_head *vbl_sigs;
617 unsigned int vbl_seq;
618 unsigned long flags;
619
620 spin_lock_irqsave(&dev->vbl_lock, flags);
621
622 vbl_sigs = &dev->vbl_sigs[crtc];
623 vbl_seq = drm_vblank_count(dev, crtc);
624
625 list_for_each_entry_safe(vbl_sig, tmp, vbl_sigs, head) {
626 if ((vbl_seq - vbl_sig->sequence) <= (1 << 23)) {
627 vbl_sig->info.si_code = vbl_seq;
628 send_sig_info(vbl_sig->info.si_signo,
629 &vbl_sig->info, vbl_sig->task);
630
631 list_del(&vbl_sig->head);
632
633 drm_free(vbl_sig, sizeof(*vbl_sig),
634 DRM_MEM_DRIVER);
635 atomic_dec(&dev->vbl_signal_pending);
636 drm_vblank_put(dev, crtc);
637 }
638 }
639
640 spin_unlock_irqrestore(&dev->vbl_lock, flags);
641}
642
643/**
644 * drm_handle_vblank - handle a vblank event
645 * @dev: DRM device
646 * @crtc: where this event occurred
647 *
648 * Drivers should call this routine in their vblank interrupt handlers to
649 * update the vblank counter and send any signals that may be pending.
650 */
651void drm_handle_vblank(struct drm_device *dev, int crtc)
652{
653 drm_update_vblank_count(dev, crtc);
654 DRM_WAKEUP(&dev->vbl_queue[crtc]);
655 drm_vbl_send_signals(dev, crtc);
656}
657EXPORT_SYMBOL(drm_handle_vblank);
658
659/**
660 * Tasklet wrapper function.
661 *
662 * \param data DRM device in disguise.
663 *
664 * Attempts to grab the HW lock and calls the driver callback on success. On
665 * failure, leave the lock marked as contended so the callback can be called
666 * from drm_unlock().
667 */
668static void drm_locked_tasklet_func(unsigned long data)
669{
670 struct drm_device *dev = (struct drm_device *)data;
671 unsigned long irqflags;
672
673 spin_lock_irqsave(&dev->tasklet_lock, irqflags);
674
675 if (!dev->locked_tasklet_func ||
676 !drm_lock_take(&dev->lock,
677 DRM_KERNEL_CONTEXT)) {
678 spin_unlock_irqrestore(&dev->tasklet_lock, irqflags);
679 return;
680 }
681
682 dev->lock.lock_time = jiffies;
683 atomic_inc(&dev->counts[_DRM_STAT_LOCKS]);
684
685 dev->locked_tasklet_func(dev);
686
687 drm_lock_free(&dev->lock,
688 DRM_KERNEL_CONTEXT);
689
690 dev->locked_tasklet_func = NULL;
691
692 spin_unlock_irqrestore(&dev->tasklet_lock, irqflags);
693}
694
695/**
696 * Schedule a tasklet to call back a driver hook with the HW lock held.
697 *
698 * \param dev DRM device.
699 * \param func Driver callback.
700 *
701 * This is intended for triggering actions that require the HW lock from an
702 * interrupt handler. The lock will be grabbed ASAP after the interrupt handler
703 * completes. Note that the callback may be called from interrupt or process
704 * context, it must not make any assumptions about this. Also, the HW lock will
705 * be held with the kernel context or any client context.
706 */
707void drm_locked_tasklet(struct drm_device *dev, void (*func)(struct drm_device *))
708{
709 unsigned long irqflags;
710 static DECLARE_TASKLET(drm_tasklet, drm_locked_tasklet_func, 0);
711
712 if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ) ||
713 test_bit(TASKLET_STATE_SCHED, &drm_tasklet.state))
714 return;
715
716 spin_lock_irqsave(&dev->tasklet_lock, irqflags);
717
718 if (dev->locked_tasklet_func) {
719 spin_unlock_irqrestore(&dev->tasklet_lock, irqflags);
720 return;
721 }
722
723 dev->locked_tasklet_func = func;
724
725 spin_unlock_irqrestore(&dev->tasklet_lock, irqflags);
726
727 drm_tasklet.data = (unsigned long)dev;
728
729 tasklet_hi_schedule(&drm_tasklet);
730}
731EXPORT_SYMBOL(drm_locked_tasklet);
diff --git a/drivers/char/drm/drm_lock.c b/drivers/char/drm/drm_lock.c
deleted file mode 100644
index 12dcdd1832f0..000000000000
--- a/drivers/char/drm/drm_lock.c
+++ /dev/null
@@ -1,396 +0,0 @@
1/**
2 * \file drm_lock.c
3 * IOCTLs for locking
4 *
5 * \author Rickard E. (Rik) Faith <faith@valinux.com>
6 * \author Gareth Hughes <gareth@valinux.com>
7 */
8
9/*
10 * Created: Tue Feb 2 08:37:54 1999 by faith@valinux.com
11 *
12 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
13 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
14 * All Rights Reserved.
15 *
16 * Permission is hereby granted, free of charge, to any person obtaining a
17 * copy of this software and associated documentation files (the "Software"),
18 * to deal in the Software without restriction, including without limitation
19 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
20 * and/or sell copies of the Software, and to permit persons to whom the
21 * Software is furnished to do so, subject to the following conditions:
22 *
23 * The above copyright notice and this permission notice (including the next
24 * paragraph) shall be included in all copies or substantial portions of the
25 * Software.
26 *
27 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
30 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
31 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
32 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
33 * OTHER DEALINGS IN THE SOFTWARE.
34 */
35
36#include "drmP.h"
37
38static int drm_notifier(void *priv);
39
40/**
41 * Lock ioctl.
42 *
43 * \param inode device inode.
44 * \param file_priv DRM file private.
45 * \param cmd command.
46 * \param arg user argument, pointing to a drm_lock structure.
47 * \return zero on success or negative number on failure.
48 *
49 * Add the current task to the lock wait queue, and attempt to take to lock.
50 */
51int drm_lock(struct drm_device *dev, void *data, struct drm_file *file_priv)
52{
53 DECLARE_WAITQUEUE(entry, current);
54 struct drm_lock *lock = data;
55 int ret = 0;
56 unsigned long irqflags;
57
58 ++file_priv->lock_count;
59
60 if (lock->context == DRM_KERNEL_CONTEXT) {
61 DRM_ERROR("Process %d using kernel context %d\n",
62 task_pid_nr(current), lock->context);
63 return -EINVAL;
64 }
65
66 DRM_DEBUG("%d (pid %d) requests lock (0x%08x), flags = 0x%08x\n",
67 lock->context, task_pid_nr(current),
68 dev->lock.hw_lock->lock, lock->flags);
69
70 if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE))
71 if (lock->context < 0)
72 return -EINVAL;
73
74 add_wait_queue(&dev->lock.lock_queue, &entry);
75 spin_lock_irqsave(&dev->lock.spinlock, irqflags);
76 dev->lock.user_waiters++;
77 spin_unlock_irqrestore(&dev->lock.spinlock, irqflags);
78 for (;;) {
79 __set_current_state(TASK_INTERRUPTIBLE);
80 if (!dev->lock.hw_lock) {
81 /* Device has been unregistered */
82 ret = -EINTR;
83 break;
84 }
85 if (drm_lock_take(&dev->lock, lock->context)) {
86 dev->lock.file_priv = file_priv;
87 dev->lock.lock_time = jiffies;
88 atomic_inc(&dev->counts[_DRM_STAT_LOCKS]);
89 break; /* Got lock */
90 }
91
92 /* Contention */
93 schedule();
94 if (signal_pending(current)) {
95 ret = -ERESTARTSYS;
96 break;
97 }
98 }
99 spin_lock_irqsave(&dev->lock.spinlock, irqflags);
100 dev->lock.user_waiters--;
101 spin_unlock_irqrestore(&dev->lock.spinlock, irqflags);
102 __set_current_state(TASK_RUNNING);
103 remove_wait_queue(&dev->lock.lock_queue, &entry);
104
105 DRM_DEBUG("%d %s\n", lock->context,
106 ret ? "interrupted" : "has lock");
107 if (ret) return ret;
108
109 sigemptyset(&dev->sigmask);
110 sigaddset(&dev->sigmask, SIGSTOP);
111 sigaddset(&dev->sigmask, SIGTSTP);
112 sigaddset(&dev->sigmask, SIGTTIN);
113 sigaddset(&dev->sigmask, SIGTTOU);
114 dev->sigdata.context = lock->context;
115 dev->sigdata.lock = dev->lock.hw_lock;
116 block_all_signals(drm_notifier, &dev->sigdata, &dev->sigmask);
117
118 if (dev->driver->dma_ready && (lock->flags & _DRM_LOCK_READY))
119 dev->driver->dma_ready(dev);
120
121 if (dev->driver->dma_quiescent && (lock->flags & _DRM_LOCK_QUIESCENT))
122 {
123 if (dev->driver->dma_quiescent(dev)) {
124 DRM_DEBUG("%d waiting for DMA quiescent\n",
125 lock->context);
126 return -EBUSY;
127 }
128 }
129
130 if (dev->driver->kernel_context_switch &&
131 dev->last_context != lock->context) {
132 dev->driver->kernel_context_switch(dev, dev->last_context,
133 lock->context);
134 }
135
136 return 0;
137}
138
139/**
140 * Unlock ioctl.
141 *
142 * \param inode device inode.
143 * \param file_priv DRM file private.
144 * \param cmd command.
145 * \param arg user argument, pointing to a drm_lock structure.
146 * \return zero on success or negative number on failure.
147 *
148 * Transfer and free the lock.
149 */
150int drm_unlock(struct drm_device *dev, void *data, struct drm_file *file_priv)
151{
152 struct drm_lock *lock = data;
153 unsigned long irqflags;
154
155 if (lock->context == DRM_KERNEL_CONTEXT) {
156 DRM_ERROR("Process %d using kernel context %d\n",
157 task_pid_nr(current), lock->context);
158 return -EINVAL;
159 }
160
161 spin_lock_irqsave(&dev->tasklet_lock, irqflags);
162
163 if (dev->locked_tasklet_func) {
164 dev->locked_tasklet_func(dev);
165
166 dev->locked_tasklet_func = NULL;
167 }
168
169 spin_unlock_irqrestore(&dev->tasklet_lock, irqflags);
170
171 atomic_inc(&dev->counts[_DRM_STAT_UNLOCKS]);
172
173 /* kernel_context_switch isn't used by any of the x86 drm
174 * modules but is required by the Sparc driver.
175 */
176 if (dev->driver->kernel_context_switch_unlock)
177 dev->driver->kernel_context_switch_unlock(dev);
178 else {
179 if (drm_lock_free(&dev->lock,lock->context)) {
180 /* FIXME: Should really bail out here. */
181 }
182 }
183
184 unblock_all_signals();
185 return 0;
186}
187
188/**
189 * Take the heavyweight lock.
190 *
191 * \param lock lock pointer.
192 * \param context locking context.
193 * \return one if the lock is held, or zero otherwise.
194 *
195 * Attempt to mark the lock as held by the given context, via the \p cmpxchg instruction.
196 */
197int drm_lock_take(struct drm_lock_data *lock_data,
198 unsigned int context)
199{
200 unsigned int old, new, prev;
201 volatile unsigned int *lock = &lock_data->hw_lock->lock;
202 unsigned long irqflags;
203
204 spin_lock_irqsave(&lock_data->spinlock, irqflags);
205 do {
206 old = *lock;
207 if (old & _DRM_LOCK_HELD)
208 new = old | _DRM_LOCK_CONT;
209 else {
210 new = context | _DRM_LOCK_HELD |
211 ((lock_data->user_waiters + lock_data->kernel_waiters > 1) ?
212 _DRM_LOCK_CONT : 0);
213 }
214 prev = cmpxchg(lock, old, new);
215 } while (prev != old);
216 spin_unlock_irqrestore(&lock_data->spinlock, irqflags);
217
218 if (_DRM_LOCKING_CONTEXT(old) == context) {
219 if (old & _DRM_LOCK_HELD) {
220 if (context != DRM_KERNEL_CONTEXT) {
221 DRM_ERROR("%d holds heavyweight lock\n",
222 context);
223 }
224 return 0;
225 }
226 }
227
228 if ((_DRM_LOCKING_CONTEXT(new)) == context && (new & _DRM_LOCK_HELD)) {
229 /* Have lock */
230 return 1;
231 }
232 return 0;
233}
234
235/**
236 * This takes a lock forcibly and hands it to context. Should ONLY be used
237 * inside *_unlock to give lock to kernel before calling *_dma_schedule.
238 *
239 * \param dev DRM device.
240 * \param lock lock pointer.
241 * \param context locking context.
242 * \return always one.
243 *
244 * Resets the lock file pointer.
245 * Marks the lock as held by the given context, via the \p cmpxchg instruction.
246 */
247static int drm_lock_transfer(struct drm_lock_data *lock_data,
248 unsigned int context)
249{
250 unsigned int old, new, prev;
251 volatile unsigned int *lock = &lock_data->hw_lock->lock;
252
253 lock_data->file_priv = NULL;
254 do {
255 old = *lock;
256 new = context | _DRM_LOCK_HELD;
257 prev = cmpxchg(lock, old, new);
258 } while (prev != old);
259 return 1;
260}
261
262/**
263 * Free lock.
264 *
265 * \param dev DRM device.
266 * \param lock lock.
267 * \param context context.
268 *
269 * Resets the lock file pointer.
270 * Marks the lock as not held, via the \p cmpxchg instruction. Wakes any task
271 * waiting on the lock queue.
272 */
273int drm_lock_free(struct drm_lock_data *lock_data, unsigned int context)
274{
275 unsigned int old, new, prev;
276 volatile unsigned int *lock = &lock_data->hw_lock->lock;
277 unsigned long irqflags;
278
279 spin_lock_irqsave(&lock_data->spinlock, irqflags);
280 if (lock_data->kernel_waiters != 0) {
281 drm_lock_transfer(lock_data, 0);
282 lock_data->idle_has_lock = 1;
283 spin_unlock_irqrestore(&lock_data->spinlock, irqflags);
284 return 1;
285 }
286 spin_unlock_irqrestore(&lock_data->spinlock, irqflags);
287
288 do {
289 old = *lock;
290 new = _DRM_LOCKING_CONTEXT(old);
291 prev = cmpxchg(lock, old, new);
292 } while (prev != old);
293
294 if (_DRM_LOCK_IS_HELD(old) && _DRM_LOCKING_CONTEXT(old) != context) {
295 DRM_ERROR("%d freed heavyweight lock held by %d\n",
296 context, _DRM_LOCKING_CONTEXT(old));
297 return 1;
298 }
299 wake_up_interruptible(&lock_data->lock_queue);
300 return 0;
301}
302
303/**
304 * If we get here, it means that the process has called DRM_IOCTL_LOCK
305 * without calling DRM_IOCTL_UNLOCK.
306 *
307 * If the lock is not held, then let the signal proceed as usual. If the lock
308 * is held, then set the contended flag and keep the signal blocked.
309 *
310 * \param priv pointer to a drm_sigdata structure.
311 * \return one if the signal should be delivered normally, or zero if the
312 * signal should be blocked.
313 */
314static int drm_notifier(void *priv)
315{
316 struct drm_sigdata *s = (struct drm_sigdata *) priv;
317 unsigned int old, new, prev;
318
319 /* Allow signal delivery if lock isn't held */
320 if (!s->lock || !_DRM_LOCK_IS_HELD(s->lock->lock)
321 || _DRM_LOCKING_CONTEXT(s->lock->lock) != s->context)
322 return 1;
323
324 /* Otherwise, set flag to force call to
325 drmUnlock */
326 do {
327 old = s->lock->lock;
328 new = old | _DRM_LOCK_CONT;
329 prev = cmpxchg(&s->lock->lock, old, new);
330 } while (prev != old);
331 return 0;
332}
333
334/**
335 * This function returns immediately and takes the hw lock
336 * with the kernel context if it is free, otherwise it gets the highest priority when and if
337 * it is eventually released.
338 *
339 * This guarantees that the kernel will _eventually_ have the lock _unless_ it is held
340 * by a blocked process. (In the latter case an explicit wait for the hardware lock would cause
341 * a deadlock, which is why the "idlelock" was invented).
342 *
343 * This should be sufficient to wait for GPU idle without
344 * having to worry about starvation.
345 */
346
347void drm_idlelock_take(struct drm_lock_data *lock_data)
348{
349 int ret = 0;
350 unsigned long irqflags;
351
352 spin_lock_irqsave(&lock_data->spinlock, irqflags);
353 lock_data->kernel_waiters++;
354 if (!lock_data->idle_has_lock) {
355
356 spin_unlock_irqrestore(&lock_data->spinlock, irqflags);
357 ret = drm_lock_take(lock_data, DRM_KERNEL_CONTEXT);
358 spin_lock_irqsave(&lock_data->spinlock, irqflags);
359
360 if (ret == 1)
361 lock_data->idle_has_lock = 1;
362 }
363 spin_unlock_irqrestore(&lock_data->spinlock, irqflags);
364}
365EXPORT_SYMBOL(drm_idlelock_take);
366
367void drm_idlelock_release(struct drm_lock_data *lock_data)
368{
369 unsigned int old, prev;
370 volatile unsigned int *lock = &lock_data->hw_lock->lock;
371 unsigned long irqflags;
372
373 spin_lock_irqsave(&lock_data->spinlock, irqflags);
374 if (--lock_data->kernel_waiters == 0) {
375 if (lock_data->idle_has_lock) {
376 do {
377 old = *lock;
378 prev = cmpxchg(lock, old, DRM_KERNEL_CONTEXT);
379 } while (prev != old);
380 wake_up_interruptible(&lock_data->lock_queue);
381 lock_data->idle_has_lock = 0;
382 }
383 }
384 spin_unlock_irqrestore(&lock_data->spinlock, irqflags);
385}
386EXPORT_SYMBOL(drm_idlelock_release);
387
388
389int drm_i_have_hw_lock(struct drm_device *dev, struct drm_file *file_priv)
390{
391 return (file_priv->lock_count && dev->lock.hw_lock &&
392 _DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) &&
393 dev->lock.file_priv == file_priv);
394}
395
396EXPORT_SYMBOL(drm_i_have_hw_lock);
diff --git a/drivers/char/drm/drm_memory.c b/drivers/char/drm/drm_memory.c
deleted file mode 100644
index 845081b44f63..000000000000
--- a/drivers/char/drm/drm_memory.c
+++ /dev/null
@@ -1,181 +0,0 @@
1/**
2 * \file drm_memory.c
3 * Memory management wrappers for DRM
4 *
5 * \author Rickard E. (Rik) Faith <faith@valinux.com>
6 * \author Gareth Hughes <gareth@valinux.com>
7 */
8
9/*
10 * Created: Thu Feb 4 14:00:34 1999 by faith@valinux.com
11 *
12 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
13 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
14 * All Rights Reserved.
15 *
16 * Permission is hereby granted, free of charge, to any person obtaining a
17 * copy of this software and associated documentation files (the "Software"),
18 * to deal in the Software without restriction, including without limitation
19 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
20 * and/or sell copies of the Software, and to permit persons to whom the
21 * Software is furnished to do so, subject to the following conditions:
22 *
23 * The above copyright notice and this permission notice (including the next
24 * paragraph) shall be included in all copies or substantial portions of the
25 * Software.
26 *
27 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
30 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
31 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
32 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
33 * OTHER DEALINGS IN THE SOFTWARE.
34 */
35
36#include <linux/highmem.h>
37#include "drmP.h"
38
39#ifdef DEBUG_MEMORY
40#include "drm_memory_debug.h"
41#else
42
43/** No-op. */
44void drm_mem_init(void)
45{
46}
47
48/**
49 * Called when "/proc/dri/%dev%/mem" is read.
50 *
51 * \param buf output buffer.
52 * \param start start of output data.
53 * \param offset requested start offset.
54 * \param len requested number of bytes.
55 * \param eof whether there is no more data to return.
56 * \param data private data.
57 * \return number of written bytes.
58 *
59 * No-op.
60 */
61int drm_mem_info(char *buf, char **start, off_t offset,
62 int len, int *eof, void *data)
63{
64 return 0;
65}
66
67/** Wrapper around kmalloc() and kfree() */
68void *drm_realloc(void *oldpt, size_t oldsize, size_t size, int area)
69{
70 void *pt;
71
72 if (!(pt = kmalloc(size, GFP_KERNEL)))
73 return NULL;
74 if (oldpt && oldsize) {
75 memcpy(pt, oldpt, oldsize);
76 kfree(oldpt);
77 }
78 return pt;
79}
80
81#if __OS_HAS_AGP
82static void *agp_remap(unsigned long offset, unsigned long size,
83 struct drm_device * dev)
84{
85 unsigned long *phys_addr_map, i, num_pages =
86 PAGE_ALIGN(size) / PAGE_SIZE;
87 struct drm_agp_mem *agpmem;
88 struct page **page_map;
89 void *addr;
90
91 size = PAGE_ALIGN(size);
92
93#ifdef __alpha__
94 offset -= dev->hose->mem_space->start;
95#endif
96
97 list_for_each_entry(agpmem, &dev->agp->memory, head)
98 if (agpmem->bound <= offset
99 && (agpmem->bound + (agpmem->pages << PAGE_SHIFT)) >=
100 (offset + size))
101 break;
102 if (!agpmem)
103 return NULL;
104
105 /*
106 * OK, we're mapping AGP space on a chipset/platform on which memory accesses by
107 * the CPU do not get remapped by the GART. We fix this by using the kernel's
108 * page-table instead (that's probably faster anyhow...).
109 */
110 /* note: use vmalloc() because num_pages could be large... */
111 page_map = vmalloc(num_pages * sizeof(struct page *));
112 if (!page_map)
113 return NULL;
114
115 phys_addr_map =
116 agpmem->memory->memory + (offset - agpmem->bound) / PAGE_SIZE;
117 for (i = 0; i < num_pages; ++i)
118 page_map[i] = pfn_to_page(phys_addr_map[i] >> PAGE_SHIFT);
119 addr = vmap(page_map, num_pages, VM_IOREMAP, PAGE_AGP);
120 vfree(page_map);
121
122 return addr;
123}
124
125/** Wrapper around agp_allocate_memory() */
126DRM_AGP_MEM *drm_alloc_agp(struct drm_device * dev, int pages, u32 type)
127{
128 return drm_agp_allocate_memory(dev->agp->bridge, pages, type);
129}
130
131/** Wrapper around agp_free_memory() */
132int drm_free_agp(DRM_AGP_MEM * handle, int pages)
133{
134 return drm_agp_free_memory(handle) ? 0 : -EINVAL;
135}
136
137/** Wrapper around agp_bind_memory() */
138int drm_bind_agp(DRM_AGP_MEM * handle, unsigned int start)
139{
140 return drm_agp_bind_memory(handle, start);
141}
142
143/** Wrapper around agp_unbind_memory() */
144int drm_unbind_agp(DRM_AGP_MEM * handle)
145{
146 return drm_agp_unbind_memory(handle);
147}
148
149#else /* __OS_HAS_AGP */
150static inline void *agp_remap(unsigned long offset, unsigned long size,
151 struct drm_device * dev)
152{
153 return NULL;
154}
155
156#endif /* agp */
157
158#endif /* debug_memory */
159
160void drm_core_ioremap(struct drm_map *map, struct drm_device *dev)
161{
162 if (drm_core_has_AGP(dev) &&
163 dev->agp && dev->agp->cant_use_aperture && map->type == _DRM_AGP)
164 map->handle = agp_remap(map->offset, map->size, dev);
165 else
166 map->handle = ioremap(map->offset, map->size);
167}
168EXPORT_SYMBOL(drm_core_ioremap);
169
170void drm_core_ioremapfree(struct drm_map *map, struct drm_device *dev)
171{
172 if (!map->handle || !map->size)
173 return;
174
175 if (drm_core_has_AGP(dev) &&
176 dev->agp && dev->agp->cant_use_aperture && map->type == _DRM_AGP)
177 vunmap(map->handle);
178 else
179 iounmap(map->handle);
180}
181EXPORT_SYMBOL(drm_core_ioremapfree);
diff --git a/drivers/char/drm/drm_memory.h b/drivers/char/drm/drm_memory.h
deleted file mode 100644
index 63e425b5ea82..000000000000
--- a/drivers/char/drm/drm_memory.h
+++ /dev/null
@@ -1,61 +0,0 @@
1/**
2 * \file drm_memory.h
3 * Memory management wrappers for DRM
4 *
5 * \author Rickard E. (Rik) Faith <faith@valinux.com>
6 * \author Gareth Hughes <gareth@valinux.com>
7 */
8
9/*
10 * Created: Thu Feb 4 14:00:34 1999 by faith@valinux.com
11 *
12 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
13 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
14 * All Rights Reserved.
15 *
16 * Permission is hereby granted, free of charge, to any person obtaining a
17 * copy of this software and associated documentation files (the "Software"),
18 * to deal in the Software without restriction, including without limitation
19 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
20 * and/or sell copies of the Software, and to permit persons to whom the
21 * Software is furnished to do so, subject to the following conditions:
22 *
23 * The above copyright notice and this permission notice (including the next
24 * paragraph) shall be included in all copies or substantial portions of the
25 * Software.
26 *
27 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
30 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
31 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
32 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
33 * OTHER DEALINGS IN THE SOFTWARE.
34 */
35
36#include <linux/highmem.h>
37#include <linux/vmalloc.h>
38#include "drmP.h"
39
40/**
41 * Cut down version of drm_memory_debug.h, which used to be called
42 * drm_memory.h.
43 */
44
45#if __OS_HAS_AGP
46
47#include <linux/vmalloc.h>
48
49#ifdef HAVE_PAGE_AGP
50#include <asm/agp.h>
51#else
52# ifdef __powerpc__
53# define PAGE_AGP __pgprot(_PAGE_KERNEL | _PAGE_NO_CACHE)
54# else
55# define PAGE_AGP PAGE_KERNEL
56# endif
57#endif
58
59#else /* __OS_HAS_AGP */
60
61#endif
diff --git a/drivers/char/drm/drm_memory_debug.h b/drivers/char/drm/drm_memory_debug.h
deleted file mode 100644
index 6463271deea8..000000000000
--- a/drivers/char/drm/drm_memory_debug.h
+++ /dev/null
@@ -1,309 +0,0 @@
1/**
2 * \file drm_memory_debug.h
3 * Memory management wrappers for DRM.
4 *
5 * \author Rickard E. (Rik) Faith <faith@valinux.com>
6 * \author Gareth Hughes <gareth@valinux.com>
7 */
8
9/*
10 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
11 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
12 * All Rights Reserved.
13 *
14 * Permission is hereby granted, free of charge, to any person obtaining a
15 * copy of this software and associated documentation files (the "Software"),
16 * to deal in the Software without restriction, including without limitation
17 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
18 * and/or sell copies of the Software, and to permit persons to whom the
19 * Software is furnished to do so, subject to the following conditions:
20 *
21 * The above copyright notice and this permission notice (including the next
22 * paragraph) shall be included in all copies or substantial portions of the
23 * Software.
24 *
25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
28 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
29 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
30 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
31 * OTHER DEALINGS IN THE SOFTWARE.
32 */
33
34#include "drmP.h"
35
36typedef struct drm_mem_stats {
37 const char *name;
38 int succeed_count;
39 int free_count;
40 int fail_count;
41 unsigned long bytes_allocated;
42 unsigned long bytes_freed;
43} drm_mem_stats_t;
44
45static DEFINE_SPINLOCK(drm_mem_lock);
46static unsigned long drm_ram_available = 0; /* In pages */
47static unsigned long drm_ram_used = 0;
48static drm_mem_stats_t drm_mem_stats[] =
49{
50 [DRM_MEM_DMA] = {"dmabufs"},
51 [DRM_MEM_SAREA] = {"sareas"},
52 [DRM_MEM_DRIVER] = {"driver"},
53 [DRM_MEM_MAGIC] = {"magic"},
54 [DRM_MEM_IOCTLS] = {"ioctltab"},
55 [DRM_MEM_MAPS] = {"maplist"},
56 [DRM_MEM_VMAS] = {"vmalist"},
57 [DRM_MEM_BUFS] = {"buflist"},
58 [DRM_MEM_SEGS] = {"seglist"},
59 [DRM_MEM_PAGES] = {"pagelist"},
60 [DRM_MEM_FILES] = {"files"},
61 [DRM_MEM_QUEUES] = {"queues"},
62 [DRM_MEM_CMDS] = {"commands"},
63 [DRM_MEM_MAPPINGS] = {"mappings"},
64 [DRM_MEM_BUFLISTS] = {"buflists"},
65 [DRM_MEM_AGPLISTS] = {"agplist"},
66 [DRM_MEM_SGLISTS] = {"sglist"},
67 [DRM_MEM_TOTALAGP] = {"totalagp"},
68 [DRM_MEM_BOUNDAGP] = {"boundagp"},
69 [DRM_MEM_CTXBITMAP] = {"ctxbitmap"},
70 [DRM_MEM_CTXLIST] = {"ctxlist"},
71 [DRM_MEM_STUB] = {"stub"},
72 {NULL, 0,} /* Last entry must be null */
73};
74
75void drm_mem_init (void) {
76 drm_mem_stats_t *mem;
77 struct sysinfo si;
78
79 for (mem = drm_mem_stats; mem->name; ++mem) {
80 mem->succeed_count = 0;
81 mem->free_count = 0;
82 mem->fail_count = 0;
83 mem->bytes_allocated = 0;
84 mem->bytes_freed = 0;
85 }
86
87 si_meminfo(&si);
88 drm_ram_available = si.totalram;
89 drm_ram_used = 0;
90}
91
92/* drm_mem_info is called whenever a process reads /dev/drm/mem. */
93
94static int drm__mem_info (char *buf, char **start, off_t offset,
95 int request, int *eof, void *data) {
96 drm_mem_stats_t *pt;
97 int len = 0;
98
99 if (offset > DRM_PROC_LIMIT) {
100 *eof = 1;
101 return 0;
102 }
103
104 *eof = 0;
105 *start = &buf[offset];
106
107 DRM_PROC_PRINT(" total counts "
108 " | outstanding \n");
109 DRM_PROC_PRINT("type alloc freed fail bytes freed"
110 " | allocs bytes\n\n");
111 DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu kB |\n",
112 "system", 0, 0, 0,
113 drm_ram_available << (PAGE_SHIFT - 10));
114 DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu kB |\n",
115 "locked", 0, 0, 0, drm_ram_used >> 10);
116 DRM_PROC_PRINT("\n");
117 for (pt = drm_mem_stats; pt->name; pt++) {
118 DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu %10lu | %6d %10ld\n",
119 pt->name,
120 pt->succeed_count,
121 pt->free_count,
122 pt->fail_count,
123 pt->bytes_allocated,
124 pt->bytes_freed,
125 pt->succeed_count - pt->free_count,
126 (long)pt->bytes_allocated
127 - (long)pt->bytes_freed);
128 }
129
130 if (len > request + offset)
131 return request;
132 *eof = 1;
133 return len - offset;
134}
135
136int drm_mem_info (char *buf, char **start, off_t offset,
137 int len, int *eof, void *data) {
138 int ret;
139
140 spin_lock(&drm_mem_lock);
141 ret = drm__mem_info (buf, start, offset, len, eof, data);
142 spin_unlock(&drm_mem_lock);
143 return ret;
144}
145
146void *drm_alloc (size_t size, int area) {
147 void *pt;
148
149 if (!size) {
150 DRM_MEM_ERROR(area, "Allocating 0 bytes\n");
151 return NULL;
152 }
153
154 if (!(pt = kmalloc(size, GFP_KERNEL))) {
155 spin_lock(&drm_mem_lock);
156 ++drm_mem_stats[area].fail_count;
157 spin_unlock(&drm_mem_lock);
158 return NULL;
159 }
160 spin_lock(&drm_mem_lock);
161 ++drm_mem_stats[area].succeed_count;
162 drm_mem_stats[area].bytes_allocated += size;
163 spin_unlock(&drm_mem_lock);
164 return pt;
165}
166
167void *drm_calloc (size_t nmemb, size_t size, int area) {
168 void *addr;
169
170 addr = drm_alloc (nmemb * size, area);
171 if (addr != NULL)
172 memset((void *)addr, 0, size * nmemb);
173
174 return addr;
175}
176
177void *drm_realloc (void *oldpt, size_t oldsize, size_t size, int area) {
178 void *pt;
179
180 if (!(pt = drm_alloc (size, area)))
181 return NULL;
182 if (oldpt && oldsize) {
183 memcpy(pt, oldpt, oldsize);
184 drm_free (oldpt, oldsize, area);
185 }
186 return pt;
187}
188
189void drm_free (void *pt, size_t size, int area) {
190 int alloc_count;
191 int free_count;
192
193 if (!pt)
194 DRM_MEM_ERROR(area, "Attempt to free NULL pointer\n");
195 else
196 kfree(pt);
197 spin_lock(&drm_mem_lock);
198 drm_mem_stats[area].bytes_freed += size;
199 free_count = ++drm_mem_stats[area].free_count;
200 alloc_count = drm_mem_stats[area].succeed_count;
201 spin_unlock(&drm_mem_lock);
202 if (free_count > alloc_count) {
203 DRM_MEM_ERROR(area, "Excess frees: %d frees, %d allocs\n",
204 free_count, alloc_count);
205 }
206}
207
208#if __OS_HAS_AGP
209
210DRM_AGP_MEM *drm_alloc_agp (drm_device_t *dev, int pages, u32 type) {
211 DRM_AGP_MEM *handle;
212
213 if (!pages) {
214 DRM_MEM_ERROR(DRM_MEM_TOTALAGP, "Allocating 0 pages\n");
215 return NULL;
216 }
217
218 if ((handle = drm_agp_allocate_memory (pages, type))) {
219 spin_lock(&drm_mem_lock);
220 ++drm_mem_stats[DRM_MEM_TOTALAGP].succeed_count;
221 drm_mem_stats[DRM_MEM_TOTALAGP].bytes_allocated
222 += pages << PAGE_SHIFT;
223 spin_unlock(&drm_mem_lock);
224 return handle;
225 }
226 spin_lock(&drm_mem_lock);
227 ++drm_mem_stats[DRM_MEM_TOTALAGP].fail_count;
228 spin_unlock(&drm_mem_lock);
229 return NULL;
230}
231
232int drm_free_agp (DRM_AGP_MEM * handle, int pages) {
233 int alloc_count;
234 int free_count;
235 int retval = -EINVAL;
236
237 if (!handle) {
238 DRM_MEM_ERROR(DRM_MEM_TOTALAGP,
239 "Attempt to free NULL AGP handle\n");
240 return retval;
241 }
242
243 if (drm_agp_free_memory (handle)) {
244 spin_lock(&drm_mem_lock);
245 free_count = ++drm_mem_stats[DRM_MEM_TOTALAGP].free_count;
246 alloc_count = drm_mem_stats[DRM_MEM_TOTALAGP].succeed_count;
247 drm_mem_stats[DRM_MEM_TOTALAGP].bytes_freed
248 += pages << PAGE_SHIFT;
249 spin_unlock(&drm_mem_lock);
250 if (free_count > alloc_count) {
251 DRM_MEM_ERROR(DRM_MEM_TOTALAGP,
252 "Excess frees: %d frees, %d allocs\n",
253 free_count, alloc_count);
254 }
255 return 0;
256 }
257 return retval;
258}
259
260int drm_bind_agp (DRM_AGP_MEM * handle, unsigned int start) {
261 int retcode = -EINVAL;
262
263 if (!handle) {
264 DRM_MEM_ERROR(DRM_MEM_BOUNDAGP,
265 "Attempt to bind NULL AGP handle\n");
266 return retcode;
267 }
268
269 if (!(retcode = drm_agp_bind_memory (handle, start))) {
270 spin_lock(&drm_mem_lock);
271 ++drm_mem_stats[DRM_MEM_BOUNDAGP].succeed_count;
272 drm_mem_stats[DRM_MEM_BOUNDAGP].bytes_allocated
273 += handle->page_count << PAGE_SHIFT;
274 spin_unlock(&drm_mem_lock);
275 return retcode;
276 }
277 spin_lock(&drm_mem_lock);
278 ++drm_mem_stats[DRM_MEM_BOUNDAGP].fail_count;
279 spin_unlock(&drm_mem_lock);
280 return retcode;
281}
282
283int drm_unbind_agp (DRM_AGP_MEM * handle) {
284 int alloc_count;
285 int free_count;
286 int retcode = -EINVAL;
287
288 if (!handle) {
289 DRM_MEM_ERROR(DRM_MEM_BOUNDAGP,
290 "Attempt to unbind NULL AGP handle\n");
291 return retcode;
292 }
293
294 if ((retcode = drm_agp_unbind_memory (handle)))
295 return retcode;
296 spin_lock(&drm_mem_lock);
297 free_count = ++drm_mem_stats[DRM_MEM_BOUNDAGP].free_count;
298 alloc_count = drm_mem_stats[DRM_MEM_BOUNDAGP].succeed_count;
299 drm_mem_stats[DRM_MEM_BOUNDAGP].bytes_freed
300 += handle->page_count << PAGE_SHIFT;
301 spin_unlock(&drm_mem_lock);
302 if (free_count > alloc_count) {
303 DRM_MEM_ERROR(DRM_MEM_BOUNDAGP,
304 "Excess frees: %d frees, %d allocs\n",
305 free_count, alloc_count);
306 }
307 return retcode;
308}
309#endif
diff --git a/drivers/char/drm/drm_mm.c b/drivers/char/drm/drm_mm.c
deleted file mode 100644
index dcff9e9b52e3..000000000000
--- a/drivers/char/drm/drm_mm.c
+++ /dev/null
@@ -1,295 +0,0 @@
1/**************************************************************************
2 *
3 * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
22 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24 * USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 *
27 **************************************************************************/
28
29/*
30 * Generic simple memory manager implementation. Intended to be used as a base
31 * class implementation for more advanced memory managers.
32 *
33 * Note that the algorithm used is quite simple and there might be substantial
34 * performance gains if a smarter free list is implemented. Currently it is just an
35 * unordered stack of free regions. This could easily be improved if an RB-tree
36 * is used instead. At least if we expect heavy fragmentation.
37 *
38 * Aligned allocations can also see improvement.
39 *
40 * Authors:
41 * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
42 */
43
44#include "drmP.h"
45#include <linux/slab.h>
46
47unsigned long drm_mm_tail_space(struct drm_mm *mm)
48{
49 struct list_head *tail_node;
50 struct drm_mm_node *entry;
51
52 tail_node = mm->ml_entry.prev;
53 entry = list_entry(tail_node, struct drm_mm_node, ml_entry);
54 if (!entry->free)
55 return 0;
56
57 return entry->size;
58}
59
60int drm_mm_remove_space_from_tail(struct drm_mm *mm, unsigned long size)
61{
62 struct list_head *tail_node;
63 struct drm_mm_node *entry;
64
65 tail_node = mm->ml_entry.prev;
66 entry = list_entry(tail_node, struct drm_mm_node, ml_entry);
67 if (!entry->free)
68 return -ENOMEM;
69
70 if (entry->size <= size)
71 return -ENOMEM;
72
73 entry->size -= size;
74 return 0;
75}
76
77
78static int drm_mm_create_tail_node(struct drm_mm *mm,
79 unsigned long start,
80 unsigned long size)
81{
82 struct drm_mm_node *child;
83
84 child = (struct drm_mm_node *)
85 drm_alloc(sizeof(*child), DRM_MEM_MM);
86 if (!child)
87 return -ENOMEM;
88
89 child->free = 1;
90 child->size = size;
91 child->start = start;
92 child->mm = mm;
93
94 list_add_tail(&child->ml_entry, &mm->ml_entry);
95 list_add_tail(&child->fl_entry, &mm->fl_entry);
96
97 return 0;
98}
99
100
101int drm_mm_add_space_to_tail(struct drm_mm *mm, unsigned long size)
102{
103 struct list_head *tail_node;
104 struct drm_mm_node *entry;
105
106 tail_node = mm->ml_entry.prev;
107 entry = list_entry(tail_node, struct drm_mm_node, ml_entry);
108 if (!entry->free) {
109 return drm_mm_create_tail_node(mm, entry->start + entry->size, size);
110 }
111 entry->size += size;
112 return 0;
113}
114
115static struct drm_mm_node *drm_mm_split_at_start(struct drm_mm_node *parent,
116 unsigned long size)
117{
118 struct drm_mm_node *child;
119
120 child = (struct drm_mm_node *)
121 drm_alloc(sizeof(*child), DRM_MEM_MM);
122 if (!child)
123 return NULL;
124
125 INIT_LIST_HEAD(&child->fl_entry);
126
127 child->free = 0;
128 child->size = size;
129 child->start = parent->start;
130 child->mm = parent->mm;
131
132 list_add_tail(&child->ml_entry, &parent->ml_entry);
133 INIT_LIST_HEAD(&child->fl_entry);
134
135 parent->size -= size;
136 parent->start += size;
137 return child;
138}
139
140
141
142struct drm_mm_node *drm_mm_get_block(struct drm_mm_node * parent,
143 unsigned long size, unsigned alignment)
144{
145
146 struct drm_mm_node *align_splitoff = NULL;
147 struct drm_mm_node *child;
148 unsigned tmp = 0;
149
150 if (alignment)
151 tmp = parent->start % alignment;
152
153 if (tmp) {
154 align_splitoff = drm_mm_split_at_start(parent, alignment - tmp);
155 if (!align_splitoff)
156 return NULL;
157 }
158
159 if (parent->size == size) {
160 list_del_init(&parent->fl_entry);
161 parent->free = 0;
162 return parent;
163 } else {
164 child = drm_mm_split_at_start(parent, size);
165 }
166
167 if (align_splitoff)
168 drm_mm_put_block(align_splitoff);
169
170 return child;
171}
172
173/*
174 * Put a block. Merge with the previous and / or next block if they are free.
175 * Otherwise add to the free stack.
176 */
177
178void drm_mm_put_block(struct drm_mm_node * cur)
179{
180
181 struct drm_mm *mm = cur->mm;
182 struct list_head *cur_head = &cur->ml_entry;
183 struct list_head *root_head = &mm->ml_entry;
184 struct drm_mm_node *prev_node = NULL;
185 struct drm_mm_node *next_node;
186
187 int merged = 0;
188
189 if (cur_head->prev != root_head) {
190 prev_node = list_entry(cur_head->prev, struct drm_mm_node, ml_entry);
191 if (prev_node->free) {
192 prev_node->size += cur->size;
193 merged = 1;
194 }
195 }
196 if (cur_head->next != root_head) {
197 next_node = list_entry(cur_head->next, struct drm_mm_node, ml_entry);
198 if (next_node->free) {
199 if (merged) {
200 prev_node->size += next_node->size;
201 list_del(&next_node->ml_entry);
202 list_del(&next_node->fl_entry);
203 drm_free(next_node, sizeof(*next_node),
204 DRM_MEM_MM);
205 } else {
206 next_node->size += cur->size;
207 next_node->start = cur->start;
208 merged = 1;
209 }
210 }
211 }
212 if (!merged) {
213 cur->free = 1;
214 list_add(&cur->fl_entry, &mm->fl_entry);
215 } else {
216 list_del(&cur->ml_entry);
217 drm_free(cur, sizeof(*cur), DRM_MEM_MM);
218 }
219}
220
221struct drm_mm_node *drm_mm_search_free(const struct drm_mm * mm,
222 unsigned long size,
223 unsigned alignment, int best_match)
224{
225 struct list_head *list;
226 const struct list_head *free_stack = &mm->fl_entry;
227 struct drm_mm_node *entry;
228 struct drm_mm_node *best;
229 unsigned long best_size;
230 unsigned wasted;
231
232 best = NULL;
233 best_size = ~0UL;
234
235 list_for_each(list, free_stack) {
236 entry = list_entry(list, struct drm_mm_node, fl_entry);
237 wasted = 0;
238
239 if (entry->size < size)
240 continue;
241
242 if (alignment) {
243 register unsigned tmp = entry->start % alignment;
244 if (tmp)
245 wasted += alignment - tmp;
246 }
247
248
249 if (entry->size >= size + wasted) {
250 if (!best_match)
251 return entry;
252 if (size < best_size) {
253 best = entry;
254 best_size = entry->size;
255 }
256 }
257 }
258
259 return best;
260}
261
262int drm_mm_clean(struct drm_mm * mm)
263{
264 struct list_head *head = &mm->ml_entry;
265
266 return (head->next->next == head);
267}
268
269int drm_mm_init(struct drm_mm * mm, unsigned long start, unsigned long size)
270{
271 INIT_LIST_HEAD(&mm->ml_entry);
272 INIT_LIST_HEAD(&mm->fl_entry);
273
274 return drm_mm_create_tail_node(mm, start, size);
275}
276
277
278void drm_mm_takedown(struct drm_mm * mm)
279{
280 struct list_head *bnode = mm->fl_entry.next;
281 struct drm_mm_node *entry;
282
283 entry = list_entry(bnode, struct drm_mm_node, fl_entry);
284
285 if (entry->ml_entry.next != &mm->ml_entry ||
286 entry->fl_entry.next != &mm->fl_entry) {
287 DRM_ERROR("Memory manager not clean. Delaying takedown\n");
288 return;
289 }
290
291 list_del(&entry->fl_entry);
292 list_del(&entry->ml_entry);
293
294 drm_free(entry, sizeof(*entry), DRM_MEM_MM);
295}
diff --git a/drivers/char/drm/drm_os_linux.h b/drivers/char/drm/drm_os_linux.h
deleted file mode 100644
index 8dbd2572b7c3..000000000000
--- a/drivers/char/drm/drm_os_linux.h
+++ /dev/null
@@ -1,108 +0,0 @@
1/**
2 * \file drm_os_linux.h
3 * OS abstraction macros.
4 */
5
6#include <linux/interrupt.h> /* For task queue support */
7#include <linux/delay.h>
8
9/** Current process ID */
10#define DRM_CURRENTPID task_pid_nr(current)
11#define DRM_SUSER(p) capable(CAP_SYS_ADMIN)
12#define DRM_UDELAY(d) udelay(d)
13/** Read a byte from a MMIO region */
14#define DRM_READ8(map, offset) readb(((void __iomem *)(map)->handle) + (offset))
15/** Read a word from a MMIO region */
16#define DRM_READ16(map, offset) readw(((void __iomem *)(map)->handle) + (offset))
17/** Read a dword from a MMIO region */
18#define DRM_READ32(map, offset) readl(((void __iomem *)(map)->handle) + (offset))
19/** Write a byte into a MMIO region */
20#define DRM_WRITE8(map, offset, val) writeb(val, ((void __iomem *)(map)->handle) + (offset))
21/** Write a word into a MMIO region */
22#define DRM_WRITE16(map, offset, val) writew(val, ((void __iomem *)(map)->handle) + (offset))
23/** Write a dword into a MMIO region */
24#define DRM_WRITE32(map, offset, val) writel(val, ((void __iomem *)(map)->handle) + (offset))
25/** Read memory barrier */
26#define DRM_READMEMORYBARRIER() rmb()
27/** Write memory barrier */
28#define DRM_WRITEMEMORYBARRIER() wmb()
29/** Read/write memory barrier */
30#define DRM_MEMORYBARRIER() mb()
31
32/** IRQ handler arguments and return type and values */
33#define DRM_IRQ_ARGS int irq, void *arg
34
35/** AGP types */
36#if __OS_HAS_AGP
37#define DRM_AGP_MEM struct agp_memory
38#define DRM_AGP_KERN struct agp_kern_info
39#else
40/* define some dummy types for non AGP supporting kernels */
41struct no_agp_kern {
42 unsigned long aper_base;
43 unsigned long aper_size;
44};
45#define DRM_AGP_MEM int
46#define DRM_AGP_KERN struct no_agp_kern
47#endif
48
49#if !(__OS_HAS_MTRR)
50static __inline__ int mtrr_add(unsigned long base, unsigned long size,
51 unsigned int type, char increment)
52{
53 return -ENODEV;
54}
55
56static __inline__ int mtrr_del(int reg, unsigned long base, unsigned long size)
57{
58 return -ENODEV;
59}
60
61#define MTRR_TYPE_WRCOMB 1
62
63#endif
64
65/** Other copying of data to kernel space */
66#define DRM_COPY_FROM_USER(arg1, arg2, arg3) \
67 copy_from_user(arg1, arg2, arg3)
68/** Other copying of data from kernel space */
69#define DRM_COPY_TO_USER(arg1, arg2, arg3) \
70 copy_to_user(arg1, arg2, arg3)
71/* Macros for copyfrom user, but checking readability only once */
72#define DRM_VERIFYAREA_READ( uaddr, size ) \
73 (access_ok( VERIFY_READ, uaddr, size ) ? 0 : -EFAULT)
74#define DRM_COPY_FROM_USER_UNCHECKED(arg1, arg2, arg3) \
75 __copy_from_user(arg1, arg2, arg3)
76#define DRM_COPY_TO_USER_UNCHECKED(arg1, arg2, arg3) \
77 __copy_to_user(arg1, arg2, arg3)
78#define DRM_GET_USER_UNCHECKED(val, uaddr) \
79 __get_user(val, uaddr)
80
81#define DRM_HZ HZ
82
83#define DRM_WAIT_ON( ret, queue, timeout, condition ) \
84do { \
85 DECLARE_WAITQUEUE(entry, current); \
86 unsigned long end = jiffies + (timeout); \
87 add_wait_queue(&(queue), &entry); \
88 \
89 for (;;) { \
90 __set_current_state(TASK_INTERRUPTIBLE); \
91 if (condition) \
92 break; \
93 if (time_after_eq(jiffies, end)) { \
94 ret = -EBUSY; \
95 break; \
96 } \
97 schedule_timeout((HZ/100 > 1) ? HZ/100 : 1); \
98 if (signal_pending(current)) { \
99 ret = -EINTR; \
100 break; \
101 } \
102 } \
103 __set_current_state(TASK_RUNNING); \
104 remove_wait_queue(&(queue), &entry); \
105} while (0)
106
107#define DRM_WAKEUP( queue ) wake_up_interruptible( queue )
108#define DRM_INIT_WAITQUEUE( queue ) init_waitqueue_head( queue )
diff --git a/drivers/char/drm/drm_pci.c b/drivers/char/drm/drm_pci.c
deleted file mode 100644
index b55d5bc6ea61..000000000000
--- a/drivers/char/drm/drm_pci.c
+++ /dev/null
@@ -1,183 +0,0 @@
1/* drm_pci.h -- PCI DMA memory management wrappers for DRM -*- linux-c -*- */
2/**
3 * \file drm_pci.c
4 * \brief Functions and ioctls to manage PCI memory
5 *
6 * \warning These interfaces aren't stable yet.
7 *
8 * \todo Implement the remaining ioctl's for the PCI pools.
9 * \todo The wrappers here are so thin that they would be better off inlined..
10 *
11 * \author José Fonseca <jrfonseca@tungstengraphics.com>
12 * \author Leif Delgass <ldelgass@retinalburn.net>
13 */
14
15/*
16 * Copyright 2003 José Fonseca.
17 * Copyright 2003 Leif Delgass.
18 * All Rights Reserved.
19 *
20 * Permission is hereby granted, free of charge, to any person obtaining a
21 * copy of this software and associated documentation files (the "Software"),
22 * to deal in the Software without restriction, including without limitation
23 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
24 * and/or sell copies of the Software, and to permit persons to whom the
25 * Software is furnished to do so, subject to the following conditions:
26 *
27 * The above copyright notice and this permission notice (including the next
28 * paragraph) shall be included in all copies or substantial portions of the
29 * Software.
30 *
31 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
32 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
33 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
34 * AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
35 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
36 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
37 */
38
39#include <linux/pci.h>
40#include <linux/dma-mapping.h>
41#include "drmP.h"
42
43/**********************************************************************/
44/** \name PCI memory */
45/*@{*/
46
47/**
48 * \brief Allocate a PCI consistent memory block, for DMA.
49 */
50drm_dma_handle_t *drm_pci_alloc(struct drm_device * dev, size_t size, size_t align,
51 dma_addr_t maxaddr)
52{
53 drm_dma_handle_t *dmah;
54#if 1
55 unsigned long addr;
56 size_t sz;
57#endif
58#ifdef DRM_DEBUG_MEMORY
59 int area = DRM_MEM_DMA;
60
61 spin_lock(&drm_mem_lock);
62 if ((drm_ram_used >> PAGE_SHIFT)
63 > (DRM_RAM_PERCENT * drm_ram_available) / 100) {
64 spin_unlock(&drm_mem_lock);
65 return 0;
66 }
67 spin_unlock(&drm_mem_lock);
68#endif
69
70 /* pci_alloc_consistent only guarantees alignment to the smallest
71 * PAGE_SIZE order which is greater than or equal to the requested size.
72 * Return NULL here for now to make sure nobody tries for larger alignment
73 */
74 if (align > size)
75 return NULL;
76
77 if (pci_set_dma_mask(dev->pdev, maxaddr) != 0) {
78 DRM_ERROR("Setting pci dma mask failed\n");
79 return NULL;
80 }
81
82 dmah = kmalloc(sizeof(drm_dma_handle_t), GFP_KERNEL);
83 if (!dmah)
84 return NULL;
85
86 dmah->size = size;
87 dmah->vaddr = dma_alloc_coherent(&dev->pdev->dev, size, &dmah->busaddr, GFP_KERNEL | __GFP_COMP);
88
89#ifdef DRM_DEBUG_MEMORY
90 if (dmah->vaddr == NULL) {
91 spin_lock(&drm_mem_lock);
92 ++drm_mem_stats[area].fail_count;
93 spin_unlock(&drm_mem_lock);
94 kfree(dmah);
95 return NULL;
96 }
97
98 spin_lock(&drm_mem_lock);
99 ++drm_mem_stats[area].succeed_count;
100 drm_mem_stats[area].bytes_allocated += size;
101 drm_ram_used += size;
102 spin_unlock(&drm_mem_lock);
103#else
104 if (dmah->vaddr == NULL) {
105 kfree(dmah);
106 return NULL;
107 }
108#endif
109
110 memset(dmah->vaddr, 0, size);
111
112 /* XXX - Is virt_to_page() legal for consistent mem? */
113 /* Reserve */
114 for (addr = (unsigned long)dmah->vaddr, sz = size;
115 sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) {
116 SetPageReserved(virt_to_page(addr));
117 }
118
119 return dmah;
120}
121
122EXPORT_SYMBOL(drm_pci_alloc);
123
124/**
125 * \brief Free a PCI consistent memory block without freeing its descriptor.
126 *
127 * This function is for internal use in the Linux-specific DRM core code.
128 */
129void __drm_pci_free(struct drm_device * dev, drm_dma_handle_t * dmah)
130{
131#if 1
132 unsigned long addr;
133 size_t sz;
134#endif
135#ifdef DRM_DEBUG_MEMORY
136 int area = DRM_MEM_DMA;
137 int alloc_count;
138 int free_count;
139#endif
140
141 if (!dmah->vaddr) {
142#ifdef DRM_DEBUG_MEMORY
143 DRM_MEM_ERROR(area, "Attempt to free address 0\n");
144#endif
145 } else {
146 /* XXX - Is virt_to_page() legal for consistent mem? */
147 /* Unreserve */
148 for (addr = (unsigned long)dmah->vaddr, sz = dmah->size;
149 sz > 0; addr += PAGE_SIZE, sz -= PAGE_SIZE) {
150 ClearPageReserved(virt_to_page(addr));
151 }
152 dma_free_coherent(&dev->pdev->dev, dmah->size, dmah->vaddr,
153 dmah->busaddr);
154 }
155
156#ifdef DRM_DEBUG_MEMORY
157 spin_lock(&drm_mem_lock);
158 free_count = ++drm_mem_stats[area].free_count;
159 alloc_count = drm_mem_stats[area].succeed_count;
160 drm_mem_stats[area].bytes_freed += size;
161 drm_ram_used -= size;
162 spin_unlock(&drm_mem_lock);
163 if (free_count > alloc_count) {
164 DRM_MEM_ERROR(area,
165 "Excess frees: %d frees, %d allocs\n",
166 free_count, alloc_count);
167 }
168#endif
169
170}
171
172/**
173 * \brief Free a PCI consistent memory block
174 */
175void drm_pci_free(struct drm_device * dev, drm_dma_handle_t * dmah)
176{
177 __drm_pci_free(dev, dmah);
178 kfree(dmah);
179}
180
181EXPORT_SYMBOL(drm_pci_free);
182
183/*@}*/
diff --git a/drivers/char/drm/drm_pciids.h b/drivers/char/drm/drm_pciids.h
deleted file mode 100644
index a6a499f97e22..000000000000
--- a/drivers/char/drm/drm_pciids.h
+++ /dev/null
@@ -1,414 +0,0 @@
1/*
2 This file is auto-generated from the drm_pciids.txt in the DRM CVS
3 Please contact dri-devel@lists.sf.net to add new cards to this list
4*/
5#define radeon_PCI_IDS \
6 {0x1002, 0x3150, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \
7 {0x1002, 0x3152, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
8 {0x1002, 0x3154, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
9 {0x1002, 0x3E50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \
10 {0x1002, 0x3E54, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \
11 {0x1002, 0x4136, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS100|RADEON_IS_IGP}, \
12 {0x1002, 0x4137, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|RADEON_IS_IGP}, \
13 {0x1002, 0x4144, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \
14 {0x1002, 0x4145, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \
15 {0x1002, 0x4146, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \
16 {0x1002, 0x4147, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \
17 {0x1002, 0x4148, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \
18 {0x1002, 0x4149, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \
19 {0x1002, 0x414A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \
20 {0x1002, 0x414B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \
21 {0x1002, 0x4150, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \
22 {0x1002, 0x4151, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \
23 {0x1002, 0x4152, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \
24 {0x1002, 0x4153, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \
25 {0x1002, 0x4154, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \
26 {0x1002, 0x4155, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \
27 {0x1002, 0x4156, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350}, \
28 {0x1002, 0x4237, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|RADEON_IS_IGP}, \
29 {0x1002, 0x4242, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
30 {0x1002, 0x4243, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
31 {0x1002, 0x4336, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS100|RADEON_IS_IGP|RADEON_IS_MOBILITY}, \
32 {0x1002, 0x4337, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|RADEON_IS_IGP|RADEON_IS_MOBILITY}, \
33 {0x1002, 0x4437, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS200|RADEON_IS_IGP|RADEON_IS_MOBILITY}, \
34 {0x1002, 0x4966, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250}, \
35 {0x1002, 0x4967, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250}, \
36 {0x1002, 0x4A48, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
37 {0x1002, 0x4A49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
38 {0x1002, 0x4A4A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
39 {0x1002, 0x4A4B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
40 {0x1002, 0x4A4C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
41 {0x1002, 0x4A4D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
42 {0x1002, 0x4A4E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
43 {0x1002, 0x4A4F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
44 {0x1002, 0x4A50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
45 {0x1002, 0x4A54, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
46 {0x1002, 0x4B49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
47 {0x1002, 0x4B4A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
48 {0x1002, 0x4B4B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
49 {0x1002, 0x4B4C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
50 {0x1002, 0x4C57, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200|RADEON_IS_MOBILITY}, \
51 {0x1002, 0x4C58, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200|RADEON_IS_MOBILITY}, \
52 {0x1002, 0x4C59, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100|RADEON_IS_MOBILITY}, \
53 {0x1002, 0x4C5A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100|RADEON_IS_MOBILITY}, \
54 {0x1002, 0x4C64, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250|RADEON_IS_MOBILITY}, \
55 {0x1002, 0x4C66, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250|RADEON_IS_MOBILITY}, \
56 {0x1002, 0x4C67, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV250|RADEON_IS_MOBILITY}, \
57 {0x1002, 0x4E44, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \
58 {0x1002, 0x4E45, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \
59 {0x1002, 0x4E46, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \
60 {0x1002, 0x4E47, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R300}, \
61 {0x1002, 0x4E48, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \
62 {0x1002, 0x4E49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \
63 {0x1002, 0x4E4A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \
64 {0x1002, 0x4E4B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R350}, \
65 {0x1002, 0x4E50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|RADEON_IS_MOBILITY}, \
66 {0x1002, 0x4E51, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|RADEON_IS_MOBILITY}, \
67 {0x1002, 0x4E52, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|RADEON_IS_MOBILITY}, \
68 {0x1002, 0x4E53, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|RADEON_IS_MOBILITY}, \
69 {0x1002, 0x4E54, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|RADEON_IS_MOBILITY}, \
70 {0x1002, 0x4E56, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV350|RADEON_IS_MOBILITY}, \
71 {0x1002, 0x5144, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|RADEON_SINGLE_CRTC}, \
72 {0x1002, 0x5145, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|RADEON_SINGLE_CRTC}, \
73 {0x1002, 0x5146, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|RADEON_SINGLE_CRTC}, \
74 {0x1002, 0x5147, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R100|RADEON_SINGLE_CRTC}, \
75 {0x1002, 0x5148, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
76 {0x1002, 0x514C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
77 {0x1002, 0x514D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R200}, \
78 {0x1002, 0x5157, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200}, \
79 {0x1002, 0x5158, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV200}, \
80 {0x1002, 0x5159, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \
81 {0x1002, 0x515A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \
82 {0x1002, 0x515E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \
83 {0x1002, 0x5460, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \
84 {0x1002, 0x5462, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \
85 {0x1002, 0x5464, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_IS_MOBILITY}, \
86 {0x1002, 0x5657, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \
87 {0x1002, 0x5548, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
88 {0x1002, 0x5549, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
89 {0x1002, 0x554A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
90 {0x1002, 0x554B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
91 {0x1002, 0x554C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
92 {0x1002, 0x554D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
93 {0x1002, 0x554E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
94 {0x1002, 0x554F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
95 {0x1002, 0x5550, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
96 {0x1002, 0x5551, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
97 {0x1002, 0x5552, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
98 {0x1002, 0x5554, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
99 {0x1002, 0x564A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
100 {0x1002, 0x564B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
101 {0x1002, 0x564F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
102 {0x1002, 0x5652, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
103 {0x1002, 0x5653, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
104 {0x1002, 0x5834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP}, \
105 {0x1002, 0x5835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_IS_MOBILITY}, \
106 {0x1002, 0x5954, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
107 {0x1002, 0x5955, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
108 {0x1002, 0x5974, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
109 {0x1002, 0x5975, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
110 {0x1002, 0x5960, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
111 {0x1002, 0x5961, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
112 {0x1002, 0x5962, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
113 {0x1002, 0x5964, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
114 {0x1002, 0x5965, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280}, \
115 {0x1002, 0x5969, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV100}, \
116 {0x1002, 0x5a41, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
117 {0x1002, 0x5a42, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
118 {0x1002, 0x5a61, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
119 {0x1002, 0x5a62, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS400|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_IS_IGPGART}, \
120 {0x1002, 0x5b60, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \
121 {0x1002, 0x5b62, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \
122 {0x1002, 0x5b63, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \
123 {0x1002, 0x5b64, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \
124 {0x1002, 0x5b65, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV380|RADEON_NEW_MEMMAP}, \
125 {0x1002, 0x5c61, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|RADEON_IS_MOBILITY}, \
126 {0x1002, 0x5c63, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV280|RADEON_IS_MOBILITY}, \
127 {0x1002, 0x5d48, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
128 {0x1002, 0x5d49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
129 {0x1002, 0x5d4a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
130 {0x1002, 0x5d4c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
131 {0x1002, 0x5d4d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
132 {0x1002, 0x5d4e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
133 {0x1002, 0x5d4f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
134 {0x1002, 0x5d50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
135 {0x1002, 0x5d52, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
136 {0x1002, 0x5d57, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R420|RADEON_NEW_MEMMAP}, \
137 {0x1002, 0x5e48, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_NEW_MEMMAP}, \
138 {0x1002, 0x5e4a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_NEW_MEMMAP}, \
139 {0x1002, 0x5e4b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_NEW_MEMMAP}, \
140 {0x1002, 0x5e4c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_NEW_MEMMAP}, \
141 {0x1002, 0x5e4d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_NEW_MEMMAP}, \
142 {0x1002, 0x5e4f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV410|RADEON_NEW_MEMMAP}, \
143 {0x1002, 0x7100, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R520|RADEON_NEW_MEMMAP}, \
144 {0x1002, 0x7101, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R520|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
145 {0x1002, 0x7102, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R520|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
146 {0x1002, 0x7103, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R520|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
147 {0x1002, 0x7104, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R520|RADEON_NEW_MEMMAP}, \
148 {0x1002, 0x7105, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R520|RADEON_NEW_MEMMAP}, \
149 {0x1002, 0x7106, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R520|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
150 {0x1002, 0x7108, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R520|RADEON_NEW_MEMMAP}, \
151 {0x1002, 0x7109, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R520|RADEON_NEW_MEMMAP}, \
152 {0x1002, 0x710A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R520|RADEON_NEW_MEMMAP}, \
153 {0x1002, 0x710B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R520|RADEON_NEW_MEMMAP}, \
154 {0x1002, 0x710C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R520|RADEON_NEW_MEMMAP}, \
155 {0x1002, 0x710E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R520|RADEON_NEW_MEMMAP}, \
156 {0x1002, 0x710F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R520|RADEON_NEW_MEMMAP}, \
157 {0x1002, 0x7140, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_NEW_MEMMAP}, \
158 {0x1002, 0x7141, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_NEW_MEMMAP}, \
159 {0x1002, 0x7142, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_NEW_MEMMAP}, \
160 {0x1002, 0x7143, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_NEW_MEMMAP}, \
161 {0x1002, 0x7144, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
162 {0x1002, 0x7145, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
163 {0x1002, 0x7146, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_NEW_MEMMAP}, \
164 {0x1002, 0x7147, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_NEW_MEMMAP}, \
165 {0x1002, 0x7149, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
166 {0x1002, 0x714A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
167 {0x1002, 0x714B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
168 {0x1002, 0x714C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
169 {0x1002, 0x714D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_NEW_MEMMAP}, \
170 {0x1002, 0x714E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_NEW_MEMMAP}, \
171 {0x1002, 0x714F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_NEW_MEMMAP}, \
172 {0x1002, 0x7151, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_NEW_MEMMAP}, \
173 {0x1002, 0x7152, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_NEW_MEMMAP}, \
174 {0x1002, 0x7153, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_NEW_MEMMAP}, \
175 {0x1002, 0x715E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_NEW_MEMMAP}, \
176 {0x1002, 0x715F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_NEW_MEMMAP}, \
177 {0x1002, 0x7180, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_NEW_MEMMAP}, \
178 {0x1002, 0x7181, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_NEW_MEMMAP}, \
179 {0x1002, 0x7183, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_NEW_MEMMAP}, \
180 {0x1002, 0x7186, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
181 {0x1002, 0x7187, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_NEW_MEMMAP}, \
182 {0x1002, 0x7188, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
183 {0x1002, 0x718A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
184 {0x1002, 0x718B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
185 {0x1002, 0x718C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
186 {0x1002, 0x718D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
187 {0x1002, 0x718F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_NEW_MEMMAP}, \
188 {0x1002, 0x7193, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_NEW_MEMMAP}, \
189 {0x1002, 0x7196, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
190 {0x1002, 0x719B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_NEW_MEMMAP}, \
191 {0x1002, 0x719F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_NEW_MEMMAP}, \
192 {0x1002, 0x71C0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV530|RADEON_NEW_MEMMAP}, \
193 {0x1002, 0x71C1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV530|RADEON_NEW_MEMMAP}, \
194 {0x1002, 0x71C2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV530|RADEON_NEW_MEMMAP}, \
195 {0x1002, 0x71C3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV530|RADEON_NEW_MEMMAP}, \
196 {0x1002, 0x71C4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV530|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
197 {0x1002, 0x71C5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV530|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
198 {0x1002, 0x71C6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV530|RADEON_NEW_MEMMAP}, \
199 {0x1002, 0x71C7, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV530|RADEON_NEW_MEMMAP}, \
200 {0x1002, 0x71CD, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV530|RADEON_NEW_MEMMAP}, \
201 {0x1002, 0x71CE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV530|RADEON_NEW_MEMMAP}, \
202 {0x1002, 0x71D2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV530|RADEON_NEW_MEMMAP}, \
203 {0x1002, 0x71D4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV530|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
204 {0x1002, 0x71D5, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV530|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
205 {0x1002, 0x71D6, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV530|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
206 {0x1002, 0x71DA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV530|RADEON_NEW_MEMMAP}, \
207 {0x1002, 0x71DE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV530|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
208 {0x1002, 0x7200, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_NEW_MEMMAP}, \
209 {0x1002, 0x7210, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
210 {0x1002, 0x7211, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV515|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
211 {0x1002, 0x7240, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R580|RADEON_NEW_MEMMAP}, \
212 {0x1002, 0x7243, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R580|RADEON_NEW_MEMMAP}, \
213 {0x1002, 0x7244, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R580|RADEON_NEW_MEMMAP}, \
214 {0x1002, 0x7245, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R580|RADEON_NEW_MEMMAP}, \
215 {0x1002, 0x7246, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R580|RADEON_NEW_MEMMAP}, \
216 {0x1002, 0x7247, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R580|RADEON_NEW_MEMMAP}, \
217 {0x1002, 0x7248, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R580|RADEON_NEW_MEMMAP}, \
218 {0x1002, 0x7249, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R580|RADEON_NEW_MEMMAP}, \
219 {0x1002, 0x724A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R580|RADEON_NEW_MEMMAP}, \
220 {0x1002, 0x724B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R580|RADEON_NEW_MEMMAP}, \
221 {0x1002, 0x724C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R580|RADEON_NEW_MEMMAP}, \
222 {0x1002, 0x724D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R580|RADEON_NEW_MEMMAP}, \
223 {0x1002, 0x724E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R580|RADEON_NEW_MEMMAP}, \
224 {0x1002, 0x724F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R580|RADEON_NEW_MEMMAP}, \
225 {0x1002, 0x7280, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV570|RADEON_NEW_MEMMAP}, \
226 {0x1002, 0x7281, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV560|RADEON_NEW_MEMMAP}, \
227 {0x1002, 0x7283, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV560|RADEON_NEW_MEMMAP}, \
228 {0x1002, 0x7284, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_R580|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
229 {0x1002, 0x7287, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV560|RADEON_NEW_MEMMAP}, \
230 {0x1002, 0x7288, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV570|RADEON_NEW_MEMMAP}, \
231 {0x1002, 0x7289, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV570|RADEON_NEW_MEMMAP}, \
232 {0x1002, 0x728B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV570|RADEON_NEW_MEMMAP}, \
233 {0x1002, 0x728C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV570|RADEON_NEW_MEMMAP}, \
234 {0x1002, 0x7290, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV560|RADEON_NEW_MEMMAP}, \
235 {0x1002, 0x7291, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV560|RADEON_NEW_MEMMAP}, \
236 {0x1002, 0x7293, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV560|RADEON_NEW_MEMMAP}, \
237 {0x1002, 0x7297, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RV560|RADEON_NEW_MEMMAP}, \
238 {0x1002, 0x7834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_NEW_MEMMAP}, \
239 {0x1002, 0x7835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS300|RADEON_IS_IGP|RADEON_IS_MOBILITY|RADEON_NEW_MEMMAP}, \
240 {0x1002, 0x791e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS690|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART}, \
241 {0x1002, 0x791f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_RS690|RADEON_IS_IGP|RADEON_NEW_MEMMAP|RADEON_IS_IGPGART}, \
242 {0, 0, 0}
243
244#define r128_PCI_IDS \
245 {0x1002, 0x4c45, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
246 {0x1002, 0x4c46, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
247 {0x1002, 0x4d46, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
248 {0x1002, 0x4d4c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
249 {0x1002, 0x5041, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
250 {0x1002, 0x5042, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
251 {0x1002, 0x5043, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
252 {0x1002, 0x5044, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
253 {0x1002, 0x5045, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
254 {0x1002, 0x5046, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
255 {0x1002, 0x5047, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
256 {0x1002, 0x5048, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
257 {0x1002, 0x5049, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
258 {0x1002, 0x504A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
259 {0x1002, 0x504B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
260 {0x1002, 0x504C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
261 {0x1002, 0x504D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
262 {0x1002, 0x504E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
263 {0x1002, 0x504F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
264 {0x1002, 0x5050, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
265 {0x1002, 0x5051, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
266 {0x1002, 0x5052, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
267 {0x1002, 0x5053, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
268 {0x1002, 0x5054, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
269 {0x1002, 0x5055, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
270 {0x1002, 0x5056, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
271 {0x1002, 0x5057, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
272 {0x1002, 0x5058, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
273 {0x1002, 0x5245, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
274 {0x1002, 0x5246, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
275 {0x1002, 0x5247, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
276 {0x1002, 0x524b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
277 {0x1002, 0x524c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
278 {0x1002, 0x534d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
279 {0x1002, 0x5446, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
280 {0x1002, 0x544C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
281 {0x1002, 0x5452, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
282 {0, 0, 0}
283
284#define mga_PCI_IDS \
285 {0x102b, 0x0520, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MGA_CARD_TYPE_G200}, \
286 {0x102b, 0x0521, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MGA_CARD_TYPE_G200}, \
287 {0x102b, 0x0525, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MGA_CARD_TYPE_G400}, \
288 {0x102b, 0x2527, PCI_ANY_ID, PCI_ANY_ID, 0, 0, MGA_CARD_TYPE_G550}, \
289 {0, 0, 0}
290
291#define mach64_PCI_IDS \
292 {0x1002, 0x4749, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
293 {0x1002, 0x4750, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
294 {0x1002, 0x4751, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
295 {0x1002, 0x4742, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
296 {0x1002, 0x4744, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
297 {0x1002, 0x4c49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
298 {0x1002, 0x4c50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
299 {0x1002, 0x4c51, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
300 {0x1002, 0x4c42, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
301 {0x1002, 0x4c44, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
302 {0x1002, 0x474c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
303 {0x1002, 0x474f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
304 {0x1002, 0x4752, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
305 {0x1002, 0x4753, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
306 {0x1002, 0x474d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
307 {0x1002, 0x474e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
308 {0x1002, 0x4c52, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
309 {0x1002, 0x4c53, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
310 {0x1002, 0x4c4d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
311 {0x1002, 0x4c4e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
312 {0, 0, 0}
313
314#define sisdrv_PCI_IDS \
315 {0x1039, 0x0300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
316 {0x1039, 0x5300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
317 {0x1039, 0x6300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
318 {0x1039, 0x6330, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_CHIP_315}, \
319 {0x1039, 0x6351, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
320 {0x1039, 0x7300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
321 {0x18CA, 0x0040, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_CHIP_315}, \
322 {0x18CA, 0x0042, PCI_ANY_ID, PCI_ANY_ID, 0, 0, SIS_CHIP_315}, \
323 {0, 0, 0}
324
325#define tdfx_PCI_IDS \
326 {0x121a, 0x0003, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
327 {0x121a, 0x0004, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
328 {0x121a, 0x0005, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
329 {0x121a, 0x0007, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
330 {0x121a, 0x0009, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
331 {0x121a, 0x000b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
332 {0, 0, 0}
333
334#define viadrv_PCI_IDS \
335 {0x1106, 0x3022, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
336 {0x1106, 0x3118, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VIA_PRO_GROUP_A}, \
337 {0x1106, 0x3122, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
338 {0x1106, 0x7205, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
339 {0x1106, 0x3108, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
340 {0x1106, 0x3344, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
341 {0x1106, 0x3343, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
342 {0x1106, 0x3230, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VIA_DX9_0}, \
343 {0x1106, 0x3157, PCI_ANY_ID, PCI_ANY_ID, 0, 0, VIA_PRO_GROUP_A}, \
344 {0, 0, 0}
345
346#define i810_PCI_IDS \
347 {0x8086, 0x7121, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
348 {0x8086, 0x7123, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
349 {0x8086, 0x7125, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
350 {0x8086, 0x1132, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
351 {0, 0, 0}
352
353#define i830_PCI_IDS \
354 {0x8086, 0x3577, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
355 {0x8086, 0x2562, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
356 {0x8086, 0x3582, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
357 {0x8086, 0x2572, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
358 {0, 0, 0}
359
360#define gamma_PCI_IDS \
361 {0x3d3d, 0x0008, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
362 {0, 0, 0}
363
364#define savage_PCI_IDS \
365 {0x5333, 0x8a20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SAVAGE3D}, \
366 {0x5333, 0x8a21, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SAVAGE3D}, \
367 {0x5333, 0x8a22, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SAVAGE4}, \
368 {0x5333, 0x8a23, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SAVAGE4}, \
369 {0x5333, 0x8c10, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SAVAGE_MX}, \
370 {0x5333, 0x8c11, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SAVAGE_MX}, \
371 {0x5333, 0x8c12, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SAVAGE_MX}, \
372 {0x5333, 0x8c13, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SAVAGE_MX}, \
373 {0x5333, 0x8c22, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SUPERSAVAGE}, \
374 {0x5333, 0x8c24, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SUPERSAVAGE}, \
375 {0x5333, 0x8c26, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SUPERSAVAGE}, \
376 {0x5333, 0x8c2a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SUPERSAVAGE}, \
377 {0x5333, 0x8c2b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SUPERSAVAGE}, \
378 {0x5333, 0x8c2c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SUPERSAVAGE}, \
379 {0x5333, 0x8c2d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SUPERSAVAGE}, \
380 {0x5333, 0x8c2e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SUPERSAVAGE}, \
381 {0x5333, 0x8c2f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_SUPERSAVAGE}, \
382 {0x5333, 0x8a25, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_PROSAVAGE}, \
383 {0x5333, 0x8a26, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_PROSAVAGE}, \
384 {0x5333, 0x8d01, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_TWISTER}, \
385 {0x5333, 0x8d02, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_TWISTER}, \
386 {0x5333, 0x8d03, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_PROSAVAGEDDR}, \
387 {0x5333, 0x8d04, PCI_ANY_ID, PCI_ANY_ID, 0, 0, S3_PROSAVAGEDDR}, \
388 {0, 0, 0}
389
390#define ffb_PCI_IDS \
391 {0, 0, 0}
392
393#define i915_PCI_IDS \
394 {0x8086, 0x3577, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
395 {0x8086, 0x2562, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
396 {0x8086, 0x3582, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
397 {0x8086, 0x2572, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
398 {0x8086, 0x2582, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
399 {0x8086, 0x258a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
400 {0x8086, 0x2592, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
401 {0x8086, 0x2772, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
402 {0x8086, 0x27a2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
403 {0x8086, 0x27ae, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
404 {0x8086, 0x2972, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
405 {0x8086, 0x2982, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
406 {0x8086, 0x2992, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
407 {0x8086, 0x29a2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
408 {0x8086, 0x29b2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
409 {0x8086, 0x29c2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
410 {0x8086, 0x29d2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
411 {0x8086, 0x2a02, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
412 {0x8086, 0x2a12, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
413 {0x8086, 0x2a42, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
414 {0, 0, 0}
diff --git a/drivers/char/drm/drm_proc.c b/drivers/char/drm/drm_proc.c
deleted file mode 100644
index 93b1e0475c93..000000000000
--- a/drivers/char/drm/drm_proc.c
+++ /dev/null
@@ -1,557 +0,0 @@
1/**
2 * \file drm_proc.c
3 * /proc support for DRM
4 *
5 * \author Rickard E. (Rik) Faith <faith@valinux.com>
6 * \author Gareth Hughes <gareth@valinux.com>
7 *
8 * \par Acknowledgements:
9 * Matthew J Sottek <matthew.j.sottek@intel.com> sent in a patch to fix
10 * the problem with the proc files not outputting all their information.
11 */
12
13/*
14 * Created: Mon Jan 11 09:48:47 1999 by faith@valinux.com
15 *
16 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
17 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
18 * All Rights Reserved.
19 *
20 * Permission is hereby granted, free of charge, to any person obtaining a
21 * copy of this software and associated documentation files (the "Software"),
22 * to deal in the Software without restriction, including without limitation
23 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
24 * and/or sell copies of the Software, and to permit persons to whom the
25 * Software is furnished to do so, subject to the following conditions:
26 *
27 * The above copyright notice and this permission notice (including the next
28 * paragraph) shall be included in all copies or substantial portions of the
29 * Software.
30 *
31 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
32 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
33 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
34 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
35 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
36 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
37 * OTHER DEALINGS IN THE SOFTWARE.
38 */
39
40#include "drmP.h"
41
42static int drm_name_info(char *buf, char **start, off_t offset,
43 int request, int *eof, void *data);
44static int drm_vm_info(char *buf, char **start, off_t offset,
45 int request, int *eof, void *data);
46static int drm_clients_info(char *buf, char **start, off_t offset,
47 int request, int *eof, void *data);
48static int drm_queues_info(char *buf, char **start, off_t offset,
49 int request, int *eof, void *data);
50static int drm_bufs_info(char *buf, char **start, off_t offset,
51 int request, int *eof, void *data);
52#if DRM_DEBUG_CODE
53static int drm_vma_info(char *buf, char **start, off_t offset,
54 int request, int *eof, void *data);
55#endif
56
57/**
58 * Proc file list.
59 */
60static struct drm_proc_list {
61 const char *name; /**< file name */
62 int (*f) (char *, char **, off_t, int, int *, void *); /**< proc callback*/
63} drm_proc_list[] = {
64 {"name", drm_name_info},
65 {"mem", drm_mem_info},
66 {"vm", drm_vm_info},
67 {"clients", drm_clients_info},
68 {"queues", drm_queues_info},
69 {"bufs", drm_bufs_info},
70#if DRM_DEBUG_CODE
71 {"vma", drm_vma_info},
72#endif
73};
74
75#define DRM_PROC_ENTRIES ARRAY_SIZE(drm_proc_list)
76
77/**
78 * Initialize the DRI proc filesystem for a device.
79 *
80 * \param dev DRM device.
81 * \param minor device minor number.
82 * \param root DRI proc dir entry.
83 * \param dev_root resulting DRI device proc dir entry.
84 * \return root entry pointer on success, or NULL on failure.
85 *
86 * Create the DRI proc root entry "/proc/dri", the device proc root entry
87 * "/proc/dri/%minor%/", and each entry in proc_list as
88 * "/proc/dri/%minor%/%name%".
89 */
90int drm_proc_init(struct drm_minor *minor, int minor_id,
91 struct proc_dir_entry *root)
92{
93 struct proc_dir_entry *ent;
94 int i, j;
95 char name[64];
96
97 sprintf(name, "%d", minor_id);
98 minor->dev_root = proc_mkdir(name, root);
99 if (!minor->dev_root) {
100 DRM_ERROR("Cannot create /proc/dri/%s\n", name);
101 return -1;
102 }
103
104 for (i = 0; i < DRM_PROC_ENTRIES; i++) {
105 ent = create_proc_entry(drm_proc_list[i].name,
106 S_IFREG | S_IRUGO, minor->dev_root);
107 if (!ent) {
108 DRM_ERROR("Cannot create /proc/dri/%s/%s\n",
109 name, drm_proc_list[i].name);
110 for (j = 0; j < i; j++)
111 remove_proc_entry(drm_proc_list[i].name,
112 minor->dev_root);
113 remove_proc_entry(name, root);
114 minor->dev_root = NULL;
115 return -1;
116 }
117 ent->read_proc = drm_proc_list[i].f;
118 ent->data = minor;
119 }
120
121 return 0;
122}
123
124/**
125 * Cleanup the proc filesystem resources.
126 *
127 * \param minor device minor number.
128 * \param root DRI proc dir entry.
129 * \param dev_root DRI device proc dir entry.
130 * \return always zero.
131 *
132 * Remove all proc entries created by proc_init().
133 */
134int drm_proc_cleanup(struct drm_minor *minor, struct proc_dir_entry *root)
135{
136 int i;
137 char name[64];
138
139 if (!root || !minor->dev_root)
140 return 0;
141
142 for (i = 0; i < DRM_PROC_ENTRIES; i++)
143 remove_proc_entry(drm_proc_list[i].name, minor->dev_root);
144 sprintf(name, "%d", minor->index);
145 remove_proc_entry(name, root);
146
147 return 0;
148}
149
150/**
151 * Called when "/proc/dri/.../name" is read.
152 *
153 * \param buf output buffer.
154 * \param start start of output data.
155 * \param offset requested start offset.
156 * \param request requested number of bytes.
157 * \param eof whether there is no more data to return.
158 * \param data private data.
159 * \return number of written bytes.
160 *
161 * Prints the device name together with the bus id if available.
162 */
163static int drm_name_info(char *buf, char **start, off_t offset, int request,
164 int *eof, void *data)
165{
166 struct drm_minor *minor = (struct drm_minor *) data;
167 struct drm_device *dev = minor->dev;
168 int len = 0;
169
170 if (offset > DRM_PROC_LIMIT) {
171 *eof = 1;
172 return 0;
173 }
174
175 *start = &buf[offset];
176 *eof = 0;
177
178 if (dev->unique) {
179 DRM_PROC_PRINT("%s %s %s\n",
180 dev->driver->pci_driver.name,
181 pci_name(dev->pdev), dev->unique);
182 } else {
183 DRM_PROC_PRINT("%s %s\n", dev->driver->pci_driver.name,
184 pci_name(dev->pdev));
185 }
186
187 if (len > request + offset)
188 return request;
189 *eof = 1;
190 return len - offset;
191}
192
193/**
194 * Called when "/proc/dri/.../vm" is read.
195 *
196 * \param buf output buffer.
197 * \param start start of output data.
198 * \param offset requested start offset.
199 * \param request requested number of bytes.
200 * \param eof whether there is no more data to return.
201 * \param data private data.
202 * \return number of written bytes.
203 *
204 * Prints information about all mappings in drm_device::maplist.
205 */
206static int drm__vm_info(char *buf, char **start, off_t offset, int request,
207 int *eof, void *data)
208{
209 struct drm_minor *minor = (struct drm_minor *) data;
210 struct drm_device *dev = minor->dev;
211 int len = 0;
212 struct drm_map *map;
213 struct drm_map_list *r_list;
214
215 /* Hardcoded from _DRM_FRAME_BUFFER,
216 _DRM_REGISTERS, _DRM_SHM, _DRM_AGP, and
217 _DRM_SCATTER_GATHER and _DRM_CONSISTENT */
218 const char *types[] = { "FB", "REG", "SHM", "AGP", "SG", "PCI" };
219 const char *type;
220 int i;
221
222 if (offset > DRM_PROC_LIMIT) {
223 *eof = 1;
224 return 0;
225 }
226
227 *start = &buf[offset];
228 *eof = 0;
229
230 DRM_PROC_PRINT("slot offset size type flags "
231 "address mtrr\n\n");
232 i = 0;
233 list_for_each_entry(r_list, &dev->maplist, head) {
234 map = r_list->map;
235 if (!map)
236 continue;
237 if (map->type < 0 || map->type > 5)
238 type = "??";
239 else
240 type = types[map->type];
241 DRM_PROC_PRINT("%4d 0x%08lx 0x%08lx %4.4s 0x%02x 0x%08lx ",
242 i,
243 map->offset,
244 map->size, type, map->flags,
245 (unsigned long) r_list->user_token);
246 if (map->mtrr < 0) {
247 DRM_PROC_PRINT("none\n");
248 } else {
249 DRM_PROC_PRINT("%4d\n", map->mtrr);
250 }
251 i++;
252 }
253
254 if (len > request + offset)
255 return request;
256 *eof = 1;
257 return len - offset;
258}
259
260/**
261 * Simply calls _vm_info() while holding the drm_device::struct_mutex lock.
262 */
263static int drm_vm_info(char *buf, char **start, off_t offset, int request,
264 int *eof, void *data)
265{
266 struct drm_minor *minor = (struct drm_minor *) data;
267 struct drm_device *dev = minor->dev;
268 int ret;
269
270 mutex_lock(&dev->struct_mutex);
271 ret = drm__vm_info(buf, start, offset, request, eof, data);
272 mutex_unlock(&dev->struct_mutex);
273 return ret;
274}
275
276/**
277 * Called when "/proc/dri/.../queues" is read.
278 *
279 * \param buf output buffer.
280 * \param start start of output data.
281 * \param offset requested start offset.
282 * \param request requested number of bytes.
283 * \param eof whether there is no more data to return.
284 * \param data private data.
285 * \return number of written bytes.
286 */
287static int drm__queues_info(char *buf, char **start, off_t offset,
288 int request, int *eof, void *data)
289{
290 struct drm_minor *minor = (struct drm_minor *) data;
291 struct drm_device *dev = minor->dev;
292 int len = 0;
293 int i;
294 struct drm_queue *q;
295
296 if (offset > DRM_PROC_LIMIT) {
297 *eof = 1;
298 return 0;
299 }
300
301 *start = &buf[offset];
302 *eof = 0;
303
304 DRM_PROC_PRINT(" ctx/flags use fin"
305 " blk/rw/rwf wait flushed queued"
306 " locks\n\n");
307 for (i = 0; i < dev->queue_count; i++) {
308 q = dev->queuelist[i];
309 atomic_inc(&q->use_count);
310 DRM_PROC_PRINT_RET(atomic_dec(&q->use_count),
311 "%5d/0x%03x %5d %5d"
312 " %5d/%c%c/%c%c%c %5Zd\n",
313 i,
314 q->flags,
315 atomic_read(&q->use_count),
316 atomic_read(&q->finalization),
317 atomic_read(&q->block_count),
318 atomic_read(&q->block_read) ? 'r' : '-',
319 atomic_read(&q->block_write) ? 'w' : '-',
320 waitqueue_active(&q->read_queue) ? 'r' : '-',
321 waitqueue_active(&q->
322 write_queue) ? 'w' : '-',
323 waitqueue_active(&q->
324 flush_queue) ? 'f' : '-',
325 DRM_BUFCOUNT(&q->waitlist));
326 atomic_dec(&q->use_count);
327 }
328
329 if (len > request + offset)
330 return request;
331 *eof = 1;
332 return len - offset;
333}
334
335/**
336 * Simply calls _queues_info() while holding the drm_device::struct_mutex lock.
337 */
338static int drm_queues_info(char *buf, char **start, off_t offset, int request,
339 int *eof, void *data)
340{
341 struct drm_minor *minor = (struct drm_minor *) data;
342 struct drm_device *dev = minor->dev;
343 int ret;
344
345 mutex_lock(&dev->struct_mutex);
346 ret = drm__queues_info(buf, start, offset, request, eof, data);
347 mutex_unlock(&dev->struct_mutex);
348 return ret;
349}
350
351/**
352 * Called when "/proc/dri/.../bufs" is read.
353 *
354 * \param buf output buffer.
355 * \param start start of output data.
356 * \param offset requested start offset.
357 * \param request requested number of bytes.
358 * \param eof whether there is no more data to return.
359 * \param data private data.
360 * \return number of written bytes.
361 */
362static int drm__bufs_info(char *buf, char **start, off_t offset, int request,
363 int *eof, void *data)
364{
365 struct drm_minor *minor = (struct drm_minor *) data;
366 struct drm_device *dev = minor->dev;
367 int len = 0;
368 struct drm_device_dma *dma = dev->dma;
369 int i;
370
371 if (!dma || offset > DRM_PROC_LIMIT) {
372 *eof = 1;
373 return 0;
374 }
375
376 *start = &buf[offset];
377 *eof = 0;
378
379 DRM_PROC_PRINT(" o size count free segs pages kB\n\n");
380 for (i = 0; i <= DRM_MAX_ORDER; i++) {
381 if (dma->bufs[i].buf_count)
382 DRM_PROC_PRINT("%2d %8d %5d %5d %5d %5d %5ld\n",
383 i,
384 dma->bufs[i].buf_size,
385 dma->bufs[i].buf_count,
386 atomic_read(&dma->bufs[i]
387 .freelist.count),
388 dma->bufs[i].seg_count,
389 dma->bufs[i].seg_count
390 * (1 << dma->bufs[i].page_order),
391 (dma->bufs[i].seg_count
392 * (1 << dma->bufs[i].page_order))
393 * PAGE_SIZE / 1024);
394 }
395 DRM_PROC_PRINT("\n");
396 for (i = 0; i < dma->buf_count; i++) {
397 if (i && !(i % 32))
398 DRM_PROC_PRINT("\n");
399 DRM_PROC_PRINT(" %d", dma->buflist[i]->list);
400 }
401 DRM_PROC_PRINT("\n");
402
403 if (len > request + offset)
404 return request;
405 *eof = 1;
406 return len - offset;
407}
408
409/**
410 * Simply calls _bufs_info() while holding the drm_device::struct_mutex lock.
411 */
412static int drm_bufs_info(char *buf, char **start, off_t offset, int request,
413 int *eof, void *data)
414{
415 struct drm_minor *minor = (struct drm_minor *) data;
416 struct drm_device *dev = minor->dev;
417 int ret;
418
419 mutex_lock(&dev->struct_mutex);
420 ret = drm__bufs_info(buf, start, offset, request, eof, data);
421 mutex_unlock(&dev->struct_mutex);
422 return ret;
423}
424
425/**
426 * Called when "/proc/dri/.../clients" is read.
427 *
428 * \param buf output buffer.
429 * \param start start of output data.
430 * \param offset requested start offset.
431 * \param request requested number of bytes.
432 * \param eof whether there is no more data to return.
433 * \param data private data.
434 * \return number of written bytes.
435 */
436static int drm__clients_info(char *buf, char **start, off_t offset,
437 int request, int *eof, void *data)
438{
439 struct drm_minor *minor = (struct drm_minor *) data;
440 struct drm_device *dev = minor->dev;
441 int len = 0;
442 struct drm_file *priv;
443
444 if (offset > DRM_PROC_LIMIT) {
445 *eof = 1;
446 return 0;
447 }
448
449 *start = &buf[offset];
450 *eof = 0;
451
452 DRM_PROC_PRINT("a dev pid uid magic ioctls\n\n");
453 list_for_each_entry(priv, &dev->filelist, lhead) {
454 DRM_PROC_PRINT("%c %3d %5d %5d %10u %10lu\n",
455 priv->authenticated ? 'y' : 'n',
456 priv->minor->index,
457 priv->pid,
458 priv->uid, priv->magic, priv->ioctl_count);
459 }
460
461 if (len > request + offset)
462 return request;
463 *eof = 1;
464 return len - offset;
465}
466
467/**
468 * Simply calls _clients_info() while holding the drm_device::struct_mutex lock.
469 */
470static int drm_clients_info(char *buf, char **start, off_t offset,
471 int request, int *eof, void *data)
472{
473 struct drm_minor *minor = (struct drm_minor *) data;
474 struct drm_device *dev = minor->dev;
475 int ret;
476
477 mutex_lock(&dev->struct_mutex);
478 ret = drm__clients_info(buf, start, offset, request, eof, data);
479 mutex_unlock(&dev->struct_mutex);
480 return ret;
481}
482
483#if DRM_DEBUG_CODE
484
485static int drm__vma_info(char *buf, char **start, off_t offset, int request,
486 int *eof, void *data)
487{
488 struct drm_minor *minor = (struct drm_minor *) data;
489 struct drm_device *dev = minor->dev;
490 int len = 0;
491 struct drm_vma_entry *pt;
492 struct vm_area_struct *vma;
493#if defined(__i386__)
494 unsigned int pgprot;
495#endif
496
497 if (offset > DRM_PROC_LIMIT) {
498 *eof = 1;
499 return 0;
500 }
501
502 *start = &buf[offset];
503 *eof = 0;
504
505 DRM_PROC_PRINT("vma use count: %d, high_memory = %p, 0x%08lx\n",
506 atomic_read(&dev->vma_count),
507 high_memory, virt_to_phys(high_memory));
508 list_for_each_entry(pt, &dev->vmalist, head) {
509 if (!(vma = pt->vma))
510 continue;
511 DRM_PROC_PRINT("\n%5d 0x%08lx-0x%08lx %c%c%c%c%c%c 0x%08lx000",
512 pt->pid,
513 vma->vm_start,
514 vma->vm_end,
515 vma->vm_flags & VM_READ ? 'r' : '-',
516 vma->vm_flags & VM_WRITE ? 'w' : '-',
517 vma->vm_flags & VM_EXEC ? 'x' : '-',
518 vma->vm_flags & VM_MAYSHARE ? 's' : 'p',
519 vma->vm_flags & VM_LOCKED ? 'l' : '-',
520 vma->vm_flags & VM_IO ? 'i' : '-',
521 vma->vm_pgoff);
522
523#if defined(__i386__)
524 pgprot = pgprot_val(vma->vm_page_prot);
525 DRM_PROC_PRINT(" %c%c%c%c%c%c%c%c%c",
526 pgprot & _PAGE_PRESENT ? 'p' : '-',
527 pgprot & _PAGE_RW ? 'w' : 'r',
528 pgprot & _PAGE_USER ? 'u' : 's',
529 pgprot & _PAGE_PWT ? 't' : 'b',
530 pgprot & _PAGE_PCD ? 'u' : 'c',
531 pgprot & _PAGE_ACCESSED ? 'a' : '-',
532 pgprot & _PAGE_DIRTY ? 'd' : '-',
533 pgprot & _PAGE_PSE ? 'm' : 'k',
534 pgprot & _PAGE_GLOBAL ? 'g' : 'l');
535#endif
536 DRM_PROC_PRINT("\n");
537 }
538
539 if (len > request + offset)
540 return request;
541 *eof = 1;
542 return len - offset;
543}
544
545static int drm_vma_info(char *buf, char **start, off_t offset, int request,
546 int *eof, void *data)
547{
548 struct drm_minor *minor = (struct drm_minor *) data;
549 struct drm_device *dev = minor->dev;
550 int ret;
551
552 mutex_lock(&dev->struct_mutex);
553 ret = drm__vma_info(buf, start, offset, request, eof, data);
554 mutex_unlock(&dev->struct_mutex);
555 return ret;
556}
557#endif
diff --git a/drivers/char/drm/drm_sarea.h b/drivers/char/drm/drm_sarea.h
deleted file mode 100644
index 480037331e4e..000000000000
--- a/drivers/char/drm/drm_sarea.h
+++ /dev/null
@@ -1,84 +0,0 @@
1/**
2 * \file drm_sarea.h
3 * \brief SAREA definitions
4 *
5 * \author Michel Dänzer <michel@daenzer.net>
6 */
7
8/*
9 * Copyright 2002 Tungsten Graphics, Inc., Cedar Park, Texas.
10 * All Rights Reserved.
11 *
12 * Permission is hereby granted, free of charge, to any person obtaining a
13 * copy of this software and associated documentation files (the "Software"),
14 * to deal in the Software without restriction, including without limitation
15 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16 * and/or sell copies of the Software, and to permit persons to whom the
17 * Software is furnished to do so, subject to the following conditions:
18 *
19 * The above copyright notice and this permission notice (including the next
20 * paragraph) shall be included in all copies or substantial portions of the
21 * Software.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26 * TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
27 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
28 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
29 * OTHER DEALINGS IN THE SOFTWARE.
30 */
31
32#ifndef _DRM_SAREA_H_
33#define _DRM_SAREA_H_
34
35#include "drm.h"
36
37/* SAREA area needs to be at least a page */
38#if defined(__alpha__)
39#define SAREA_MAX 0x2000
40#elif defined(__ia64__)
41#define SAREA_MAX 0x10000 /* 64kB */
42#else
43/* Intel 830M driver needs at least 8k SAREA */
44#define SAREA_MAX 0x2000
45#endif
46
47/** Maximum number of drawables in the SAREA */
48#define SAREA_MAX_DRAWABLES 256
49
50#define SAREA_DRAWABLE_CLAIMED_ENTRY 0x80000000
51
52/** SAREA drawable */
53struct drm_sarea_drawable {
54 unsigned int stamp;
55 unsigned int flags;
56};
57
58/** SAREA frame */
59struct drm_sarea_frame {
60 unsigned int x;
61 unsigned int y;
62 unsigned int width;
63 unsigned int height;
64 unsigned int fullscreen;
65};
66
67/** SAREA */
68struct drm_sarea {
69 /** first thing is always the DRM locking structure */
70 struct drm_hw_lock lock;
71 /** \todo Use readers/writer lock for drm_sarea::drawable_lock */
72 struct drm_hw_lock drawable_lock;
73 struct drm_sarea_drawable drawableTable[SAREA_MAX_DRAWABLES]; /**< drawables */
74 struct drm_sarea_frame frame; /**< frame */
75 drm_context_t dummy_context;
76};
77
78#ifndef __KERNEL__
79typedef struct drm_sarea_drawable drm_sarea_drawable_t;
80typedef struct drm_sarea_frame drm_sarea_frame_t;
81typedef struct drm_sarea drm_sarea_t;
82#endif
83
84#endif /* _DRM_SAREA_H_ */
diff --git a/drivers/char/drm/drm_scatter.c b/drivers/char/drm/drm_scatter.c
deleted file mode 100644
index b2b0f3d41714..000000000000
--- a/drivers/char/drm/drm_scatter.c
+++ /dev/null
@@ -1,227 +0,0 @@
1/**
2 * \file drm_scatter.c
3 * IOCTLs to manage scatter/gather memory
4 *
5 * \author Gareth Hughes <gareth@valinux.com>
6 */
7
8/*
9 * Created: Mon Dec 18 23:20:54 2000 by gareth@valinux.com
10 *
11 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
12 * All Rights Reserved.
13 *
14 * Permission is hereby granted, free of charge, to any person obtaining a
15 * copy of this software and associated documentation files (the "Software"),
16 * to deal in the Software without restriction, including without limitation
17 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
18 * and/or sell copies of the Software, and to permit persons to whom the
19 * Software is furnished to do so, subject to the following conditions:
20 *
21 * The above copyright notice and this permission notice (including the next
22 * paragraph) shall be included in all copies or substantial portions of the
23 * Software.
24 *
25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
28 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
29 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
30 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
31 * DEALINGS IN THE SOFTWARE.
32 */
33
34#include <linux/vmalloc.h>
35#include "drmP.h"
36
37#define DEBUG_SCATTER 0
38
39static inline void *drm_vmalloc_dma(unsigned long size)
40{
41#if defined(__powerpc__) && defined(CONFIG_NOT_COHERENT_CACHE)
42 return __vmalloc(size, GFP_KERNEL, PAGE_KERNEL | _PAGE_NO_CACHE);
43#else
44 return vmalloc_32(size);
45#endif
46}
47
48void drm_sg_cleanup(struct drm_sg_mem * entry)
49{
50 struct page *page;
51 int i;
52
53 for (i = 0; i < entry->pages; i++) {
54 page = entry->pagelist[i];
55 if (page)
56 ClearPageReserved(page);
57 }
58
59 vfree(entry->virtual);
60
61 drm_free(entry->busaddr,
62 entry->pages * sizeof(*entry->busaddr), DRM_MEM_PAGES);
63 drm_free(entry->pagelist,
64 entry->pages * sizeof(*entry->pagelist), DRM_MEM_PAGES);
65 drm_free(entry, sizeof(*entry), DRM_MEM_SGLISTS);
66}
67
68#ifdef _LP64
69# define ScatterHandle(x) (unsigned int)((x >> 32) + (x & ((1L << 32) - 1)))
70#else
71# define ScatterHandle(x) (unsigned int)(x)
72#endif
73
74int drm_sg_alloc(struct drm_device *dev, struct drm_scatter_gather * request)
75{
76 struct drm_sg_mem *entry;
77 unsigned long pages, i, j;
78
79 DRM_DEBUG("\n");
80
81 if (!drm_core_check_feature(dev, DRIVER_SG))
82 return -EINVAL;
83
84 if (dev->sg)
85 return -EINVAL;
86
87 entry = drm_alloc(sizeof(*entry), DRM_MEM_SGLISTS);
88 if (!entry)
89 return -ENOMEM;
90
91 memset(entry, 0, sizeof(*entry));
92 pages = (request->size + PAGE_SIZE - 1) / PAGE_SIZE;
93 DRM_DEBUG("size=%ld pages=%ld\n", request->size, pages);
94
95 entry->pages = pages;
96 entry->pagelist = drm_alloc(pages * sizeof(*entry->pagelist),
97 DRM_MEM_PAGES);
98 if (!entry->pagelist) {
99 drm_free(entry, sizeof(*entry), DRM_MEM_SGLISTS);
100 return -ENOMEM;
101 }
102
103 memset(entry->pagelist, 0, pages * sizeof(*entry->pagelist));
104
105 entry->busaddr = drm_alloc(pages * sizeof(*entry->busaddr),
106 DRM_MEM_PAGES);
107 if (!entry->busaddr) {
108 drm_free(entry->pagelist,
109 entry->pages * sizeof(*entry->pagelist),
110 DRM_MEM_PAGES);
111 drm_free(entry, sizeof(*entry), DRM_MEM_SGLISTS);
112 return -ENOMEM;
113 }
114 memset((void *)entry->busaddr, 0, pages * sizeof(*entry->busaddr));
115
116 entry->virtual = drm_vmalloc_dma(pages << PAGE_SHIFT);
117 if (!entry->virtual) {
118 drm_free(entry->busaddr,
119 entry->pages * sizeof(*entry->busaddr), DRM_MEM_PAGES);
120 drm_free(entry->pagelist,
121 entry->pages * sizeof(*entry->pagelist),
122 DRM_MEM_PAGES);
123 drm_free(entry, sizeof(*entry), DRM_MEM_SGLISTS);
124 return -ENOMEM;
125 }
126
127 /* This also forces the mapping of COW pages, so our page list
128 * will be valid. Please don't remove it...
129 */
130 memset(entry->virtual, 0, pages << PAGE_SHIFT);
131
132 entry->handle = ScatterHandle((unsigned long)entry->virtual);
133
134 DRM_DEBUG("handle = %08lx\n", entry->handle);
135 DRM_DEBUG("virtual = %p\n", entry->virtual);
136
137 for (i = (unsigned long)entry->virtual, j = 0; j < pages;
138 i += PAGE_SIZE, j++) {
139 entry->pagelist[j] = vmalloc_to_page((void *)i);
140 if (!entry->pagelist[j])
141 goto failed;
142 SetPageReserved(entry->pagelist[j]);
143 }
144
145 request->handle = entry->handle;
146
147 dev->sg = entry;
148
149#if DEBUG_SCATTER
150 /* Verify that each page points to its virtual address, and vice
151 * versa.
152 */
153 {
154 int error = 0;
155
156 for (i = 0; i < pages; i++) {
157 unsigned long *tmp;
158
159 tmp = page_address(entry->pagelist[i]);
160 for (j = 0;
161 j < PAGE_SIZE / sizeof(unsigned long);
162 j++, tmp++) {
163 *tmp = 0xcafebabe;
164 }
165 tmp = (unsigned long *)((u8 *) entry->virtual +
166 (PAGE_SIZE * i));
167 for (j = 0;
168 j < PAGE_SIZE / sizeof(unsigned long);
169 j++, tmp++) {
170 if (*tmp != 0xcafebabe && error == 0) {
171 error = 1;
172 DRM_ERROR("Scatter allocation error, "
173 "pagelist does not match "
174 "virtual mapping\n");
175 }
176 }
177 tmp = page_address(entry->pagelist[i]);
178 for (j = 0;
179 j < PAGE_SIZE / sizeof(unsigned long);
180 j++, tmp++) {
181 *tmp = 0;
182 }
183 }
184 if (error == 0)
185 DRM_ERROR("Scatter allocation matches pagelist\n");
186 }
187#endif
188
189 return 0;
190
191 failed:
192 drm_sg_cleanup(entry);
193 return -ENOMEM;
194}
195EXPORT_SYMBOL(drm_sg_alloc);
196
197
198int drm_sg_alloc_ioctl(struct drm_device *dev, void *data,
199 struct drm_file *file_priv)
200{
201 struct drm_scatter_gather *request = data;
202
203 return drm_sg_alloc(dev, request);
204
205}
206
207int drm_sg_free(struct drm_device *dev, void *data,
208 struct drm_file *file_priv)
209{
210 struct drm_scatter_gather *request = data;
211 struct drm_sg_mem *entry;
212
213 if (!drm_core_check_feature(dev, DRIVER_SG))
214 return -EINVAL;
215
216 entry = dev->sg;
217 dev->sg = NULL;
218
219 if (!entry || entry->handle != request->handle)
220 return -EINVAL;
221
222 DRM_DEBUG("virtual = %p\n", entry->virtual);
223
224 drm_sg_cleanup(entry);
225
226 return 0;
227}
diff --git a/drivers/char/drm/drm_sman.c b/drivers/char/drm/drm_sman.c
deleted file mode 100644
index 926f146390ce..000000000000
--- a/drivers/char/drm/drm_sman.c
+++ /dev/null
@@ -1,353 +0,0 @@
1/**************************************************************************
2 *
3 * Copyright 2006 Tungsten Graphics, Inc., Bismarck., ND., USA.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
18 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
19 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
20 * USE OR OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * The above copyright notice and this permission notice (including the
23 * next paragraph) shall be included in all copies or substantial portions
24 * of the Software.
25 *
26 *
27 **************************************************************************/
28/*
29 * Simple memory manager interface that keeps track on allocate regions on a
30 * per "owner" basis. All regions associated with an "owner" can be released
31 * with a simple call. Typically if the "owner" exists. The owner is any
32 * "unsigned long" identifier. Can typically be a pointer to a file private
33 * struct or a context identifier.
34 *
35 * Authors:
36 * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
37 */
38
39#include "drm_sman.h"
40
41struct drm_owner_item {
42 struct drm_hash_item owner_hash;
43 struct list_head sman_list;
44 struct list_head mem_blocks;
45};
46
47void drm_sman_takedown(struct drm_sman * sman)
48{
49 drm_ht_remove(&sman->user_hash_tab);
50 drm_ht_remove(&sman->owner_hash_tab);
51 if (sman->mm)
52 drm_free(sman->mm, sman->num_managers * sizeof(*sman->mm),
53 DRM_MEM_MM);
54}
55
56EXPORT_SYMBOL(drm_sman_takedown);
57
58int
59drm_sman_init(struct drm_sman * sman, unsigned int num_managers,
60 unsigned int user_order, unsigned int owner_order)
61{
62 int ret = 0;
63
64 sman->mm = (struct drm_sman_mm *) drm_calloc(num_managers, sizeof(*sman->mm),
65 DRM_MEM_MM);
66 if (!sman->mm) {
67 ret = -ENOMEM;
68 goto out;
69 }
70 sman->num_managers = num_managers;
71 INIT_LIST_HEAD(&sman->owner_items);
72 ret = drm_ht_create(&sman->owner_hash_tab, owner_order);
73 if (ret)
74 goto out1;
75 ret = drm_ht_create(&sman->user_hash_tab, user_order);
76 if (!ret)
77 goto out;
78
79 drm_ht_remove(&sman->owner_hash_tab);
80out1:
81 drm_free(sman->mm, num_managers * sizeof(*sman->mm), DRM_MEM_MM);
82out:
83 return ret;
84}
85
86EXPORT_SYMBOL(drm_sman_init);
87
88static void *drm_sman_mm_allocate(void *private, unsigned long size,
89 unsigned alignment)
90{
91 struct drm_mm *mm = (struct drm_mm *) private;
92 struct drm_mm_node *tmp;
93
94 tmp = drm_mm_search_free(mm, size, alignment, 1);
95 if (!tmp) {
96 return NULL;
97 }
98 tmp = drm_mm_get_block(tmp, size, alignment);
99 return tmp;
100}
101
102static void drm_sman_mm_free(void *private, void *ref)
103{
104 struct drm_mm_node *node = (struct drm_mm_node *) ref;
105
106 drm_mm_put_block(node);
107}
108
109static void drm_sman_mm_destroy(void *private)
110{
111 struct drm_mm *mm = (struct drm_mm *) private;
112 drm_mm_takedown(mm);
113 drm_free(mm, sizeof(*mm), DRM_MEM_MM);
114}
115
116static unsigned long drm_sman_mm_offset(void *private, void *ref)
117{
118 struct drm_mm_node *node = (struct drm_mm_node *) ref;
119 return node->start;
120}
121
122int
123drm_sman_set_range(struct drm_sman * sman, unsigned int manager,
124 unsigned long start, unsigned long size)
125{
126 struct drm_sman_mm *sman_mm;
127 struct drm_mm *mm;
128 int ret;
129
130 BUG_ON(manager >= sman->num_managers);
131
132 sman_mm = &sman->mm[manager];
133 mm = drm_calloc(1, sizeof(*mm), DRM_MEM_MM);
134 if (!mm) {
135 return -ENOMEM;
136 }
137 sman_mm->private = mm;
138 ret = drm_mm_init(mm, start, size);
139
140 if (ret) {
141 drm_free(mm, sizeof(*mm), DRM_MEM_MM);
142 return ret;
143 }
144
145 sman_mm->allocate = drm_sman_mm_allocate;
146 sman_mm->free = drm_sman_mm_free;
147 sman_mm->destroy = drm_sman_mm_destroy;
148 sman_mm->offset = drm_sman_mm_offset;
149
150 return 0;
151}
152
153EXPORT_SYMBOL(drm_sman_set_range);
154
155int
156drm_sman_set_manager(struct drm_sman * sman, unsigned int manager,
157 struct drm_sman_mm * allocator)
158{
159 BUG_ON(manager >= sman->num_managers);
160 sman->mm[manager] = *allocator;
161
162 return 0;
163}
164EXPORT_SYMBOL(drm_sman_set_manager);
165
166static struct drm_owner_item *drm_sman_get_owner_item(struct drm_sman * sman,
167 unsigned long owner)
168{
169 int ret;
170 struct drm_hash_item *owner_hash_item;
171 struct drm_owner_item *owner_item;
172
173 ret = drm_ht_find_item(&sman->owner_hash_tab, owner, &owner_hash_item);
174 if (!ret) {
175 return drm_hash_entry(owner_hash_item, struct drm_owner_item,
176 owner_hash);
177 }
178
179 owner_item = drm_calloc(1, sizeof(*owner_item), DRM_MEM_MM);
180 if (!owner_item)
181 goto out;
182
183 INIT_LIST_HEAD(&owner_item->mem_blocks);
184 owner_item->owner_hash.key = owner;
185 if (drm_ht_insert_item(&sman->owner_hash_tab, &owner_item->owner_hash))
186 goto out1;
187
188 list_add_tail(&owner_item->sman_list, &sman->owner_items);
189 return owner_item;
190
191out1:
192 drm_free(owner_item, sizeof(*owner_item), DRM_MEM_MM);
193out:
194 return NULL;
195}
196
197struct drm_memblock_item *drm_sman_alloc(struct drm_sman *sman, unsigned int manager,
198 unsigned long size, unsigned alignment,
199 unsigned long owner)
200{
201 void *tmp;
202 struct drm_sman_mm *sman_mm;
203 struct drm_owner_item *owner_item;
204 struct drm_memblock_item *memblock;
205
206 BUG_ON(manager >= sman->num_managers);
207
208 sman_mm = &sman->mm[manager];
209 tmp = sman_mm->allocate(sman_mm->private, size, alignment);
210
211 if (!tmp) {
212 return NULL;
213 }
214
215 memblock = drm_calloc(1, sizeof(*memblock), DRM_MEM_MM);
216
217 if (!memblock)
218 goto out;
219
220 memblock->mm_info = tmp;
221 memblock->mm = sman_mm;
222 memblock->sman = sman;
223
224 if (drm_ht_just_insert_please
225 (&sman->user_hash_tab, &memblock->user_hash,
226 (unsigned long)memblock, 32, 0, 0))
227 goto out1;
228
229 owner_item = drm_sman_get_owner_item(sman, owner);
230 if (!owner_item)
231 goto out2;
232
233 list_add_tail(&memblock->owner_list, &owner_item->mem_blocks);
234
235 return memblock;
236
237out2:
238 drm_ht_remove_item(&sman->user_hash_tab, &memblock->user_hash);
239out1:
240 drm_free(memblock, sizeof(*memblock), DRM_MEM_MM);
241out:
242 sman_mm->free(sman_mm->private, tmp);
243
244 return NULL;
245}
246
247EXPORT_SYMBOL(drm_sman_alloc);
248
249static void drm_sman_free(struct drm_memblock_item *item)
250{
251 struct drm_sman *sman = item->sman;
252
253 list_del(&item->owner_list);
254 drm_ht_remove_item(&sman->user_hash_tab, &item->user_hash);
255 item->mm->free(item->mm->private, item->mm_info);
256 drm_free(item, sizeof(*item), DRM_MEM_MM);
257}
258
259int drm_sman_free_key(struct drm_sman *sman, unsigned int key)
260{
261 struct drm_hash_item *hash_item;
262 struct drm_memblock_item *memblock_item;
263
264 if (drm_ht_find_item(&sman->user_hash_tab, key, &hash_item))
265 return -EINVAL;
266
267 memblock_item = drm_hash_entry(hash_item, struct drm_memblock_item,
268 user_hash);
269 drm_sman_free(memblock_item);
270 return 0;
271}
272
273EXPORT_SYMBOL(drm_sman_free_key);
274
275static void drm_sman_remove_owner(struct drm_sman *sman,
276 struct drm_owner_item *owner_item)
277{
278 list_del(&owner_item->sman_list);
279 drm_ht_remove_item(&sman->owner_hash_tab, &owner_item->owner_hash);
280 drm_free(owner_item, sizeof(*owner_item), DRM_MEM_MM);
281}
282
283int drm_sman_owner_clean(struct drm_sman *sman, unsigned long owner)
284{
285
286 struct drm_hash_item *hash_item;
287 struct drm_owner_item *owner_item;
288
289 if (drm_ht_find_item(&sman->owner_hash_tab, owner, &hash_item)) {
290 return -1;
291 }
292
293 owner_item = drm_hash_entry(hash_item, struct drm_owner_item, owner_hash);
294 if (owner_item->mem_blocks.next == &owner_item->mem_blocks) {
295 drm_sman_remove_owner(sman, owner_item);
296 return -1;
297 }
298
299 return 0;
300}
301
302EXPORT_SYMBOL(drm_sman_owner_clean);
303
304static void drm_sman_do_owner_cleanup(struct drm_sman *sman,
305 struct drm_owner_item *owner_item)
306{
307 struct drm_memblock_item *entry, *next;
308
309 list_for_each_entry_safe(entry, next, &owner_item->mem_blocks,
310 owner_list) {
311 drm_sman_free(entry);
312 }
313 drm_sman_remove_owner(sman, owner_item);
314}
315
316void drm_sman_owner_cleanup(struct drm_sman *sman, unsigned long owner)
317{
318
319 struct drm_hash_item *hash_item;
320 struct drm_owner_item *owner_item;
321
322 if (drm_ht_find_item(&sman->owner_hash_tab, owner, &hash_item)) {
323
324 return;
325 }
326
327 owner_item = drm_hash_entry(hash_item, struct drm_owner_item, owner_hash);
328 drm_sman_do_owner_cleanup(sman, owner_item);
329}
330
331EXPORT_SYMBOL(drm_sman_owner_cleanup);
332
333void drm_sman_cleanup(struct drm_sman *sman)
334{
335 struct drm_owner_item *entry, *next;
336 unsigned int i;
337 struct drm_sman_mm *sman_mm;
338
339 list_for_each_entry_safe(entry, next, &sman->owner_items, sman_list) {
340 drm_sman_do_owner_cleanup(sman, entry);
341 }
342 if (sman->mm) {
343 for (i = 0; i < sman->num_managers; ++i) {
344 sman_mm = &sman->mm[i];
345 if (sman_mm->private) {
346 sman_mm->destroy(sman_mm->private);
347 sman_mm->private = NULL;
348 }
349 }
350 }
351}
352
353EXPORT_SYMBOL(drm_sman_cleanup);
diff --git a/drivers/char/drm/drm_sman.h b/drivers/char/drm/drm_sman.h
deleted file mode 100644
index 08ecf83ad5d4..000000000000
--- a/drivers/char/drm/drm_sman.h
+++ /dev/null
@@ -1,176 +0,0 @@
1/**************************************************************************
2 *
3 * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
22 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24 * USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 *
27 **************************************************************************/
28/*
29 * Simple memory MANager interface that keeps track on allocate regions on a
30 * per "owner" basis. All regions associated with an "owner" can be released
31 * with a simple call. Typically if the "owner" exists. The owner is any
32 * "unsigned long" identifier. Can typically be a pointer to a file private
33 * struct or a context identifier.
34 *
35 * Authors:
36 * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
37 */
38
39#ifndef DRM_SMAN_H
40#define DRM_SMAN_H
41
42#include "drmP.h"
43#include "drm_hashtab.h"
44
45/*
46 * A class that is an abstration of a simple memory allocator.
47 * The sman implementation provides a default such allocator
48 * using the drm_mm.c implementation. But the user can replace it.
49 * See the SiS implementation, which may use the SiS FB kernel module
50 * for memory management.
51 */
52
53struct drm_sman_mm {
54 /* private info. If allocated, needs to be destroyed by the destroy
55 function */
56 void *private;
57
58 /* Allocate a memory block with given size and alignment.
59 Return an opaque reference to the memory block */
60
61 void *(*allocate) (void *private, unsigned long size,
62 unsigned alignment);
63
64 /* Free a memory block. "ref" is the opaque reference that we got from
65 the "alloc" function */
66
67 void (*free) (void *private, void *ref);
68
69 /* Free all resources associated with this allocator */
70
71 void (*destroy) (void *private);
72
73 /* Return a memory offset from the opaque reference returned from the
74 "alloc" function */
75
76 unsigned long (*offset) (void *private, void *ref);
77};
78
79struct drm_memblock_item {
80 struct list_head owner_list;
81 struct drm_hash_item user_hash;
82 void *mm_info;
83 struct drm_sman_mm *mm;
84 struct drm_sman *sman;
85};
86
87struct drm_sman {
88 struct drm_sman_mm *mm;
89 int num_managers;
90 struct drm_open_hash owner_hash_tab;
91 struct drm_open_hash user_hash_tab;
92 struct list_head owner_items;
93};
94
95/*
96 * Take down a memory manager. This function should only be called after a
97 * successful init and after a call to drm_sman_cleanup.
98 */
99
100extern void drm_sman_takedown(struct drm_sman * sman);
101
102/*
103 * Allocate structures for a manager.
104 * num_managers are the number of memory pools to manage. (VRAM, AGP, ....)
105 * user_order is the log2 of the number of buckets in the user hash table.
106 * set this to approximately log2 of the max number of memory regions
107 * that will be allocated for _all_ pools together.
108 * owner_order is the log2 of the number of buckets in the owner hash table.
109 * set this to approximately log2 of
110 * the number of client file connections that will
111 * be using the manager.
112 *
113 */
114
115extern int drm_sman_init(struct drm_sman * sman, unsigned int num_managers,
116 unsigned int user_order, unsigned int owner_order);
117
118/*
119 * Initialize a drm_mm.c allocator. Should be called only once for each
120 * manager unless a customized allogator is used.
121 */
122
123extern int drm_sman_set_range(struct drm_sman * sman, unsigned int manager,
124 unsigned long start, unsigned long size);
125
126/*
127 * Initialize a customized allocator for one of the managers.
128 * (See the SiS module). The object pointed to by "allocator" is copied,
129 * so it can be destroyed after this call.
130 */
131
132extern int drm_sman_set_manager(struct drm_sman * sman, unsigned int mananger,
133 struct drm_sman_mm * allocator);
134
135/*
136 * Allocate a memory block. Aligment is not implemented yet.
137 */
138
139extern struct drm_memblock_item *drm_sman_alloc(struct drm_sman * sman,
140 unsigned int manager,
141 unsigned long size,
142 unsigned alignment,
143 unsigned long owner);
144/*
145 * Free a memory block identified by its user hash key.
146 */
147
148extern int drm_sman_free_key(struct drm_sman * sman, unsigned int key);
149
150/*
151 * returns 1 iff there are no stale memory blocks associated with this owner.
152 * Typically called to determine if we need to idle the hardware and call
153 * drm_sman_owner_cleanup. If there are no stale memory blocks, it removes all
154 * resources associated with owner.
155 */
156
157extern int drm_sman_owner_clean(struct drm_sman * sman, unsigned long owner);
158
159/*
160 * Frees all stale memory blocks associated with this owner. Note that this
161 * requires that the hardware is finished with all blocks, so the graphics engine
162 * should be idled before this call is made. This function also frees
163 * any resources associated with "owner" and should be called when owner
164 * is not going to be referenced anymore.
165 */
166
167extern void drm_sman_owner_cleanup(struct drm_sman * sman, unsigned long owner);
168
169/*
170 * Frees all stale memory blocks associated with the memory manager.
171 * See idling above.
172 */
173
174extern void drm_sman_cleanup(struct drm_sman * sman);
175
176#endif
diff --git a/drivers/char/drm/drm_stub.c b/drivers/char/drm/drm_stub.c
deleted file mode 100644
index c2f584f3b46c..000000000000
--- a/drivers/char/drm/drm_stub.c
+++ /dev/null
@@ -1,331 +0,0 @@
1/**
2 * \file drm_stub.h
3 * Stub support
4 *
5 * \author Rickard E. (Rik) Faith <faith@valinux.com>
6 */
7
8/*
9 * Created: Fri Jan 19 10:48:35 2001 by faith@acm.org
10 *
11 * Copyright 2001 VA Linux Systems, Inc., Sunnyvale, California.
12 * All Rights Reserved.
13 *
14 * Permission is hereby granted, free of charge, to any person obtaining a
15 * copy of this software and associated documentation files (the "Software"),
16 * to deal in the Software without restriction, including without limitation
17 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
18 * and/or sell copies of the Software, and to permit persons to whom the
19 * Software is furnished to do so, subject to the following conditions:
20 *
21 * The above copyright notice and this permission notice (including the next
22 * paragraph) shall be included in all copies or substantial portions of the
23 * Software.
24 *
25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
28 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
29 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
30 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
31 * DEALINGS IN THE SOFTWARE.
32 */
33
34#include <linux/module.h>
35#include <linux/moduleparam.h>
36#include "drmP.h"
37#include "drm_core.h"
38
39unsigned int drm_debug = 0; /* 1 to enable debug output */
40EXPORT_SYMBOL(drm_debug);
41
42MODULE_AUTHOR(CORE_AUTHOR);
43MODULE_DESCRIPTION(CORE_DESC);
44MODULE_LICENSE("GPL and additional rights");
45MODULE_PARM_DESC(debug, "Enable debug output");
46
47module_param_named(debug, drm_debug, int, 0600);
48
49struct idr drm_minors_idr;
50
51struct class *drm_class;
52struct proc_dir_entry *drm_proc_root;
53
54static int drm_minor_get_id(struct drm_device *dev, int type)
55{
56 int new_id;
57 int ret;
58 int base = 0, limit = 63;
59
60again:
61 if (idr_pre_get(&drm_minors_idr, GFP_KERNEL) == 0) {
62 DRM_ERROR("Out of memory expanding drawable idr\n");
63 return -ENOMEM;
64 }
65 mutex_lock(&dev->struct_mutex);
66 ret = idr_get_new_above(&drm_minors_idr, NULL,
67 base, &new_id);
68 mutex_unlock(&dev->struct_mutex);
69 if (ret == -EAGAIN) {
70 goto again;
71 } else if (ret) {
72 return ret;
73 }
74
75 if (new_id >= limit) {
76 idr_remove(&drm_minors_idr, new_id);
77 return -EINVAL;
78 }
79 return new_id;
80}
81
82static int drm_fill_in_dev(struct drm_device * dev, struct pci_dev *pdev,
83 const struct pci_device_id *ent,
84 struct drm_driver *driver)
85{
86 int retcode;
87
88 INIT_LIST_HEAD(&dev->filelist);
89 INIT_LIST_HEAD(&dev->ctxlist);
90 INIT_LIST_HEAD(&dev->vmalist);
91 INIT_LIST_HEAD(&dev->maplist);
92
93 spin_lock_init(&dev->count_lock);
94 spin_lock_init(&dev->drw_lock);
95 spin_lock_init(&dev->tasklet_lock);
96 spin_lock_init(&dev->lock.spinlock);
97 init_timer(&dev->timer);
98 mutex_init(&dev->struct_mutex);
99 mutex_init(&dev->ctxlist_mutex);
100
101 idr_init(&dev->drw_idr);
102
103 dev->pdev = pdev;
104 dev->pci_device = pdev->device;
105 dev->pci_vendor = pdev->vendor;
106
107#ifdef __alpha__
108 dev->hose = pdev->sysdata;
109#endif
110 dev->irq = pdev->irq;
111
112 if (drm_ht_create(&dev->map_hash, 12)) {
113 return -ENOMEM;
114 }
115
116 /* the DRM has 6 basic counters */
117 dev->counters = 6;
118 dev->types[0] = _DRM_STAT_LOCK;
119 dev->types[1] = _DRM_STAT_OPENS;
120 dev->types[2] = _DRM_STAT_CLOSES;
121 dev->types[3] = _DRM_STAT_IOCTLS;
122 dev->types[4] = _DRM_STAT_LOCKS;
123 dev->types[5] = _DRM_STAT_UNLOCKS;
124
125 dev->driver = driver;
126
127 if (drm_core_has_AGP(dev)) {
128 if (drm_device_is_agp(dev))
129 dev->agp = drm_agp_init(dev);
130 if (drm_core_check_feature(dev, DRIVER_REQUIRE_AGP)
131 && (dev->agp == NULL)) {
132 DRM_ERROR("Cannot initialize the agpgart module.\n");
133 retcode = -EINVAL;
134 goto error_out_unreg;
135 }
136 if (drm_core_has_MTRR(dev)) {
137 if (dev->agp)
138 dev->agp->agp_mtrr =
139 mtrr_add(dev->agp->agp_info.aper_base,
140 dev->agp->agp_info.aper_size *
141 1024 * 1024, MTRR_TYPE_WRCOMB, 1);
142 }
143 }
144
145 if (dev->driver->load)
146 if ((retcode = dev->driver->load(dev, ent->driver_data)))
147 goto error_out_unreg;
148
149 retcode = drm_ctxbitmap_init(dev);
150 if (retcode) {
151 DRM_ERROR("Cannot allocate memory for context bitmap.\n");
152 goto error_out_unreg;
153 }
154
155 return 0;
156
157 error_out_unreg:
158 drm_lastclose(dev);
159 return retcode;
160}
161
162
163/**
164 * Get a secondary minor number.
165 *
166 * \param dev device data structure
167 * \param sec-minor structure to hold the assigned minor
168 * \return negative number on failure.
169 *
170 * Search an empty entry and initialize it to the given parameters, and
171 * create the proc init entry via proc_init(). This routines assigns
172 * minor numbers to secondary heads of multi-headed cards
173 */
174static int drm_get_minor(struct drm_device *dev, struct drm_minor **minor, int type)
175{
176 struct drm_minor *new_minor;
177 int ret;
178 int minor_id;
179
180 DRM_DEBUG("\n");
181
182 minor_id = drm_minor_get_id(dev, type);
183 if (minor_id < 0)
184 return minor_id;
185
186 new_minor = kzalloc(sizeof(struct drm_minor), GFP_KERNEL);
187 if (!new_minor) {
188 ret = -ENOMEM;
189 goto err_idr;
190 }
191
192 new_minor->type = type;
193 new_minor->device = MKDEV(DRM_MAJOR, minor_id);
194 new_minor->dev = dev;
195 new_minor->index = minor_id;
196
197 idr_replace(&drm_minors_idr, new_minor, minor_id);
198
199 if (type == DRM_MINOR_LEGACY) {
200 ret = drm_proc_init(new_minor, minor_id, drm_proc_root);
201 if (ret) {
202 DRM_ERROR("DRM: Failed to initialize /proc/dri.\n");
203 goto err_mem;
204 }
205 } else
206 new_minor->dev_root = NULL;
207
208 ret = drm_sysfs_device_add(new_minor);
209 if (ret) {
210 printk(KERN_ERR
211 "DRM: Error sysfs_device_add.\n");
212 goto err_g2;
213 }
214 *minor = new_minor;
215
216 DRM_DEBUG("new minor assigned %d\n", minor_id);
217 return 0;
218
219
220err_g2:
221 if (new_minor->type == DRM_MINOR_LEGACY)
222 drm_proc_cleanup(new_minor, drm_proc_root);
223err_mem:
224 kfree(new_minor);
225err_idr:
226 idr_remove(&drm_minors_idr, minor_id);
227 *minor = NULL;
228 return ret;
229}
230
231/**
232 * Register.
233 *
234 * \param pdev - PCI device structure
235 * \param ent entry from the PCI ID table with device type flags
236 * \return zero on success or a negative number on failure.
237 *
238 * Attempt to gets inter module "drm" information. If we are first
239 * then register the character device and inter module information.
240 * Try and register, if we fail to register, backout previous work.
241 */
242int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent,
243 struct drm_driver *driver)
244{
245 struct drm_device *dev;
246 int ret;
247
248 DRM_DEBUG("\n");
249
250 dev = drm_calloc(1, sizeof(*dev), DRM_MEM_STUB);
251 if (!dev)
252 return -ENOMEM;
253
254 ret = pci_enable_device(pdev);
255 if (ret)
256 goto err_g1;
257
258 pci_set_master(pdev);
259 if ((ret = drm_fill_in_dev(dev, pdev, ent, driver))) {
260 printk(KERN_ERR "DRM: Fill_in_dev failed.\n");
261 goto err_g2;
262 }
263 if ((ret = drm_get_minor(dev, &dev->primary, DRM_MINOR_LEGACY)))
264 goto err_g2;
265
266 DRM_INFO("Initialized %s %d.%d.%d %s on minor %d\n",
267 driver->name, driver->major, driver->minor, driver->patchlevel,
268 driver->date, dev->primary->index);
269
270 return 0;
271
272err_g2:
273 pci_disable_device(pdev);
274err_g1:
275 drm_free(dev, sizeof(*dev), DRM_MEM_STUB);
276 return ret;
277}
278
279/**
280 * Put a device minor number.
281 *
282 * \param dev device data structure
283 * \return always zero
284 *
285 * Cleans up the proc resources. If it is the last minor then release the foreign
286 * "drm" data, otherwise unregisters the "drm" data, frees the dev list and
287 * unregisters the character device.
288 */
289int drm_put_dev(struct drm_device * dev)
290{
291 DRM_DEBUG("release primary %s\n", dev->driver->pci_driver.name);
292
293 if (dev->unique) {
294 drm_free(dev->unique, strlen(dev->unique) + 1, DRM_MEM_DRIVER);
295 dev->unique = NULL;
296 dev->unique_len = 0;
297 }
298 if (dev->devname) {
299 drm_free(dev->devname, strlen(dev->devname) + 1,
300 DRM_MEM_DRIVER);
301 dev->devname = NULL;
302 }
303 drm_free(dev, sizeof(*dev), DRM_MEM_STUB);
304 return 0;
305}
306
307/**
308 * Put a secondary minor number.
309 *
310 * \param sec_minor - structure to be released
311 * \return always zero
312 *
313 * Cleans up the proc resources. Not legal for this to be the
314 * last minor released.
315 *
316 */
317int drm_put_minor(struct drm_minor **minor_p)
318{
319 struct drm_minor *minor = *minor_p;
320 DRM_DEBUG("release secondary minor %d\n", minor->index);
321
322 if (minor->type == DRM_MINOR_LEGACY)
323 drm_proc_cleanup(minor, drm_proc_root);
324 drm_sysfs_device_remove(minor);
325
326 idr_remove(&drm_minors_idr, minor->index);
327
328 kfree(minor);
329 *minor_p = NULL;
330 return 0;
331}
diff --git a/drivers/char/drm/drm_sysfs.c b/drivers/char/drm/drm_sysfs.c
deleted file mode 100644
index 9a32169e88fb..000000000000
--- a/drivers/char/drm/drm_sysfs.c
+++ /dev/null
@@ -1,210 +0,0 @@
1
2/*
3 * drm_sysfs.c - Modifications to drm_sysfs_class.c to support
4 * extra sysfs attribute from DRM. Normal drm_sysfs_class
5 * does not allow adding attributes.
6 *
7 * Copyright (c) 2004 Jon Smirl <jonsmirl@gmail.com>
8 * Copyright (c) 2003-2004 Greg Kroah-Hartman <greg@kroah.com>
9 * Copyright (c) 2003-2004 IBM Corp.
10 *
11 * This file is released under the GPLv2
12 *
13 */
14
15#include <linux/device.h>
16#include <linux/kdev_t.h>
17#include <linux/err.h>
18
19#include "drm_core.h"
20#include "drmP.h"
21
22#define to_drm_minor(d) container_of(d, struct drm_minor, kdev)
23
24/**
25 * drm_sysfs_suspend - DRM class suspend hook
26 * @dev: Linux device to suspend
27 * @state: power state to enter
28 *
29 * Just figures out what the actual struct drm_device associated with
30 * @dev is and calls its suspend hook, if present.
31 */
32static int drm_sysfs_suspend(struct device *dev, pm_message_t state)
33{
34 struct drm_minor *drm_minor = to_drm_minor(dev);
35 struct drm_device *drm_dev = drm_minor->dev;
36
37 printk(KERN_ERR "%s\n", __func__);
38
39 if (drm_dev->driver->suspend)
40 return drm_dev->driver->suspend(drm_dev, state);
41
42 return 0;
43}
44
45/**
46 * drm_sysfs_resume - DRM class resume hook
47 * @dev: Linux device to resume
48 *
49 * Just figures out what the actual struct drm_device associated with
50 * @dev is and calls its resume hook, if present.
51 */
52static int drm_sysfs_resume(struct device *dev)
53{
54 struct drm_minor *drm_minor = to_drm_minor(dev);
55 struct drm_device *drm_dev = drm_minor->dev;
56
57 if (drm_dev->driver->resume)
58 return drm_dev->driver->resume(drm_dev);
59
60 return 0;
61}
62
63/* Display the version of drm_core. This doesn't work right in current design */
64static ssize_t version_show(struct class *dev, char *buf)
65{
66 return sprintf(buf, "%s %d.%d.%d %s\n", CORE_NAME, CORE_MAJOR,
67 CORE_MINOR, CORE_PATCHLEVEL, CORE_DATE);
68}
69
70static CLASS_ATTR(version, S_IRUGO, version_show, NULL);
71
72/**
73 * drm_sysfs_create - create a struct drm_sysfs_class structure
74 * @owner: pointer to the module that is to "own" this struct drm_sysfs_class
75 * @name: pointer to a string for the name of this class.
76 *
77 * This is used to create DRM class pointer that can then be used
78 * in calls to drm_sysfs_device_add().
79 *
80 * Note, the pointer created here is to be destroyed when finished by making a
81 * call to drm_sysfs_destroy().
82 */
83struct class *drm_sysfs_create(struct module *owner, char *name)
84{
85 struct class *class;
86 int err;
87
88 class = class_create(owner, name);
89 if (IS_ERR(class)) {
90 err = PTR_ERR(class);
91 goto err_out;
92 }
93
94 class->suspend = drm_sysfs_suspend;
95 class->resume = drm_sysfs_resume;
96
97 err = class_create_file(class, &class_attr_version);
98 if (err)
99 goto err_out_class;
100
101 return class;
102
103err_out_class:
104 class_destroy(class);
105err_out:
106 return ERR_PTR(err);
107}
108
109/**
110 * drm_sysfs_destroy - destroys DRM class
111 *
112 * Destroy the DRM device class.
113 */
114void drm_sysfs_destroy(void)
115{
116 if ((drm_class == NULL) || (IS_ERR(drm_class)))
117 return;
118 class_remove_file(drm_class, &class_attr_version);
119 class_destroy(drm_class);
120}
121
122static ssize_t show_dri(struct device *device, struct device_attribute *attr,
123 char *buf)
124{
125 struct drm_minor *drm_minor = to_drm_minor(device);
126 struct drm_device *drm_dev = drm_minor->dev;
127 if (drm_dev->driver->dri_library_name)
128 return drm_dev->driver->dri_library_name(drm_dev, buf);
129 return snprintf(buf, PAGE_SIZE, "%s\n", drm_dev->driver->pci_driver.name);
130}
131
132static struct device_attribute device_attrs[] = {
133 __ATTR(dri_library_name, S_IRUGO, show_dri, NULL),
134};
135
136/**
137 * drm_sysfs_device_release - do nothing
138 * @dev: Linux device
139 *
140 * Normally, this would free the DRM device associated with @dev, along
141 * with cleaning up any other stuff. But we do that in the DRM core, so
142 * this function can just return and hope that the core does its job.
143 */
144static void drm_sysfs_device_release(struct device *dev)
145{
146 return;
147}
148
149/**
150 * drm_sysfs_device_add - adds a class device to sysfs for a character driver
151 * @dev: DRM device to be added
152 * @head: DRM head in question
153 *
154 * Add a DRM device to the DRM's device model class. We use @dev's PCI device
155 * as the parent for the Linux device, and make sure it has a file containing
156 * the driver we're using (for userspace compatibility).
157 */
158int drm_sysfs_device_add(struct drm_minor *minor)
159{
160 int err;
161 int i, j;
162 char *minor_str;
163
164 minor->kdev.parent = &minor->dev->pdev->dev;
165 minor->kdev.class = drm_class;
166 minor->kdev.release = drm_sysfs_device_release;
167 minor->kdev.devt = minor->device;
168 minor_str = "card%d";
169
170 snprintf(minor->kdev.bus_id, BUS_ID_SIZE, minor_str, minor->index);
171
172 err = device_register(&minor->kdev);
173 if (err) {
174 DRM_ERROR("device add failed: %d\n", err);
175 goto err_out;
176 }
177
178 for (i = 0; i < ARRAY_SIZE(device_attrs); i++) {
179 err = device_create_file(&minor->kdev, &device_attrs[i]);
180 if (err)
181 goto err_out_files;
182 }
183
184 return 0;
185
186err_out_files:
187 if (i > 0)
188 for (j = 0; j < i; j++)
189 device_remove_file(&minor->kdev, &device_attrs[i]);
190 device_unregister(&minor->kdev);
191err_out:
192
193 return err;
194}
195
196/**
197 * drm_sysfs_device_remove - remove DRM device
198 * @dev: DRM device to remove
199 *
200 * This call unregisters and cleans up a class device that was created with a
201 * call to drm_sysfs_device_add()
202 */
203void drm_sysfs_device_remove(struct drm_minor *minor)
204{
205 int i;
206
207 for (i = 0; i < ARRAY_SIZE(device_attrs); i++)
208 device_remove_file(&minor->kdev, &device_attrs[i]);
209 device_unregister(&minor->kdev);
210}
diff --git a/drivers/char/drm/drm_vm.c b/drivers/char/drm/drm_vm.c
deleted file mode 100644
index c234c6f24a8d..000000000000
--- a/drivers/char/drm/drm_vm.c
+++ /dev/null
@@ -1,673 +0,0 @@
1/**
2 * \file drm_vm.c
3 * Memory mapping for DRM
4 *
5 * \author Rickard E. (Rik) Faith <faith@valinux.com>
6 * \author Gareth Hughes <gareth@valinux.com>
7 */
8
9/*
10 * Created: Mon Jan 4 08:58:31 1999 by faith@valinux.com
11 *
12 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
13 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
14 * All Rights Reserved.
15 *
16 * Permission is hereby granted, free of charge, to any person obtaining a
17 * copy of this software and associated documentation files (the "Software"),
18 * to deal in the Software without restriction, including without limitation
19 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
20 * and/or sell copies of the Software, and to permit persons to whom the
21 * Software is furnished to do so, subject to the following conditions:
22 *
23 * The above copyright notice and this permission notice (including the next
24 * paragraph) shall be included in all copies or substantial portions of the
25 * Software.
26 *
27 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
28 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
29 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
30 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
31 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
32 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
33 * OTHER DEALINGS IN THE SOFTWARE.
34 */
35
36#include "drmP.h"
37#if defined(__ia64__)
38#include <linux/efi.h>
39#endif
40
41static void drm_vm_open(struct vm_area_struct *vma);
42static void drm_vm_close(struct vm_area_struct *vma);
43
44static pgprot_t drm_io_prot(uint32_t map_type, struct vm_area_struct *vma)
45{
46 pgprot_t tmp = vm_get_page_prot(vma->vm_flags);
47
48#if defined(__i386__) || defined(__x86_64__)
49 if (boot_cpu_data.x86 > 3 && map_type != _DRM_AGP) {
50 pgprot_val(tmp) |= _PAGE_PCD;
51 pgprot_val(tmp) &= ~_PAGE_PWT;
52 }
53#elif defined(__powerpc__)
54 pgprot_val(tmp) |= _PAGE_NO_CACHE;
55 if (map_type == _DRM_REGISTERS)
56 pgprot_val(tmp) |= _PAGE_GUARDED;
57#elif defined(__ia64__)
58 if (efi_range_is_wc(vma->vm_start, vma->vm_end -
59 vma->vm_start))
60 tmp = pgprot_writecombine(tmp);
61 else
62 tmp = pgprot_noncached(tmp);
63#elif defined(__sparc__)
64 tmp = pgprot_noncached(tmp);
65#endif
66 return tmp;
67}
68
69static pgprot_t drm_dma_prot(uint32_t map_type, struct vm_area_struct *vma)
70{
71 pgprot_t tmp = vm_get_page_prot(vma->vm_flags);
72
73#if defined(__powerpc__) && defined(CONFIG_NOT_COHERENT_CACHE)
74 tmp |= _PAGE_NO_CACHE;
75#endif
76 return tmp;
77}
78
79/**
80 * \c fault method for AGP virtual memory.
81 *
82 * \param vma virtual memory area.
83 * \param address access address.
84 * \return pointer to the page structure.
85 *
86 * Find the right map and if it's AGP memory find the real physical page to
87 * map, get the page, increment the use count and return it.
88 */
89#if __OS_HAS_AGP
90static int drm_do_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
91{
92 struct drm_file *priv = vma->vm_file->private_data;
93 struct drm_device *dev = priv->minor->dev;
94 struct drm_map *map = NULL;
95 struct drm_map_list *r_list;
96 struct drm_hash_item *hash;
97
98 /*
99 * Find the right map
100 */
101 if (!drm_core_has_AGP(dev))
102 goto vm_fault_error;
103
104 if (!dev->agp || !dev->agp->cant_use_aperture)
105 goto vm_fault_error;
106
107 if (drm_ht_find_item(&dev->map_hash, vma->vm_pgoff, &hash))
108 goto vm_fault_error;
109
110 r_list = drm_hash_entry(hash, struct drm_map_list, hash);
111 map = r_list->map;
112
113 if (map && map->type == _DRM_AGP) {
114 /*
115 * Using vm_pgoff as a selector forces us to use this unusual
116 * addressing scheme.
117 */
118 unsigned long offset = (unsigned long)vmf->virtual_address -
119 vma->vm_start;
120 unsigned long baddr = map->offset + offset;
121 struct drm_agp_mem *agpmem;
122 struct page *page;
123
124#ifdef __alpha__
125 /*
126 * Adjust to a bus-relative address
127 */
128 baddr -= dev->hose->mem_space->start;
129#endif
130
131 /*
132 * It's AGP memory - find the real physical page to map
133 */
134 list_for_each_entry(agpmem, &dev->agp->memory, head) {
135 if (agpmem->bound <= baddr &&
136 agpmem->bound + agpmem->pages * PAGE_SIZE > baddr)
137 break;
138 }
139
140 if (!agpmem)
141 goto vm_fault_error;
142
143 /*
144 * Get the page, inc the use count, and return it
145 */
146 offset = (baddr - agpmem->bound) >> PAGE_SHIFT;
147 page = virt_to_page(__va(agpmem->memory->memory[offset]));
148 get_page(page);
149 vmf->page = page;
150
151 DRM_DEBUG
152 ("baddr = 0x%lx page = 0x%p, offset = 0x%lx, count=%d\n",
153 baddr, __va(agpmem->memory->memory[offset]), offset,
154 page_count(page));
155 return 0;
156 }
157vm_fault_error:
158 return VM_FAULT_SIGBUS; /* Disallow mremap */
159}
160#else /* __OS_HAS_AGP */
161static int drm_do_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
162{
163 return VM_FAULT_SIGBUS;
164}
165#endif /* __OS_HAS_AGP */
166
167/**
168 * \c nopage method for shared virtual memory.
169 *
170 * \param vma virtual memory area.
171 * \param address access address.
172 * \return pointer to the page structure.
173 *
174 * Get the mapping, find the real physical page to map, get the page, and
175 * return it.
176 */
177static int drm_do_vm_shm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
178{
179 struct drm_map *map = (struct drm_map *) vma->vm_private_data;
180 unsigned long offset;
181 unsigned long i;
182 struct page *page;
183
184 if (!map)
185 return VM_FAULT_SIGBUS; /* Nothing allocated */
186
187 offset = (unsigned long)vmf->virtual_address - vma->vm_start;
188 i = (unsigned long)map->handle + offset;
189 page = vmalloc_to_page((void *)i);
190 if (!page)
191 return VM_FAULT_SIGBUS;
192 get_page(page);
193 vmf->page = page;
194
195 DRM_DEBUG("shm_fault 0x%lx\n", offset);
196 return 0;
197}
198
199/**
200 * \c close method for shared virtual memory.
201 *
202 * \param vma virtual memory area.
203 *
204 * Deletes map information if we are the last
205 * person to close a mapping and it's not in the global maplist.
206 */
207static void drm_vm_shm_close(struct vm_area_struct *vma)
208{
209 struct drm_file *priv = vma->vm_file->private_data;
210 struct drm_device *dev = priv->minor->dev;
211 struct drm_vma_entry *pt, *temp;
212 struct drm_map *map;
213 struct drm_map_list *r_list;
214 int found_maps = 0;
215
216 DRM_DEBUG("0x%08lx,0x%08lx\n",
217 vma->vm_start, vma->vm_end - vma->vm_start);
218 atomic_dec(&dev->vma_count);
219
220 map = vma->vm_private_data;
221
222 mutex_lock(&dev->struct_mutex);
223 list_for_each_entry_safe(pt, temp, &dev->vmalist, head) {
224 if (pt->vma->vm_private_data == map)
225 found_maps++;
226 if (pt->vma == vma) {
227 list_del(&pt->head);
228 drm_free(pt, sizeof(*pt), DRM_MEM_VMAS);
229 }
230 }
231
232 /* We were the only map that was found */
233 if (found_maps == 1 && map->flags & _DRM_REMOVABLE) {
234 /* Check to see if we are in the maplist, if we are not, then
235 * we delete this mappings information.
236 */
237 found_maps = 0;
238 list_for_each_entry(r_list, &dev->maplist, head) {
239 if (r_list->map == map)
240 found_maps++;
241 }
242
243 if (!found_maps) {
244 drm_dma_handle_t dmah;
245
246 switch (map->type) {
247 case _DRM_REGISTERS:
248 case _DRM_FRAME_BUFFER:
249 if (drm_core_has_MTRR(dev) && map->mtrr >= 0) {
250 int retcode;
251 retcode = mtrr_del(map->mtrr,
252 map->offset,
253 map->size);
254 DRM_DEBUG("mtrr_del = %d\n", retcode);
255 }
256 iounmap(map->handle);
257 break;
258 case _DRM_SHM:
259 vfree(map->handle);
260 break;
261 case _DRM_AGP:
262 case _DRM_SCATTER_GATHER:
263 break;
264 case _DRM_CONSISTENT:
265 dmah.vaddr = map->handle;
266 dmah.busaddr = map->offset;
267 dmah.size = map->size;
268 __drm_pci_free(dev, &dmah);
269 break;
270 }
271 drm_free(map, sizeof(*map), DRM_MEM_MAPS);
272 }
273 }
274 mutex_unlock(&dev->struct_mutex);
275}
276
277/**
278 * \c fault method for DMA virtual memory.
279 *
280 * \param vma virtual memory area.
281 * \param address access address.
282 * \return pointer to the page structure.
283 *
284 * Determine the page number from the page offset and get it from drm_device_dma::pagelist.
285 */
286static int drm_do_vm_dma_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
287{
288 struct drm_file *priv = vma->vm_file->private_data;
289 struct drm_device *dev = priv->minor->dev;
290 struct drm_device_dma *dma = dev->dma;
291 unsigned long offset;
292 unsigned long page_nr;
293 struct page *page;
294
295 if (!dma)
296 return VM_FAULT_SIGBUS; /* Error */
297 if (!dma->pagelist)
298 return VM_FAULT_SIGBUS; /* Nothing allocated */
299
300 offset = (unsigned long)vmf->virtual_address - vma->vm_start; /* vm_[pg]off[set] should be 0 */
301 page_nr = offset >> PAGE_SHIFT; /* page_nr could just be vmf->pgoff */
302 page = virt_to_page((dma->pagelist[page_nr] + (offset & (~PAGE_MASK))));
303
304 get_page(page);
305 vmf->page = page;
306
307 DRM_DEBUG("dma_fault 0x%lx (page %lu)\n", offset, page_nr);
308 return 0;
309}
310
311/**
312 * \c fault method for scatter-gather virtual memory.
313 *
314 * \param vma virtual memory area.
315 * \param address access address.
316 * \return pointer to the page structure.
317 *
318 * Determine the map offset from the page offset and get it from drm_sg_mem::pagelist.
319 */
320static int drm_do_vm_sg_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
321{
322 struct drm_map *map = (struct drm_map *) vma->vm_private_data;
323 struct drm_file *priv = vma->vm_file->private_data;
324 struct drm_device *dev = priv->minor->dev;
325 struct drm_sg_mem *entry = dev->sg;
326 unsigned long offset;
327 unsigned long map_offset;
328 unsigned long page_offset;
329 struct page *page;
330
331 if (!entry)
332 return VM_FAULT_SIGBUS; /* Error */
333 if (!entry->pagelist)
334 return VM_FAULT_SIGBUS; /* Nothing allocated */
335
336 offset = (unsigned long)vmf->virtual_address - vma->vm_start;
337 map_offset = map->offset - (unsigned long)dev->sg->virtual;
338 page_offset = (offset >> PAGE_SHIFT) + (map_offset >> PAGE_SHIFT);
339 page = entry->pagelist[page_offset];
340 get_page(page);
341 vmf->page = page;
342
343 return 0;
344}
345
346static int drm_vm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
347{
348 return drm_do_vm_fault(vma, vmf);
349}
350
351static int drm_vm_shm_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
352{
353 return drm_do_vm_shm_fault(vma, vmf);
354}
355
356static int drm_vm_dma_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
357{
358 return drm_do_vm_dma_fault(vma, vmf);
359}
360
361static int drm_vm_sg_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
362{
363 return drm_do_vm_sg_fault(vma, vmf);
364}
365
366/** AGP virtual memory operations */
367static struct vm_operations_struct drm_vm_ops = {
368 .fault = drm_vm_fault,
369 .open = drm_vm_open,
370 .close = drm_vm_close,
371};
372
373/** Shared virtual memory operations */
374static struct vm_operations_struct drm_vm_shm_ops = {
375 .fault = drm_vm_shm_fault,
376 .open = drm_vm_open,
377 .close = drm_vm_shm_close,
378};
379
380/** DMA virtual memory operations */
381static struct vm_operations_struct drm_vm_dma_ops = {
382 .fault = drm_vm_dma_fault,
383 .open = drm_vm_open,
384 .close = drm_vm_close,
385};
386
387/** Scatter-gather virtual memory operations */
388static struct vm_operations_struct drm_vm_sg_ops = {
389 .fault = drm_vm_sg_fault,
390 .open = drm_vm_open,
391 .close = drm_vm_close,
392};
393
394/**
395 * \c open method for shared virtual memory.
396 *
397 * \param vma virtual memory area.
398 *
399 * Create a new drm_vma_entry structure as the \p vma private data entry and
400 * add it to drm_device::vmalist.
401 */
402static void drm_vm_open_locked(struct vm_area_struct *vma)
403{
404 struct drm_file *priv = vma->vm_file->private_data;
405 struct drm_device *dev = priv->minor->dev;
406 struct drm_vma_entry *vma_entry;
407
408 DRM_DEBUG("0x%08lx,0x%08lx\n",
409 vma->vm_start, vma->vm_end - vma->vm_start);
410 atomic_inc(&dev->vma_count);
411
412 vma_entry = drm_alloc(sizeof(*vma_entry), DRM_MEM_VMAS);
413 if (vma_entry) {
414 vma_entry->vma = vma;
415 vma_entry->pid = current->pid;
416 list_add(&vma_entry->head, &dev->vmalist);
417 }
418}
419
420static void drm_vm_open(struct vm_area_struct *vma)
421{
422 struct drm_file *priv = vma->vm_file->private_data;
423 struct drm_device *dev = priv->minor->dev;
424
425 mutex_lock(&dev->struct_mutex);
426 drm_vm_open_locked(vma);
427 mutex_unlock(&dev->struct_mutex);
428}
429
430/**
431 * \c close method for all virtual memory types.
432 *
433 * \param vma virtual memory area.
434 *
435 * Search the \p vma private data entry in drm_device::vmalist, unlink it, and
436 * free it.
437 */
438static void drm_vm_close(struct vm_area_struct *vma)
439{
440 struct drm_file *priv = vma->vm_file->private_data;
441 struct drm_device *dev = priv->minor->dev;
442 struct drm_vma_entry *pt, *temp;
443
444 DRM_DEBUG("0x%08lx,0x%08lx\n",
445 vma->vm_start, vma->vm_end - vma->vm_start);
446 atomic_dec(&dev->vma_count);
447
448 mutex_lock(&dev->struct_mutex);
449 list_for_each_entry_safe(pt, temp, &dev->vmalist, head) {
450 if (pt->vma == vma) {
451 list_del(&pt->head);
452 drm_free(pt, sizeof(*pt), DRM_MEM_VMAS);
453 break;
454 }
455 }
456 mutex_unlock(&dev->struct_mutex);
457}
458
459/**
460 * mmap DMA memory.
461 *
462 * \param file_priv DRM file private.
463 * \param vma virtual memory area.
464 * \return zero on success or a negative number on failure.
465 *
466 * Sets the virtual memory area operations structure to vm_dma_ops, the file
467 * pointer, and calls vm_open().
468 */
469static int drm_mmap_dma(struct file *filp, struct vm_area_struct *vma)
470{
471 struct drm_file *priv = filp->private_data;
472 struct drm_device *dev;
473 struct drm_device_dma *dma;
474 unsigned long length = vma->vm_end - vma->vm_start;
475
476 dev = priv->minor->dev;
477 dma = dev->dma;
478 DRM_DEBUG("start = 0x%lx, end = 0x%lx, page offset = 0x%lx\n",
479 vma->vm_start, vma->vm_end, vma->vm_pgoff);
480
481 /* Length must match exact page count */
482 if (!dma || (length >> PAGE_SHIFT) != dma->page_count) {
483 return -EINVAL;
484 }
485
486 if (!capable(CAP_SYS_ADMIN) &&
487 (dma->flags & _DRM_DMA_USE_PCI_RO)) {
488 vma->vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
489#if defined(__i386__) || defined(__x86_64__)
490 pgprot_val(vma->vm_page_prot) &= ~_PAGE_RW;
491#else
492 /* Ye gads this is ugly. With more thought
493 we could move this up higher and use
494 `protection_map' instead. */
495 vma->vm_page_prot =
496 __pgprot(pte_val
497 (pte_wrprotect
498 (__pte(pgprot_val(vma->vm_page_prot)))));
499#endif
500 }
501
502 vma->vm_ops = &drm_vm_dma_ops;
503
504 vma->vm_flags |= VM_RESERVED; /* Don't swap */
505 vma->vm_flags |= VM_DONTEXPAND;
506
507 vma->vm_file = filp; /* Needed for drm_vm_open() */
508 drm_vm_open_locked(vma);
509 return 0;
510}
511
512unsigned long drm_core_get_map_ofs(struct drm_map * map)
513{
514 return map->offset;
515}
516
517EXPORT_SYMBOL(drm_core_get_map_ofs);
518
519unsigned long drm_core_get_reg_ofs(struct drm_device *dev)
520{
521#ifdef __alpha__
522 return dev->hose->dense_mem_base - dev->hose->mem_space->start;
523#else
524 return 0;
525#endif
526}
527
528EXPORT_SYMBOL(drm_core_get_reg_ofs);
529
530/**
531 * mmap DMA memory.
532 *
533 * \param file_priv DRM file private.
534 * \param vma virtual memory area.
535 * \return zero on success or a negative number on failure.
536 *
537 * If the virtual memory area has no offset associated with it then it's a DMA
538 * area, so calls mmap_dma(). Otherwise searches the map in drm_device::maplist,
539 * checks that the restricted flag is not set, sets the virtual memory operations
540 * according to the mapping type and remaps the pages. Finally sets the file
541 * pointer and calls vm_open().
542 */
543static int drm_mmap_locked(struct file *filp, struct vm_area_struct *vma)
544{
545 struct drm_file *priv = filp->private_data;
546 struct drm_device *dev = priv->minor->dev;
547 struct drm_map *map = NULL;
548 unsigned long offset = 0;
549 struct drm_hash_item *hash;
550
551 DRM_DEBUG("start = 0x%lx, end = 0x%lx, page offset = 0x%lx\n",
552 vma->vm_start, vma->vm_end, vma->vm_pgoff);
553
554 if (!priv->authenticated)
555 return -EACCES;
556
557 /* We check for "dma". On Apple's UniNorth, it's valid to have
558 * the AGP mapped at physical address 0
559 * --BenH.
560 */
561 if (!vma->vm_pgoff
562#if __OS_HAS_AGP
563 && (!dev->agp
564 || dev->agp->agp_info.device->vendor != PCI_VENDOR_ID_APPLE)
565#endif
566 )
567 return drm_mmap_dma(filp, vma);
568
569 if (drm_ht_find_item(&dev->map_hash, vma->vm_pgoff, &hash)) {
570 DRM_ERROR("Could not find map\n");
571 return -EINVAL;
572 }
573
574 map = drm_hash_entry(hash, struct drm_map_list, hash)->map;
575 if (!map || ((map->flags & _DRM_RESTRICTED) && !capable(CAP_SYS_ADMIN)))
576 return -EPERM;
577
578 /* Check for valid size. */
579 if (map->size < vma->vm_end - vma->vm_start)
580 return -EINVAL;
581
582 if (!capable(CAP_SYS_ADMIN) && (map->flags & _DRM_READ_ONLY)) {
583 vma->vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
584#if defined(__i386__) || defined(__x86_64__)
585 pgprot_val(vma->vm_page_prot) &= ~_PAGE_RW;
586#else
587 /* Ye gads this is ugly. With more thought
588 we could move this up higher and use
589 `protection_map' instead. */
590 vma->vm_page_prot =
591 __pgprot(pte_val
592 (pte_wrprotect
593 (__pte(pgprot_val(vma->vm_page_prot)))));
594#endif
595 }
596
597 switch (map->type) {
598 case _DRM_AGP:
599 if (drm_core_has_AGP(dev) && dev->agp->cant_use_aperture) {
600 /*
601 * On some platforms we can't talk to bus dma address from the CPU, so for
602 * memory of type DRM_AGP, we'll deal with sorting out the real physical
603 * pages and mappings in fault()
604 */
605#if defined(__powerpc__)
606 pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE;
607#endif
608 vma->vm_ops = &drm_vm_ops;
609 break;
610 }
611 /* fall through to _DRM_FRAME_BUFFER... */
612 case _DRM_FRAME_BUFFER:
613 case _DRM_REGISTERS:
614 offset = dev->driver->get_reg_ofs(dev);
615 vma->vm_flags |= VM_IO; /* not in core dump */
616 vma->vm_page_prot = drm_io_prot(map->type, vma);
617 if (io_remap_pfn_range(vma, vma->vm_start,
618 (map->offset + offset) >> PAGE_SHIFT,
619 vma->vm_end - vma->vm_start,
620 vma->vm_page_prot))
621 return -EAGAIN;
622 DRM_DEBUG(" Type = %d; start = 0x%lx, end = 0x%lx,"
623 " offset = 0x%lx\n",
624 map->type,
625 vma->vm_start, vma->vm_end, map->offset + offset);
626 vma->vm_ops = &drm_vm_ops;
627 break;
628 case _DRM_CONSISTENT:
629 /* Consistent memory is really like shared memory. But
630 * it's allocated in a different way, so avoid fault */
631 if (remap_pfn_range(vma, vma->vm_start,
632 page_to_pfn(virt_to_page(map->handle)),
633 vma->vm_end - vma->vm_start, vma->vm_page_prot))
634 return -EAGAIN;
635 vma->vm_page_prot = drm_dma_prot(map->type, vma);
636 /* fall through to _DRM_SHM */
637 case _DRM_SHM:
638 vma->vm_ops = &drm_vm_shm_ops;
639 vma->vm_private_data = (void *)map;
640 /* Don't let this area swap. Change when
641 DRM_KERNEL advisory is supported. */
642 vma->vm_flags |= VM_RESERVED;
643 break;
644 case _DRM_SCATTER_GATHER:
645 vma->vm_ops = &drm_vm_sg_ops;
646 vma->vm_private_data = (void *)map;
647 vma->vm_flags |= VM_RESERVED;
648 vma->vm_page_prot = drm_dma_prot(map->type, vma);
649 break;
650 default:
651 return -EINVAL; /* This should never happen. */
652 }
653 vma->vm_flags |= VM_RESERVED; /* Don't swap */
654 vma->vm_flags |= VM_DONTEXPAND;
655
656 vma->vm_file = filp; /* Needed for drm_vm_open() */
657 drm_vm_open_locked(vma);
658 return 0;
659}
660
661int drm_mmap(struct file *filp, struct vm_area_struct *vma)
662{
663 struct drm_file *priv = filp->private_data;
664 struct drm_device *dev = priv->minor->dev;
665 int ret;
666
667 mutex_lock(&dev->struct_mutex);
668 ret = drm_mmap_locked(filp, vma);
669 mutex_unlock(&dev->struct_mutex);
670
671 return ret;
672}
673EXPORT_SYMBOL(drm_mmap);
diff --git a/drivers/char/drm/i810_dma.c b/drivers/char/drm/i810_dma.c
deleted file mode 100644
index e5de8ea41544..000000000000
--- a/drivers/char/drm/i810_dma.c
+++ /dev/null
@@ -1,1283 +0,0 @@
1/* i810_dma.c -- DMA support for the i810 -*- linux-c -*-
2 * Created: Mon Dec 13 01:50:01 1999 by jhartmann@precisioninsight.com
3 *
4 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
5 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
6 * All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice (including the next
16 * paragraph) shall be included in all copies or substantial portions of the
17 * Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
23 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 * DEALINGS IN THE SOFTWARE.
26 *
27 * Authors: Rickard E. (Rik) Faith <faith@valinux.com>
28 * Jeff Hartmann <jhartmann@valinux.com>
29 * Keith Whitwell <keith@tungstengraphics.com>
30 *
31 */
32
33#include "drmP.h"
34#include "drm.h"
35#include "i810_drm.h"
36#include "i810_drv.h"
37#include <linux/interrupt.h> /* For task queue support */
38#include <linux/delay.h>
39#include <linux/pagemap.h>
40
41#define I810_BUF_FREE 2
42#define I810_BUF_CLIENT 1
43#define I810_BUF_HARDWARE 0
44
45#define I810_BUF_UNMAPPED 0
46#define I810_BUF_MAPPED 1
47
48static struct drm_buf *i810_freelist_get(struct drm_device * dev)
49{
50 struct drm_device_dma *dma = dev->dma;
51 int i;
52 int used;
53
54 /* Linear search might not be the best solution */
55
56 for (i = 0; i < dma->buf_count; i++) {
57 struct drm_buf *buf = dma->buflist[i];
58 drm_i810_buf_priv_t *buf_priv = buf->dev_private;
59 /* In use is already a pointer */
60 used = cmpxchg(buf_priv->in_use, I810_BUF_FREE,
61 I810_BUF_CLIENT);
62 if (used == I810_BUF_FREE) {
63 return buf;
64 }
65 }
66 return NULL;
67}
68
69/* This should only be called if the buffer is not sent to the hardware
70 * yet, the hardware updates in use for us once its on the ring buffer.
71 */
72
73static int i810_freelist_put(struct drm_device * dev, struct drm_buf * buf)
74{
75 drm_i810_buf_priv_t *buf_priv = buf->dev_private;
76 int used;
77
78 /* In use is already a pointer */
79 used = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT, I810_BUF_FREE);
80 if (used != I810_BUF_CLIENT) {
81 DRM_ERROR("Freeing buffer thats not in use : %d\n", buf->idx);
82 return -EINVAL;
83 }
84
85 return 0;
86}
87
88static int i810_mmap_buffers(struct file *filp, struct vm_area_struct *vma)
89{
90 struct drm_file *priv = filp->private_data;
91 struct drm_device *dev;
92 drm_i810_private_t *dev_priv;
93 struct drm_buf *buf;
94 drm_i810_buf_priv_t *buf_priv;
95
96 lock_kernel();
97 dev = priv->minor->dev;
98 dev_priv = dev->dev_private;
99 buf = dev_priv->mmap_buffer;
100 buf_priv = buf->dev_private;
101
102 vma->vm_flags |= (VM_IO | VM_DONTCOPY);
103 vma->vm_file = filp;
104
105 buf_priv->currently_mapped = I810_BUF_MAPPED;
106 unlock_kernel();
107
108 if (io_remap_pfn_range(vma, vma->vm_start,
109 vma->vm_pgoff,
110 vma->vm_end - vma->vm_start, vma->vm_page_prot))
111 return -EAGAIN;
112 return 0;
113}
114
115static const struct file_operations i810_buffer_fops = {
116 .open = drm_open,
117 .release = drm_release,
118 .ioctl = drm_ioctl,
119 .mmap = i810_mmap_buffers,
120 .fasync = drm_fasync,
121};
122
123static int i810_map_buffer(struct drm_buf * buf, struct drm_file *file_priv)
124{
125 struct drm_device *dev = file_priv->minor->dev;
126 drm_i810_buf_priv_t *buf_priv = buf->dev_private;
127 drm_i810_private_t *dev_priv = dev->dev_private;
128 const struct file_operations *old_fops;
129 int retcode = 0;
130
131 if (buf_priv->currently_mapped == I810_BUF_MAPPED)
132 return -EINVAL;
133
134 down_write(&current->mm->mmap_sem);
135 old_fops = file_priv->filp->f_op;
136 file_priv->filp->f_op = &i810_buffer_fops;
137 dev_priv->mmap_buffer = buf;
138 buf_priv->virtual = (void *)do_mmap(file_priv->filp, 0, buf->total,
139 PROT_READ | PROT_WRITE,
140 MAP_SHARED, buf->bus_address);
141 dev_priv->mmap_buffer = NULL;
142 file_priv->filp->f_op = old_fops;
143 if (IS_ERR(buf_priv->virtual)) {
144 /* Real error */
145 DRM_ERROR("mmap error\n");
146 retcode = PTR_ERR(buf_priv->virtual);
147 buf_priv->virtual = NULL;
148 }
149 up_write(&current->mm->mmap_sem);
150
151 return retcode;
152}
153
154static int i810_unmap_buffer(struct drm_buf * buf)
155{
156 drm_i810_buf_priv_t *buf_priv = buf->dev_private;
157 int retcode = 0;
158
159 if (buf_priv->currently_mapped != I810_BUF_MAPPED)
160 return -EINVAL;
161
162 down_write(&current->mm->mmap_sem);
163 retcode = do_munmap(current->mm,
164 (unsigned long)buf_priv->virtual,
165 (size_t) buf->total);
166 up_write(&current->mm->mmap_sem);
167
168 buf_priv->currently_mapped = I810_BUF_UNMAPPED;
169 buf_priv->virtual = NULL;
170
171 return retcode;
172}
173
174static int i810_dma_get_buffer(struct drm_device * dev, drm_i810_dma_t * d,
175 struct drm_file *file_priv)
176{
177 struct drm_buf *buf;
178 drm_i810_buf_priv_t *buf_priv;
179 int retcode = 0;
180
181 buf = i810_freelist_get(dev);
182 if (!buf) {
183 retcode = -ENOMEM;
184 DRM_DEBUG("retcode=%d\n", retcode);
185 return retcode;
186 }
187
188 retcode = i810_map_buffer(buf, file_priv);
189 if (retcode) {
190 i810_freelist_put(dev, buf);
191 DRM_ERROR("mapbuf failed, retcode %d\n", retcode);
192 return retcode;
193 }
194 buf->file_priv = file_priv;
195 buf_priv = buf->dev_private;
196 d->granted = 1;
197 d->request_idx = buf->idx;
198 d->request_size = buf->total;
199 d->virtual = buf_priv->virtual;
200
201 return retcode;
202}
203
204static int i810_dma_cleanup(struct drm_device * dev)
205{
206 struct drm_device_dma *dma = dev->dma;
207
208 /* Make sure interrupts are disabled here because the uninstall ioctl
209 * may not have been called from userspace and after dev_private
210 * is freed, it's too late.
211 */
212 if (drm_core_check_feature(dev, DRIVER_HAVE_IRQ) && dev->irq_enabled)
213 drm_irq_uninstall(dev);
214
215 if (dev->dev_private) {
216 int i;
217 drm_i810_private_t *dev_priv =
218 (drm_i810_private_t *) dev->dev_private;
219
220 if (dev_priv->ring.virtual_start) {
221 drm_core_ioremapfree(&dev_priv->ring.map, dev);
222 }
223 if (dev_priv->hw_status_page) {
224 pci_free_consistent(dev->pdev, PAGE_SIZE,
225 dev_priv->hw_status_page,
226 dev_priv->dma_status_page);
227 /* Need to rewrite hardware status page */
228 I810_WRITE(0x02080, 0x1ffff000);
229 }
230 drm_free(dev->dev_private, sizeof(drm_i810_private_t),
231 DRM_MEM_DRIVER);
232 dev->dev_private = NULL;
233
234 for (i = 0; i < dma->buf_count; i++) {
235 struct drm_buf *buf = dma->buflist[i];
236 drm_i810_buf_priv_t *buf_priv = buf->dev_private;
237
238 if (buf_priv->kernel_virtual && buf->total)
239 drm_core_ioremapfree(&buf_priv->map, dev);
240 }
241 }
242 return 0;
243}
244
245static int i810_wait_ring(struct drm_device * dev, int n)
246{
247 drm_i810_private_t *dev_priv = dev->dev_private;
248 drm_i810_ring_buffer_t *ring = &(dev_priv->ring);
249 int iters = 0;
250 unsigned long end;
251 unsigned int last_head = I810_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
252
253 end = jiffies + (HZ * 3);
254 while (ring->space < n) {
255 ring->head = I810_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
256 ring->space = ring->head - (ring->tail + 8);
257 if (ring->space < 0)
258 ring->space += ring->Size;
259
260 if (ring->head != last_head) {
261 end = jiffies + (HZ * 3);
262 last_head = ring->head;
263 }
264
265 iters++;
266 if (time_before(end, jiffies)) {
267 DRM_ERROR("space: %d wanted %d\n", ring->space, n);
268 DRM_ERROR("lockup\n");
269 goto out_wait_ring;
270 }
271 udelay(1);
272 }
273
274 out_wait_ring:
275 return iters;
276}
277
278static void i810_kernel_lost_context(struct drm_device * dev)
279{
280 drm_i810_private_t *dev_priv = dev->dev_private;
281 drm_i810_ring_buffer_t *ring = &(dev_priv->ring);
282
283 ring->head = I810_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
284 ring->tail = I810_READ(LP_RING + RING_TAIL);
285 ring->space = ring->head - (ring->tail + 8);
286 if (ring->space < 0)
287 ring->space += ring->Size;
288}
289
290static int i810_freelist_init(struct drm_device * dev, drm_i810_private_t * dev_priv)
291{
292 struct drm_device_dma *dma = dev->dma;
293 int my_idx = 24;
294 u32 *hw_status = (u32 *) (dev_priv->hw_status_page + my_idx);
295 int i;
296
297 if (dma->buf_count > 1019) {
298 /* Not enough space in the status page for the freelist */
299 return -EINVAL;
300 }
301
302 for (i = 0; i < dma->buf_count; i++) {
303 struct drm_buf *buf = dma->buflist[i];
304 drm_i810_buf_priv_t *buf_priv = buf->dev_private;
305
306 buf_priv->in_use = hw_status++;
307 buf_priv->my_use_idx = my_idx;
308 my_idx += 4;
309
310 *buf_priv->in_use = I810_BUF_FREE;
311
312 buf_priv->map.offset = buf->bus_address;
313 buf_priv->map.size = buf->total;
314 buf_priv->map.type = _DRM_AGP;
315 buf_priv->map.flags = 0;
316 buf_priv->map.mtrr = 0;
317
318 drm_core_ioremap(&buf_priv->map, dev);
319 buf_priv->kernel_virtual = buf_priv->map.handle;
320
321 }
322 return 0;
323}
324
325static int i810_dma_initialize(struct drm_device * dev,
326 drm_i810_private_t * dev_priv,
327 drm_i810_init_t * init)
328{
329 struct drm_map_list *r_list;
330 memset(dev_priv, 0, sizeof(drm_i810_private_t));
331
332 list_for_each_entry(r_list, &dev->maplist, head) {
333 if (r_list->map &&
334 r_list->map->type == _DRM_SHM &&
335 r_list->map->flags & _DRM_CONTAINS_LOCK) {
336 dev_priv->sarea_map = r_list->map;
337 break;
338 }
339 }
340 if (!dev_priv->sarea_map) {
341 dev->dev_private = (void *)dev_priv;
342 i810_dma_cleanup(dev);
343 DRM_ERROR("can not find sarea!\n");
344 return -EINVAL;
345 }
346 dev_priv->mmio_map = drm_core_findmap(dev, init->mmio_offset);
347 if (!dev_priv->mmio_map) {
348 dev->dev_private = (void *)dev_priv;
349 i810_dma_cleanup(dev);
350 DRM_ERROR("can not find mmio map!\n");
351 return -EINVAL;
352 }
353 dev->agp_buffer_token = init->buffers_offset;
354 dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset);
355 if (!dev->agp_buffer_map) {
356 dev->dev_private = (void *)dev_priv;
357 i810_dma_cleanup(dev);
358 DRM_ERROR("can not find dma buffer map!\n");
359 return -EINVAL;
360 }
361
362 dev_priv->sarea_priv = (drm_i810_sarea_t *)
363 ((u8 *) dev_priv->sarea_map->handle + init->sarea_priv_offset);
364
365 dev_priv->ring.Start = init->ring_start;
366 dev_priv->ring.End = init->ring_end;
367 dev_priv->ring.Size = init->ring_size;
368
369 dev_priv->ring.map.offset = dev->agp->base + init->ring_start;
370 dev_priv->ring.map.size = init->ring_size;
371 dev_priv->ring.map.type = _DRM_AGP;
372 dev_priv->ring.map.flags = 0;
373 dev_priv->ring.map.mtrr = 0;
374
375 drm_core_ioremap(&dev_priv->ring.map, dev);
376
377 if (dev_priv->ring.map.handle == NULL) {
378 dev->dev_private = (void *)dev_priv;
379 i810_dma_cleanup(dev);
380 DRM_ERROR("can not ioremap virtual address for"
381 " ring buffer\n");
382 return -ENOMEM;
383 }
384
385 dev_priv->ring.virtual_start = dev_priv->ring.map.handle;
386
387 dev_priv->ring.tail_mask = dev_priv->ring.Size - 1;
388
389 dev_priv->w = init->w;
390 dev_priv->h = init->h;
391 dev_priv->pitch = init->pitch;
392 dev_priv->back_offset = init->back_offset;
393 dev_priv->depth_offset = init->depth_offset;
394 dev_priv->front_offset = init->front_offset;
395
396 dev_priv->overlay_offset = init->overlay_offset;
397 dev_priv->overlay_physical = init->overlay_physical;
398
399 dev_priv->front_di1 = init->front_offset | init->pitch_bits;
400 dev_priv->back_di1 = init->back_offset | init->pitch_bits;
401 dev_priv->zi1 = init->depth_offset | init->pitch_bits;
402
403 /* Program Hardware Status Page */
404 dev_priv->hw_status_page =
405 pci_alloc_consistent(dev->pdev, PAGE_SIZE,
406 &dev_priv->dma_status_page);
407 if (!dev_priv->hw_status_page) {
408 dev->dev_private = (void *)dev_priv;
409 i810_dma_cleanup(dev);
410 DRM_ERROR("Can not allocate hardware status page\n");
411 return -ENOMEM;
412 }
413 memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
414 DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page);
415
416 I810_WRITE(0x02080, dev_priv->dma_status_page);
417 DRM_DEBUG("Enabled hardware status page\n");
418
419 /* Now we need to init our freelist */
420 if (i810_freelist_init(dev, dev_priv) != 0) {
421 dev->dev_private = (void *)dev_priv;
422 i810_dma_cleanup(dev);
423 DRM_ERROR("Not enough space in the status page for"
424 " the freelist\n");
425 return -ENOMEM;
426 }
427 dev->dev_private = (void *)dev_priv;
428
429 return 0;
430}
431
432static int i810_dma_init(struct drm_device *dev, void *data,
433 struct drm_file *file_priv)
434{
435 drm_i810_private_t *dev_priv;
436 drm_i810_init_t *init = data;
437 int retcode = 0;
438
439 switch (init->func) {
440 case I810_INIT_DMA_1_4:
441 DRM_INFO("Using v1.4 init.\n");
442 dev_priv = drm_alloc(sizeof(drm_i810_private_t),
443 DRM_MEM_DRIVER);
444 if (dev_priv == NULL)
445 return -ENOMEM;
446 retcode = i810_dma_initialize(dev, dev_priv, init);
447 break;
448
449 case I810_CLEANUP_DMA:
450 DRM_INFO("DMA Cleanup\n");
451 retcode = i810_dma_cleanup(dev);
452 break;
453 default:
454 return -EINVAL;
455 }
456
457 return retcode;
458}
459
460/* Most efficient way to verify state for the i810 is as it is
461 * emitted. Non-conformant state is silently dropped.
462 *
463 * Use 'volatile' & local var tmp to force the emitted values to be
464 * identical to the verified ones.
465 */
466static void i810EmitContextVerified(struct drm_device * dev,
467 volatile unsigned int *code)
468{
469 drm_i810_private_t *dev_priv = dev->dev_private;
470 int i, j = 0;
471 unsigned int tmp;
472 RING_LOCALS;
473
474 BEGIN_LP_RING(I810_CTX_SETUP_SIZE);
475
476 OUT_RING(GFX_OP_COLOR_FACTOR);
477 OUT_RING(code[I810_CTXREG_CF1]);
478
479 OUT_RING(GFX_OP_STIPPLE);
480 OUT_RING(code[I810_CTXREG_ST1]);
481
482 for (i = 4; i < I810_CTX_SETUP_SIZE; i++) {
483 tmp = code[i];
484
485 if ((tmp & (7 << 29)) == (3 << 29) &&
486 (tmp & (0x1f << 24)) < (0x1d << 24)) {
487 OUT_RING(tmp);
488 j++;
489 } else
490 printk("constext state dropped!!!\n");
491 }
492
493 if (j & 1)
494 OUT_RING(0);
495
496 ADVANCE_LP_RING();
497}
498
499static void i810EmitTexVerified(struct drm_device * dev, volatile unsigned int *code)
500{
501 drm_i810_private_t *dev_priv = dev->dev_private;
502 int i, j = 0;
503 unsigned int tmp;
504 RING_LOCALS;
505
506 BEGIN_LP_RING(I810_TEX_SETUP_SIZE);
507
508 OUT_RING(GFX_OP_MAP_INFO);
509 OUT_RING(code[I810_TEXREG_MI1]);
510 OUT_RING(code[I810_TEXREG_MI2]);
511 OUT_RING(code[I810_TEXREG_MI3]);
512
513 for (i = 4; i < I810_TEX_SETUP_SIZE; i++) {
514 tmp = code[i];
515
516 if ((tmp & (7 << 29)) == (3 << 29) &&
517 (tmp & (0x1f << 24)) < (0x1d << 24)) {
518 OUT_RING(tmp);
519 j++;
520 } else
521 printk("texture state dropped!!!\n");
522 }
523
524 if (j & 1)
525 OUT_RING(0);
526
527 ADVANCE_LP_RING();
528}
529
530/* Need to do some additional checking when setting the dest buffer.
531 */
532static void i810EmitDestVerified(struct drm_device * dev,
533 volatile unsigned int *code)
534{
535 drm_i810_private_t *dev_priv = dev->dev_private;
536 unsigned int tmp;
537 RING_LOCALS;
538
539 BEGIN_LP_RING(I810_DEST_SETUP_SIZE + 2);
540
541 tmp = code[I810_DESTREG_DI1];
542 if (tmp == dev_priv->front_di1 || tmp == dev_priv->back_di1) {
543 OUT_RING(CMD_OP_DESTBUFFER_INFO);
544 OUT_RING(tmp);
545 } else
546 DRM_DEBUG("bad di1 %x (allow %x or %x)\n",
547 tmp, dev_priv->front_di1, dev_priv->back_di1);
548
549 /* invarient:
550 */
551 OUT_RING(CMD_OP_Z_BUFFER_INFO);
552 OUT_RING(dev_priv->zi1);
553
554 OUT_RING(GFX_OP_DESTBUFFER_VARS);
555 OUT_RING(code[I810_DESTREG_DV1]);
556
557 OUT_RING(GFX_OP_DRAWRECT_INFO);
558 OUT_RING(code[I810_DESTREG_DR1]);
559 OUT_RING(code[I810_DESTREG_DR2]);
560 OUT_RING(code[I810_DESTREG_DR3]);
561 OUT_RING(code[I810_DESTREG_DR4]);
562 OUT_RING(0);
563
564 ADVANCE_LP_RING();
565}
566
567static void i810EmitState(struct drm_device * dev)
568{
569 drm_i810_private_t *dev_priv = dev->dev_private;
570 drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv;
571 unsigned int dirty = sarea_priv->dirty;
572
573 DRM_DEBUG("%x\n", dirty);
574
575 if (dirty & I810_UPLOAD_BUFFERS) {
576 i810EmitDestVerified(dev, sarea_priv->BufferState);
577 sarea_priv->dirty &= ~I810_UPLOAD_BUFFERS;
578 }
579
580 if (dirty & I810_UPLOAD_CTX) {
581 i810EmitContextVerified(dev, sarea_priv->ContextState);
582 sarea_priv->dirty &= ~I810_UPLOAD_CTX;
583 }
584
585 if (dirty & I810_UPLOAD_TEX0) {
586 i810EmitTexVerified(dev, sarea_priv->TexState[0]);
587 sarea_priv->dirty &= ~I810_UPLOAD_TEX0;
588 }
589
590 if (dirty & I810_UPLOAD_TEX1) {
591 i810EmitTexVerified(dev, sarea_priv->TexState[1]);
592 sarea_priv->dirty &= ~I810_UPLOAD_TEX1;
593 }
594}
595
596/* need to verify
597 */
598static void i810_dma_dispatch_clear(struct drm_device * dev, int flags,
599 unsigned int clear_color,
600 unsigned int clear_zval)
601{
602 drm_i810_private_t *dev_priv = dev->dev_private;
603 drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv;
604 int nbox = sarea_priv->nbox;
605 struct drm_clip_rect *pbox = sarea_priv->boxes;
606 int pitch = dev_priv->pitch;
607 int cpp = 2;
608 int i;
609 RING_LOCALS;
610
611 if (dev_priv->current_page == 1) {
612 unsigned int tmp = flags;
613
614 flags &= ~(I810_FRONT | I810_BACK);
615 if (tmp & I810_FRONT)
616 flags |= I810_BACK;
617 if (tmp & I810_BACK)
618 flags |= I810_FRONT;
619 }
620
621 i810_kernel_lost_context(dev);
622
623 if (nbox > I810_NR_SAREA_CLIPRECTS)
624 nbox = I810_NR_SAREA_CLIPRECTS;
625
626 for (i = 0; i < nbox; i++, pbox++) {
627 unsigned int x = pbox->x1;
628 unsigned int y = pbox->y1;
629 unsigned int width = (pbox->x2 - x) * cpp;
630 unsigned int height = pbox->y2 - y;
631 unsigned int start = y * pitch + x * cpp;
632
633 if (pbox->x1 > pbox->x2 ||
634 pbox->y1 > pbox->y2 ||
635 pbox->x2 > dev_priv->w || pbox->y2 > dev_priv->h)
636 continue;
637
638 if (flags & I810_FRONT) {
639 BEGIN_LP_RING(6);
640 OUT_RING(BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3);
641 OUT_RING(BR13_SOLID_PATTERN | (0xF0 << 16) | pitch);
642 OUT_RING((height << 16) | width);
643 OUT_RING(start);
644 OUT_RING(clear_color);
645 OUT_RING(0);
646 ADVANCE_LP_RING();
647 }
648
649 if (flags & I810_BACK) {
650 BEGIN_LP_RING(6);
651 OUT_RING(BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3);
652 OUT_RING(BR13_SOLID_PATTERN | (0xF0 << 16) | pitch);
653 OUT_RING((height << 16) | width);
654 OUT_RING(dev_priv->back_offset + start);
655 OUT_RING(clear_color);
656 OUT_RING(0);
657 ADVANCE_LP_RING();
658 }
659
660 if (flags & I810_DEPTH) {
661 BEGIN_LP_RING(6);
662 OUT_RING(BR00_BITBLT_CLIENT | BR00_OP_COLOR_BLT | 0x3);
663 OUT_RING(BR13_SOLID_PATTERN | (0xF0 << 16) | pitch);
664 OUT_RING((height << 16) | width);
665 OUT_RING(dev_priv->depth_offset + start);
666 OUT_RING(clear_zval);
667 OUT_RING(0);
668 ADVANCE_LP_RING();
669 }
670 }
671}
672
673static void i810_dma_dispatch_swap(struct drm_device * dev)
674{
675 drm_i810_private_t *dev_priv = dev->dev_private;
676 drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv;
677 int nbox = sarea_priv->nbox;
678 struct drm_clip_rect *pbox = sarea_priv->boxes;
679 int pitch = dev_priv->pitch;
680 int cpp = 2;
681 int i;
682 RING_LOCALS;
683
684 DRM_DEBUG("swapbuffers\n");
685
686 i810_kernel_lost_context(dev);
687
688 if (nbox > I810_NR_SAREA_CLIPRECTS)
689 nbox = I810_NR_SAREA_CLIPRECTS;
690
691 for (i = 0; i < nbox; i++, pbox++) {
692 unsigned int w = pbox->x2 - pbox->x1;
693 unsigned int h = pbox->y2 - pbox->y1;
694 unsigned int dst = pbox->x1 * cpp + pbox->y1 * pitch;
695 unsigned int start = dst;
696
697 if (pbox->x1 > pbox->x2 ||
698 pbox->y1 > pbox->y2 ||
699 pbox->x2 > dev_priv->w || pbox->y2 > dev_priv->h)
700 continue;
701
702 BEGIN_LP_RING(6);
703 OUT_RING(BR00_BITBLT_CLIENT | BR00_OP_SRC_COPY_BLT | 0x4);
704 OUT_RING(pitch | (0xCC << 16));
705 OUT_RING((h << 16) | (w * cpp));
706 if (dev_priv->current_page == 0)
707 OUT_RING(dev_priv->front_offset + start);
708 else
709 OUT_RING(dev_priv->back_offset + start);
710 OUT_RING(pitch);
711 if (dev_priv->current_page == 0)
712 OUT_RING(dev_priv->back_offset + start);
713 else
714 OUT_RING(dev_priv->front_offset + start);
715 ADVANCE_LP_RING();
716 }
717}
718
719static void i810_dma_dispatch_vertex(struct drm_device * dev,
720 struct drm_buf * buf, int discard, int used)
721{
722 drm_i810_private_t *dev_priv = dev->dev_private;
723 drm_i810_buf_priv_t *buf_priv = buf->dev_private;
724 drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv;
725 struct drm_clip_rect *box = sarea_priv->boxes;
726 int nbox = sarea_priv->nbox;
727 unsigned long address = (unsigned long)buf->bus_address;
728 unsigned long start = address - dev->agp->base;
729 int i = 0;
730 RING_LOCALS;
731
732 i810_kernel_lost_context(dev);
733
734 if (nbox > I810_NR_SAREA_CLIPRECTS)
735 nbox = I810_NR_SAREA_CLIPRECTS;
736
737 if (used > 4 * 1024)
738 used = 0;
739
740 if (sarea_priv->dirty)
741 i810EmitState(dev);
742
743 if (buf_priv->currently_mapped == I810_BUF_MAPPED) {
744 unsigned int prim = (sarea_priv->vertex_prim & PR_MASK);
745
746 *(u32 *) buf_priv->kernel_virtual =
747 ((GFX_OP_PRIMITIVE | prim | ((used / 4) - 2)));
748
749 if (used & 4) {
750 *(u32 *) ((char *) buf_priv->kernel_virtual + used) = 0;
751 used += 4;
752 }
753
754 i810_unmap_buffer(buf);
755 }
756
757 if (used) {
758 do {
759 if (i < nbox) {
760 BEGIN_LP_RING(4);
761 OUT_RING(GFX_OP_SCISSOR | SC_UPDATE_SCISSOR |
762 SC_ENABLE);
763 OUT_RING(GFX_OP_SCISSOR_INFO);
764 OUT_RING(box[i].x1 | (box[i].y1 << 16));
765 OUT_RING((box[i].x2 -
766 1) | ((box[i].y2 - 1) << 16));
767 ADVANCE_LP_RING();
768 }
769
770 BEGIN_LP_RING(4);
771 OUT_RING(CMD_OP_BATCH_BUFFER);
772 OUT_RING(start | BB1_PROTECTED);
773 OUT_RING(start + used - 4);
774 OUT_RING(0);
775 ADVANCE_LP_RING();
776
777 } while (++i < nbox);
778 }
779
780 if (discard) {
781 dev_priv->counter++;
782
783 (void)cmpxchg(buf_priv->in_use, I810_BUF_CLIENT,
784 I810_BUF_HARDWARE);
785
786 BEGIN_LP_RING(8);
787 OUT_RING(CMD_STORE_DWORD_IDX);
788 OUT_RING(20);
789 OUT_RING(dev_priv->counter);
790 OUT_RING(CMD_STORE_DWORD_IDX);
791 OUT_RING(buf_priv->my_use_idx);
792 OUT_RING(I810_BUF_FREE);
793 OUT_RING(CMD_REPORT_HEAD);
794 OUT_RING(0);
795 ADVANCE_LP_RING();
796 }
797}
798
799static void i810_dma_dispatch_flip(struct drm_device * dev)
800{
801 drm_i810_private_t *dev_priv = dev->dev_private;
802 int pitch = dev_priv->pitch;
803 RING_LOCALS;
804
805 DRM_DEBUG("page=%d pfCurrentPage=%d\n",
806 dev_priv->current_page,
807 dev_priv->sarea_priv->pf_current_page);
808
809 i810_kernel_lost_context(dev);
810
811 BEGIN_LP_RING(2);
812 OUT_RING(INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE);
813 OUT_RING(0);
814 ADVANCE_LP_RING();
815
816 BEGIN_LP_RING(I810_DEST_SETUP_SIZE + 2);
817 /* On i815 at least ASYNC is buggy */
818 /* pitch<<5 is from 11.2.8 p158,
819 its the pitch / 8 then left shifted 8,
820 so (pitch >> 3) << 8 */
821 OUT_RING(CMD_OP_FRONTBUFFER_INFO | (pitch << 5) /*| ASYNC_FLIP */ );
822 if (dev_priv->current_page == 0) {
823 OUT_RING(dev_priv->back_offset);
824 dev_priv->current_page = 1;
825 } else {
826 OUT_RING(dev_priv->front_offset);
827 dev_priv->current_page = 0;
828 }
829 OUT_RING(0);
830 ADVANCE_LP_RING();
831
832 BEGIN_LP_RING(2);
833 OUT_RING(CMD_OP_WAIT_FOR_EVENT | WAIT_FOR_PLANE_A_FLIP);
834 OUT_RING(0);
835 ADVANCE_LP_RING();
836
837 /* Increment the frame counter. The client-side 3D driver must
838 * throttle the framerate by waiting for this value before
839 * performing the swapbuffer ioctl.
840 */
841 dev_priv->sarea_priv->pf_current_page = dev_priv->current_page;
842
843}
844
845static void i810_dma_quiescent(struct drm_device * dev)
846{
847 drm_i810_private_t *dev_priv = dev->dev_private;
848 RING_LOCALS;
849
850 i810_kernel_lost_context(dev);
851
852 BEGIN_LP_RING(4);
853 OUT_RING(INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE);
854 OUT_RING(CMD_REPORT_HEAD);
855 OUT_RING(0);
856 OUT_RING(0);
857 ADVANCE_LP_RING();
858
859 i810_wait_ring(dev, dev_priv->ring.Size - 8);
860}
861
862static int i810_flush_queue(struct drm_device * dev)
863{
864 drm_i810_private_t *dev_priv = dev->dev_private;
865 struct drm_device_dma *dma = dev->dma;
866 int i, ret = 0;
867 RING_LOCALS;
868
869 i810_kernel_lost_context(dev);
870
871 BEGIN_LP_RING(2);
872 OUT_RING(CMD_REPORT_HEAD);
873 OUT_RING(0);
874 ADVANCE_LP_RING();
875
876 i810_wait_ring(dev, dev_priv->ring.Size - 8);
877
878 for (i = 0; i < dma->buf_count; i++) {
879 struct drm_buf *buf = dma->buflist[i];
880 drm_i810_buf_priv_t *buf_priv = buf->dev_private;
881
882 int used = cmpxchg(buf_priv->in_use, I810_BUF_HARDWARE,
883 I810_BUF_FREE);
884
885 if (used == I810_BUF_HARDWARE)
886 DRM_DEBUG("reclaimed from HARDWARE\n");
887 if (used == I810_BUF_CLIENT)
888 DRM_DEBUG("still on client\n");
889 }
890
891 return ret;
892}
893
894/* Must be called with the lock held */
895static void i810_reclaim_buffers(struct drm_device * dev,
896 struct drm_file *file_priv)
897{
898 struct drm_device_dma *dma = dev->dma;
899 int i;
900
901 if (!dma)
902 return;
903 if (!dev->dev_private)
904 return;
905 if (!dma->buflist)
906 return;
907
908 i810_flush_queue(dev);
909
910 for (i = 0; i < dma->buf_count; i++) {
911 struct drm_buf *buf = dma->buflist[i];
912 drm_i810_buf_priv_t *buf_priv = buf->dev_private;
913
914 if (buf->file_priv == file_priv && buf_priv) {
915 int used = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT,
916 I810_BUF_FREE);
917
918 if (used == I810_BUF_CLIENT)
919 DRM_DEBUG("reclaimed from client\n");
920 if (buf_priv->currently_mapped == I810_BUF_MAPPED)
921 buf_priv->currently_mapped = I810_BUF_UNMAPPED;
922 }
923 }
924}
925
926static int i810_flush_ioctl(struct drm_device *dev, void *data,
927 struct drm_file *file_priv)
928{
929 LOCK_TEST_WITH_RETURN(dev, file_priv);
930
931 i810_flush_queue(dev);
932 return 0;
933}
934
935static int i810_dma_vertex(struct drm_device *dev, void *data,
936 struct drm_file *file_priv)
937{
938 struct drm_device_dma *dma = dev->dma;
939 drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private;
940 u32 *hw_status = dev_priv->hw_status_page;
941 drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *)
942 dev_priv->sarea_priv;
943 drm_i810_vertex_t *vertex = data;
944
945 LOCK_TEST_WITH_RETURN(dev, file_priv);
946
947 DRM_DEBUG("idx %d used %d discard %d\n",
948 vertex->idx, vertex->used, vertex->discard);
949
950 if (vertex->idx < 0 || vertex->idx > dma->buf_count)
951 return -EINVAL;
952
953 i810_dma_dispatch_vertex(dev,
954 dma->buflist[vertex->idx],
955 vertex->discard, vertex->used);
956
957 atomic_add(vertex->used, &dev->counts[_DRM_STAT_SECONDARY]);
958 atomic_inc(&dev->counts[_DRM_STAT_DMA]);
959 sarea_priv->last_enqueue = dev_priv->counter - 1;
960 sarea_priv->last_dispatch = (int)hw_status[5];
961
962 return 0;
963}
964
965static int i810_clear_bufs(struct drm_device *dev, void *data,
966 struct drm_file *file_priv)
967{
968 drm_i810_clear_t *clear = data;
969
970 LOCK_TEST_WITH_RETURN(dev, file_priv);
971
972 /* GH: Someone's doing nasty things... */
973 if (!dev->dev_private) {
974 return -EINVAL;
975 }
976
977 i810_dma_dispatch_clear(dev, clear->flags,
978 clear->clear_color, clear->clear_depth);
979 return 0;
980}
981
982static int i810_swap_bufs(struct drm_device *dev, void *data,
983 struct drm_file *file_priv)
984{
985 DRM_DEBUG("\n");
986
987 LOCK_TEST_WITH_RETURN(dev, file_priv);
988
989 i810_dma_dispatch_swap(dev);
990 return 0;
991}
992
993static int i810_getage(struct drm_device *dev, void *data,
994 struct drm_file *file_priv)
995{
996 drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private;
997 u32 *hw_status = dev_priv->hw_status_page;
998 drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *)
999 dev_priv->sarea_priv;
1000
1001 sarea_priv->last_dispatch = (int)hw_status[5];
1002 return 0;
1003}
1004
1005static int i810_getbuf(struct drm_device *dev, void *data,
1006 struct drm_file *file_priv)
1007{
1008 int retcode = 0;
1009 drm_i810_dma_t *d = data;
1010 drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private;
1011 u32 *hw_status = dev_priv->hw_status_page;
1012 drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *)
1013 dev_priv->sarea_priv;
1014
1015 LOCK_TEST_WITH_RETURN(dev, file_priv);
1016
1017 d->granted = 0;
1018
1019 retcode = i810_dma_get_buffer(dev, d, file_priv);
1020
1021 DRM_DEBUG("i810_dma: %d returning %d, granted = %d\n",
1022 task_pid_nr(current), retcode, d->granted);
1023
1024 sarea_priv->last_dispatch = (int)hw_status[5];
1025
1026 return retcode;
1027}
1028
1029static int i810_copybuf(struct drm_device *dev, void *data,
1030 struct drm_file *file_priv)
1031{
1032 /* Never copy - 2.4.x doesn't need it */
1033 return 0;
1034}
1035
1036static int i810_docopy(struct drm_device *dev, void *data,
1037 struct drm_file *file_priv)
1038{
1039 /* Never copy - 2.4.x doesn't need it */
1040 return 0;
1041}
1042
1043static void i810_dma_dispatch_mc(struct drm_device * dev, struct drm_buf * buf, int used,
1044 unsigned int last_render)
1045{
1046 drm_i810_private_t *dev_priv = dev->dev_private;
1047 drm_i810_buf_priv_t *buf_priv = buf->dev_private;
1048 drm_i810_sarea_t *sarea_priv = dev_priv->sarea_priv;
1049 unsigned long address = (unsigned long)buf->bus_address;
1050 unsigned long start = address - dev->agp->base;
1051 int u;
1052 RING_LOCALS;
1053
1054 i810_kernel_lost_context(dev);
1055
1056 u = cmpxchg(buf_priv->in_use, I810_BUF_CLIENT, I810_BUF_HARDWARE);
1057 if (u != I810_BUF_CLIENT) {
1058 DRM_DEBUG("MC found buffer that isn't mine!\n");
1059 }
1060
1061 if (used > 4 * 1024)
1062 used = 0;
1063
1064 sarea_priv->dirty = 0x7f;
1065
1066 DRM_DEBUG("addr 0x%lx, used 0x%x\n", address, used);
1067
1068 dev_priv->counter++;
1069 DRM_DEBUG("dispatch counter : %ld\n", dev_priv->counter);
1070 DRM_DEBUG("start : %lx\n", start);
1071 DRM_DEBUG("used : %d\n", used);
1072 DRM_DEBUG("start + used - 4 : %ld\n", start + used - 4);
1073
1074 if (buf_priv->currently_mapped == I810_BUF_MAPPED) {
1075 if (used & 4) {
1076 *(u32 *) ((char *) buf_priv->virtual + used) = 0;
1077 used += 4;
1078 }
1079
1080 i810_unmap_buffer(buf);
1081 }
1082 BEGIN_LP_RING(4);
1083 OUT_RING(CMD_OP_BATCH_BUFFER);
1084 OUT_RING(start | BB1_PROTECTED);
1085 OUT_RING(start + used - 4);
1086 OUT_RING(0);
1087 ADVANCE_LP_RING();
1088
1089 BEGIN_LP_RING(8);
1090 OUT_RING(CMD_STORE_DWORD_IDX);
1091 OUT_RING(buf_priv->my_use_idx);
1092 OUT_RING(I810_BUF_FREE);
1093 OUT_RING(0);
1094
1095 OUT_RING(CMD_STORE_DWORD_IDX);
1096 OUT_RING(16);
1097 OUT_RING(last_render);
1098 OUT_RING(0);
1099 ADVANCE_LP_RING();
1100}
1101
1102static int i810_dma_mc(struct drm_device *dev, void *data,
1103 struct drm_file *file_priv)
1104{
1105 struct drm_device_dma *dma = dev->dma;
1106 drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private;
1107 u32 *hw_status = dev_priv->hw_status_page;
1108 drm_i810_sarea_t *sarea_priv = (drm_i810_sarea_t *)
1109 dev_priv->sarea_priv;
1110 drm_i810_mc_t *mc = data;
1111
1112 LOCK_TEST_WITH_RETURN(dev, file_priv);
1113
1114 if (mc->idx >= dma->buf_count || mc->idx < 0)
1115 return -EINVAL;
1116
1117 i810_dma_dispatch_mc(dev, dma->buflist[mc->idx], mc->used,
1118 mc->last_render);
1119
1120 atomic_add(mc->used, &dev->counts[_DRM_STAT_SECONDARY]);
1121 atomic_inc(&dev->counts[_DRM_STAT_DMA]);
1122 sarea_priv->last_enqueue = dev_priv->counter - 1;
1123 sarea_priv->last_dispatch = (int)hw_status[5];
1124
1125 return 0;
1126}
1127
1128static int i810_rstatus(struct drm_device *dev, void *data,
1129 struct drm_file *file_priv)
1130{
1131 drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private;
1132
1133 return (int)(((u32 *) (dev_priv->hw_status_page))[4]);
1134}
1135
1136static int i810_ov0_info(struct drm_device *dev, void *data,
1137 struct drm_file *file_priv)
1138{
1139 drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private;
1140 drm_i810_overlay_t *ov = data;
1141
1142 ov->offset = dev_priv->overlay_offset;
1143 ov->physical = dev_priv->overlay_physical;
1144
1145 return 0;
1146}
1147
1148static int i810_fstatus(struct drm_device *dev, void *data,
1149 struct drm_file *file_priv)
1150{
1151 drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private;
1152
1153 LOCK_TEST_WITH_RETURN(dev, file_priv);
1154 return I810_READ(0x30008);
1155}
1156
1157static int i810_ov0_flip(struct drm_device *dev, void *data,
1158 struct drm_file *file_priv)
1159{
1160 drm_i810_private_t *dev_priv = (drm_i810_private_t *) dev->dev_private;
1161
1162 LOCK_TEST_WITH_RETURN(dev, file_priv);
1163
1164 //Tell the overlay to update
1165 I810_WRITE(0x30000, dev_priv->overlay_physical | 0x80000000);
1166
1167 return 0;
1168}
1169
1170/* Not sure why this isn't set all the time:
1171 */
1172static void i810_do_init_pageflip(struct drm_device * dev)
1173{
1174 drm_i810_private_t *dev_priv = dev->dev_private;
1175
1176 DRM_DEBUG("\n");
1177 dev_priv->page_flipping = 1;
1178 dev_priv->current_page = 0;
1179 dev_priv->sarea_priv->pf_current_page = dev_priv->current_page;
1180}
1181
1182static int i810_do_cleanup_pageflip(struct drm_device * dev)
1183{
1184 drm_i810_private_t *dev_priv = dev->dev_private;
1185
1186 DRM_DEBUG("\n");
1187 if (dev_priv->current_page != 0)
1188 i810_dma_dispatch_flip(dev);
1189
1190 dev_priv->page_flipping = 0;
1191 return 0;
1192}
1193
1194static int i810_flip_bufs(struct drm_device *dev, void *data,
1195 struct drm_file *file_priv)
1196{
1197 drm_i810_private_t *dev_priv = dev->dev_private;
1198
1199 DRM_DEBUG("\n");
1200
1201 LOCK_TEST_WITH_RETURN(dev, file_priv);
1202
1203 if (!dev_priv->page_flipping)
1204 i810_do_init_pageflip(dev);
1205
1206 i810_dma_dispatch_flip(dev);
1207 return 0;
1208}
1209
1210int i810_driver_load(struct drm_device *dev, unsigned long flags)
1211{
1212 /* i810 has 4 more counters */
1213 dev->counters += 4;
1214 dev->types[6] = _DRM_STAT_IRQ;
1215 dev->types[7] = _DRM_STAT_PRIMARY;
1216 dev->types[8] = _DRM_STAT_SECONDARY;
1217 dev->types[9] = _DRM_STAT_DMA;
1218
1219 return 0;
1220}
1221
1222void i810_driver_lastclose(struct drm_device * dev)
1223{
1224 i810_dma_cleanup(dev);
1225}
1226
1227void i810_driver_preclose(struct drm_device * dev, struct drm_file *file_priv)
1228{
1229 if (dev->dev_private) {
1230 drm_i810_private_t *dev_priv = dev->dev_private;
1231 if (dev_priv->page_flipping) {
1232 i810_do_cleanup_pageflip(dev);
1233 }
1234 }
1235}
1236
1237void i810_driver_reclaim_buffers_locked(struct drm_device * dev,
1238 struct drm_file *file_priv)
1239{
1240 i810_reclaim_buffers(dev, file_priv);
1241}
1242
1243int i810_driver_dma_quiescent(struct drm_device * dev)
1244{
1245 i810_dma_quiescent(dev);
1246 return 0;
1247}
1248
1249struct drm_ioctl_desc i810_ioctls[] = {
1250 DRM_IOCTL_DEF(DRM_I810_INIT, i810_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
1251 DRM_IOCTL_DEF(DRM_I810_VERTEX, i810_dma_vertex, DRM_AUTH),
1252 DRM_IOCTL_DEF(DRM_I810_CLEAR, i810_clear_bufs, DRM_AUTH),
1253 DRM_IOCTL_DEF(DRM_I810_FLUSH, i810_flush_ioctl, DRM_AUTH),
1254 DRM_IOCTL_DEF(DRM_I810_GETAGE, i810_getage, DRM_AUTH),
1255 DRM_IOCTL_DEF(DRM_I810_GETBUF, i810_getbuf, DRM_AUTH),
1256 DRM_IOCTL_DEF(DRM_I810_SWAP, i810_swap_bufs, DRM_AUTH),
1257 DRM_IOCTL_DEF(DRM_I810_COPY, i810_copybuf, DRM_AUTH),
1258 DRM_IOCTL_DEF(DRM_I810_DOCOPY, i810_docopy, DRM_AUTH),
1259 DRM_IOCTL_DEF(DRM_I810_OV0INFO, i810_ov0_info, DRM_AUTH),
1260 DRM_IOCTL_DEF(DRM_I810_FSTATUS, i810_fstatus, DRM_AUTH),
1261 DRM_IOCTL_DEF(DRM_I810_OV0FLIP, i810_ov0_flip, DRM_AUTH),
1262 DRM_IOCTL_DEF(DRM_I810_MC, i810_dma_mc, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
1263 DRM_IOCTL_DEF(DRM_I810_RSTATUS, i810_rstatus, DRM_AUTH),
1264 DRM_IOCTL_DEF(DRM_I810_FLIP, i810_flip_bufs, DRM_AUTH)
1265};
1266
1267int i810_max_ioctl = DRM_ARRAY_SIZE(i810_ioctls);
1268
1269/**
1270 * Determine if the device really is AGP or not.
1271 *
1272 * All Intel graphics chipsets are treated as AGP, even if they are really
1273 * PCI-e.
1274 *
1275 * \param dev The device to be tested.
1276 *
1277 * \returns
1278 * A value of 1 is always retured to indictate every i810 is AGP.
1279 */
1280int i810_driver_device_is_agp(struct drm_device * dev)
1281{
1282 return 1;
1283}
diff --git a/drivers/char/drm/i810_drm.h b/drivers/char/drm/i810_drm.h
deleted file mode 100644
index 7a10bb6f2c0f..000000000000
--- a/drivers/char/drm/i810_drm.h
+++ /dev/null
@@ -1,281 +0,0 @@
1#ifndef _I810_DRM_H_
2#define _I810_DRM_H_
3
4/* WARNING: These defines must be the same as what the Xserver uses.
5 * if you change them, you must change the defines in the Xserver.
6 */
7
8#ifndef _I810_DEFINES_
9#define _I810_DEFINES_
10
11#define I810_DMA_BUF_ORDER 12
12#define I810_DMA_BUF_SZ (1<<I810_DMA_BUF_ORDER)
13#define I810_DMA_BUF_NR 256
14#define I810_NR_SAREA_CLIPRECTS 8
15
16/* Each region is a minimum of 64k, and there are at most 64 of them.
17 */
18#define I810_NR_TEX_REGIONS 64
19#define I810_LOG_MIN_TEX_REGION_SIZE 16
20#endif
21
22#define I810_UPLOAD_TEX0IMAGE 0x1 /* handled clientside */
23#define I810_UPLOAD_TEX1IMAGE 0x2 /* handled clientside */
24#define I810_UPLOAD_CTX 0x4
25#define I810_UPLOAD_BUFFERS 0x8
26#define I810_UPLOAD_TEX0 0x10
27#define I810_UPLOAD_TEX1 0x20
28#define I810_UPLOAD_CLIPRECTS 0x40
29
30/* Indices into buf.Setup where various bits of state are mirrored per
31 * context and per buffer. These can be fired at the card as a unit,
32 * or in a piecewise fashion as required.
33 */
34
35/* Destbuffer state
36 * - backbuffer linear offset and pitch -- invarient in the current dri
37 * - zbuffer linear offset and pitch -- also invarient
38 * - drawing origin in back and depth buffers.
39 *
40 * Keep the depth/back buffer state here to accommodate private buffers
41 * in the future.
42 */
43#define I810_DESTREG_DI0 0 /* CMD_OP_DESTBUFFER_INFO (2 dwords) */
44#define I810_DESTREG_DI1 1
45#define I810_DESTREG_DV0 2 /* GFX_OP_DESTBUFFER_VARS (2 dwords) */
46#define I810_DESTREG_DV1 3
47#define I810_DESTREG_DR0 4 /* GFX_OP_DRAWRECT_INFO (4 dwords) */
48#define I810_DESTREG_DR1 5
49#define I810_DESTREG_DR2 6
50#define I810_DESTREG_DR3 7
51#define I810_DESTREG_DR4 8
52#define I810_DEST_SETUP_SIZE 10
53
54/* Context state
55 */
56#define I810_CTXREG_CF0 0 /* GFX_OP_COLOR_FACTOR */
57#define I810_CTXREG_CF1 1
58#define I810_CTXREG_ST0 2 /* GFX_OP_STIPPLE */
59#define I810_CTXREG_ST1 3
60#define I810_CTXREG_VF 4 /* GFX_OP_VERTEX_FMT */
61#define I810_CTXREG_MT 5 /* GFX_OP_MAP_TEXELS */
62#define I810_CTXREG_MC0 6 /* GFX_OP_MAP_COLOR_STAGES - stage 0 */
63#define I810_CTXREG_MC1 7 /* GFX_OP_MAP_COLOR_STAGES - stage 1 */
64#define I810_CTXREG_MC2 8 /* GFX_OP_MAP_COLOR_STAGES - stage 2 */
65#define I810_CTXREG_MA0 9 /* GFX_OP_MAP_ALPHA_STAGES - stage 0 */
66#define I810_CTXREG_MA1 10 /* GFX_OP_MAP_ALPHA_STAGES - stage 1 */
67#define I810_CTXREG_MA2 11 /* GFX_OP_MAP_ALPHA_STAGES - stage 2 */
68#define I810_CTXREG_SDM 12 /* GFX_OP_SRC_DEST_MONO */
69#define I810_CTXREG_FOG 13 /* GFX_OP_FOG_COLOR */
70#define I810_CTXREG_B1 14 /* GFX_OP_BOOL_1 */
71#define I810_CTXREG_B2 15 /* GFX_OP_BOOL_2 */
72#define I810_CTXREG_LCS 16 /* GFX_OP_LINEWIDTH_CULL_SHADE_MODE */
73#define I810_CTXREG_PV 17 /* GFX_OP_PV_RULE -- Invarient! */
74#define I810_CTXREG_ZA 18 /* GFX_OP_ZBIAS_ALPHAFUNC */
75#define I810_CTXREG_AA 19 /* GFX_OP_ANTIALIAS */
76#define I810_CTX_SETUP_SIZE 20
77
78/* Texture state (per tex unit)
79 */
80#define I810_TEXREG_MI0 0 /* GFX_OP_MAP_INFO (4 dwords) */
81#define I810_TEXREG_MI1 1
82#define I810_TEXREG_MI2 2
83#define I810_TEXREG_MI3 3
84#define I810_TEXREG_MF 4 /* GFX_OP_MAP_FILTER */
85#define I810_TEXREG_MLC 5 /* GFX_OP_MAP_LOD_CTL */
86#define I810_TEXREG_MLL 6 /* GFX_OP_MAP_LOD_LIMITS */
87#define I810_TEXREG_MCS 7 /* GFX_OP_MAP_COORD_SETS ??? */
88#define I810_TEX_SETUP_SIZE 8
89
90/* Flags for clear ioctl
91 */
92#define I810_FRONT 0x1
93#define I810_BACK 0x2
94#define I810_DEPTH 0x4
95
96typedef enum _drm_i810_init_func {
97 I810_INIT_DMA = 0x01,
98 I810_CLEANUP_DMA = 0x02,
99 I810_INIT_DMA_1_4 = 0x03
100} drm_i810_init_func_t;
101
102/* This is the init structure after v1.2 */
103typedef struct _drm_i810_init {
104 drm_i810_init_func_t func;
105 unsigned int mmio_offset;
106 unsigned int buffers_offset;
107 int sarea_priv_offset;
108 unsigned int ring_start;
109 unsigned int ring_end;
110 unsigned int ring_size;
111 unsigned int front_offset;
112 unsigned int back_offset;
113 unsigned int depth_offset;
114 unsigned int overlay_offset;
115 unsigned int overlay_physical;
116 unsigned int w;
117 unsigned int h;
118 unsigned int pitch;
119 unsigned int pitch_bits;
120} drm_i810_init_t;
121
122/* This is the init structure prior to v1.2 */
123typedef struct _drm_i810_pre12_init {
124 drm_i810_init_func_t func;
125 unsigned int mmio_offset;
126 unsigned int buffers_offset;
127 int sarea_priv_offset;
128 unsigned int ring_start;
129 unsigned int ring_end;
130 unsigned int ring_size;
131 unsigned int front_offset;
132 unsigned int back_offset;
133 unsigned int depth_offset;
134 unsigned int w;
135 unsigned int h;
136 unsigned int pitch;
137 unsigned int pitch_bits;
138} drm_i810_pre12_init_t;
139
140/* Warning: If you change the SAREA structure you must change the Xserver
141 * structure as well */
142
143typedef struct _drm_i810_tex_region {
144 unsigned char next, prev; /* indices to form a circular LRU */
145 unsigned char in_use; /* owned by a client, or free? */
146 int age; /* tracked by clients to update local LRU's */
147} drm_i810_tex_region_t;
148
149typedef struct _drm_i810_sarea {
150 unsigned int ContextState[I810_CTX_SETUP_SIZE];
151 unsigned int BufferState[I810_DEST_SETUP_SIZE];
152 unsigned int TexState[2][I810_TEX_SETUP_SIZE];
153 unsigned int dirty;
154
155 unsigned int nbox;
156 struct drm_clip_rect boxes[I810_NR_SAREA_CLIPRECTS];
157
158 /* Maintain an LRU of contiguous regions of texture space. If
159 * you think you own a region of texture memory, and it has an
160 * age different to the one you set, then you are mistaken and
161 * it has been stolen by another client. If global texAge
162 * hasn't changed, there is no need to walk the list.
163 *
164 * These regions can be used as a proxy for the fine-grained
165 * texture information of other clients - by maintaining them
166 * in the same lru which is used to age their own textures,
167 * clients have an approximate lru for the whole of global
168 * texture space, and can make informed decisions as to which
169 * areas to kick out. There is no need to choose whether to
170 * kick out your own texture or someone else's - simply eject
171 * them all in LRU order.
172 */
173
174 drm_i810_tex_region_t texList[I810_NR_TEX_REGIONS + 1];
175 /* Last elt is sentinal */
176 int texAge; /* last time texture was uploaded */
177 int last_enqueue; /* last time a buffer was enqueued */
178 int last_dispatch; /* age of the most recently dispatched buffer */
179 int last_quiescent; /* */
180 int ctxOwner; /* last context to upload state */
181
182 int vertex_prim;
183
184 int pf_enabled; /* is pageflipping allowed? */
185 int pf_active;
186 int pf_current_page; /* which buffer is being displayed? */
187} drm_i810_sarea_t;
188
189/* WARNING: If you change any of these defines, make sure to change the
190 * defines in the Xserver file (xf86drmMga.h)
191 */
192
193/* i810 specific ioctls
194 * The device specific ioctl range is 0x40 to 0x79.
195 */
196#define DRM_I810_INIT 0x00
197#define DRM_I810_VERTEX 0x01
198#define DRM_I810_CLEAR 0x02
199#define DRM_I810_FLUSH 0x03
200#define DRM_I810_GETAGE 0x04
201#define DRM_I810_GETBUF 0x05
202#define DRM_I810_SWAP 0x06
203#define DRM_I810_COPY 0x07
204#define DRM_I810_DOCOPY 0x08
205#define DRM_I810_OV0INFO 0x09
206#define DRM_I810_FSTATUS 0x0a
207#define DRM_I810_OV0FLIP 0x0b
208#define DRM_I810_MC 0x0c
209#define DRM_I810_RSTATUS 0x0d
210#define DRM_I810_FLIP 0x0e
211
212#define DRM_IOCTL_I810_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I810_INIT, drm_i810_init_t)
213#define DRM_IOCTL_I810_VERTEX DRM_IOW( DRM_COMMAND_BASE + DRM_I810_VERTEX, drm_i810_vertex_t)
214#define DRM_IOCTL_I810_CLEAR DRM_IOW( DRM_COMMAND_BASE + DRM_I810_CLEAR, drm_i810_clear_t)
215#define DRM_IOCTL_I810_FLUSH DRM_IO( DRM_COMMAND_BASE + DRM_I810_FLUSH)
216#define DRM_IOCTL_I810_GETAGE DRM_IO( DRM_COMMAND_BASE + DRM_I810_GETAGE)
217#define DRM_IOCTL_I810_GETBUF DRM_IOWR(DRM_COMMAND_BASE + DRM_I810_GETBUF, drm_i810_dma_t)
218#define DRM_IOCTL_I810_SWAP DRM_IO( DRM_COMMAND_BASE + DRM_I810_SWAP)
219#define DRM_IOCTL_I810_COPY DRM_IOW( DRM_COMMAND_BASE + DRM_I810_COPY, drm_i810_copy_t)
220#define DRM_IOCTL_I810_DOCOPY DRM_IO( DRM_COMMAND_BASE + DRM_I810_DOCOPY)
221#define DRM_IOCTL_I810_OV0INFO DRM_IOR( DRM_COMMAND_BASE + DRM_I810_OV0INFO, drm_i810_overlay_t)
222#define DRM_IOCTL_I810_FSTATUS DRM_IO ( DRM_COMMAND_BASE + DRM_I810_FSTATUS)
223#define DRM_IOCTL_I810_OV0FLIP DRM_IO ( DRM_COMMAND_BASE + DRM_I810_OV0FLIP)
224#define DRM_IOCTL_I810_MC DRM_IOW( DRM_COMMAND_BASE + DRM_I810_MC, drm_i810_mc_t)
225#define DRM_IOCTL_I810_RSTATUS DRM_IO ( DRM_COMMAND_BASE + DRM_I810_RSTATUS)
226#define DRM_IOCTL_I810_FLIP DRM_IO ( DRM_COMMAND_BASE + DRM_I810_FLIP)
227
228typedef struct _drm_i810_clear {
229 int clear_color;
230 int clear_depth;
231 int flags;
232} drm_i810_clear_t;
233
234/* These may be placeholders if we have more cliprects than
235 * I810_NR_SAREA_CLIPRECTS. In that case, the client sets discard to
236 * false, indicating that the buffer will be dispatched again with a
237 * new set of cliprects.
238 */
239typedef struct _drm_i810_vertex {
240 int idx; /* buffer index */
241 int used; /* nr bytes in use */
242 int discard; /* client is finished with the buffer? */
243} drm_i810_vertex_t;
244
245typedef struct _drm_i810_copy_t {
246 int idx; /* buffer index */
247 int used; /* nr bytes in use */
248 void *address; /* Address to copy from */
249} drm_i810_copy_t;
250
251#define PR_TRIANGLES (0x0<<18)
252#define PR_TRISTRIP_0 (0x1<<18)
253#define PR_TRISTRIP_1 (0x2<<18)
254#define PR_TRIFAN (0x3<<18)
255#define PR_POLYGON (0x4<<18)
256#define PR_LINES (0x5<<18)
257#define PR_LINESTRIP (0x6<<18)
258#define PR_RECTS (0x7<<18)
259#define PR_MASK (0x7<<18)
260
261typedef struct drm_i810_dma {
262 void *virtual;
263 int request_idx;
264 int request_size;
265 int granted;
266} drm_i810_dma_t;
267
268typedef struct _drm_i810_overlay_t {
269 unsigned int offset; /* Address of the Overlay Regs */
270 unsigned int physical;
271} drm_i810_overlay_t;
272
273typedef struct _drm_i810_mc {
274 int idx; /* buffer index */
275 int used; /* nr bytes in use */
276 int num_blocks; /* number of GFXBlocks */
277 int *length; /* List of lengths for GFXBlocks (FUTURE) */
278 unsigned int last_render; /* Last Render Request */
279} drm_i810_mc_t;
280
281#endif /* _I810_DRM_H_ */
diff --git a/drivers/char/drm/i810_drv.c b/drivers/char/drm/i810_drv.c
deleted file mode 100644
index fabb9a817966..000000000000
--- a/drivers/char/drm/i810_drv.c
+++ /dev/null
@@ -1,97 +0,0 @@
1/* i810_drv.c -- I810 driver -*- linux-c -*-
2 * Created: Mon Dec 13 01:56:22 1999 by jhartmann@precisioninsight.com
3 *
4 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
5 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
6 * All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice (including the next
16 * paragraph) shall be included in all copies or substantial portions of the
17 * Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
23 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25 * OTHER DEALINGS IN THE SOFTWARE.
26 *
27 * Authors:
28 * Rickard E. (Rik) Faith <faith@valinux.com>
29 * Jeff Hartmann <jhartmann@valinux.com>
30 * Gareth Hughes <gareth@valinux.com>
31 */
32
33#include "drmP.h"
34#include "drm.h"
35#include "i810_drm.h"
36#include "i810_drv.h"
37
38#include "drm_pciids.h"
39
40static struct pci_device_id pciidlist[] = {
41 i810_PCI_IDS
42};
43
44static struct drm_driver driver = {
45 .driver_features =
46 DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR |
47 DRIVER_HAVE_DMA | DRIVER_DMA_QUEUE,
48 .dev_priv_size = sizeof(drm_i810_buf_priv_t),
49 .load = i810_driver_load,
50 .lastclose = i810_driver_lastclose,
51 .preclose = i810_driver_preclose,
52 .device_is_agp = i810_driver_device_is_agp,
53 .reclaim_buffers_locked = i810_driver_reclaim_buffers_locked,
54 .dma_quiescent = i810_driver_dma_quiescent,
55 .get_map_ofs = drm_core_get_map_ofs,
56 .get_reg_ofs = drm_core_get_reg_ofs,
57 .ioctls = i810_ioctls,
58 .fops = {
59 .owner = THIS_MODULE,
60 .open = drm_open,
61 .release = drm_release,
62 .ioctl = drm_ioctl,
63 .mmap = drm_mmap,
64 .poll = drm_poll,
65 .fasync = drm_fasync,
66 },
67
68 .pci_driver = {
69 .name = DRIVER_NAME,
70 .id_table = pciidlist,
71 },
72
73 .name = DRIVER_NAME,
74 .desc = DRIVER_DESC,
75 .date = DRIVER_DATE,
76 .major = DRIVER_MAJOR,
77 .minor = DRIVER_MINOR,
78 .patchlevel = DRIVER_PATCHLEVEL,
79};
80
81static int __init i810_init(void)
82{
83 driver.num_ioctls = i810_max_ioctl;
84 return drm_init(&driver);
85}
86
87static void __exit i810_exit(void)
88{
89 drm_exit(&driver);
90}
91
92module_init(i810_init);
93module_exit(i810_exit);
94
95MODULE_AUTHOR(DRIVER_AUTHOR);
96MODULE_DESCRIPTION(DRIVER_DESC);
97MODULE_LICENSE("GPL and additional rights");
diff --git a/drivers/char/drm/i810_drv.h b/drivers/char/drm/i810_drv.h
deleted file mode 100644
index 0118849a5672..000000000000
--- a/drivers/char/drm/i810_drv.h
+++ /dev/null
@@ -1,242 +0,0 @@
1/* i810_drv.h -- Private header for the Matrox g200/g400 driver -*- linux-c -*-
2 * Created: Mon Dec 13 01:50:01 1999 by jhartmann@precisioninsight.com
3 *
4 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
5 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
6 * All rights reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice (including the next
16 * paragraph) shall be included in all copies or substantial portions of the
17 * Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
23 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 * DEALINGS IN THE SOFTWARE.
26 *
27 * Authors: Rickard E. (Rik) Faith <faith@valinux.com>
28 * Jeff Hartmann <jhartmann@valinux.com>
29 *
30 */
31
32#ifndef _I810_DRV_H_
33#define _I810_DRV_H_
34
35/* General customization:
36 */
37
38#define DRIVER_AUTHOR "VA Linux Systems Inc."
39
40#define DRIVER_NAME "i810"
41#define DRIVER_DESC "Intel i810"
42#define DRIVER_DATE "20030605"
43
44/* Interface history
45 *
46 * 1.1 - XFree86 4.1
47 * 1.2 - XvMC interfaces
48 * - XFree86 4.2
49 * 1.2.1 - Disable copying code (leave stub ioctls for backwards compatibility)
50 * - Remove requirement for interrupt (leave stubs again)
51 * 1.3 - Add page flipping.
52 * 1.4 - fix DRM interface
53 */
54#define DRIVER_MAJOR 1
55#define DRIVER_MINOR 4
56#define DRIVER_PATCHLEVEL 0
57
58typedef struct drm_i810_buf_priv {
59 u32 *in_use;
60 int my_use_idx;
61 int currently_mapped;
62 void *virtual;
63 void *kernel_virtual;
64 drm_local_map_t map;
65} drm_i810_buf_priv_t;
66
67typedef struct _drm_i810_ring_buffer {
68 int tail_mask;
69 unsigned long Start;
70 unsigned long End;
71 unsigned long Size;
72 u8 *virtual_start;
73 int head;
74 int tail;
75 int space;
76 drm_local_map_t map;
77} drm_i810_ring_buffer_t;
78
79typedef struct drm_i810_private {
80 struct drm_map *sarea_map;
81 struct drm_map *mmio_map;
82
83 drm_i810_sarea_t *sarea_priv;
84 drm_i810_ring_buffer_t ring;
85
86 void *hw_status_page;
87 unsigned long counter;
88
89 dma_addr_t dma_status_page;
90
91 struct drm_buf *mmap_buffer;
92
93 u32 front_di1, back_di1, zi1;
94
95 int back_offset;
96 int depth_offset;
97 int overlay_offset;
98 int overlay_physical;
99 int w, h;
100 int pitch;
101 int back_pitch;
102 int depth_pitch;
103
104 int do_boxes;
105 int dma_used;
106
107 int current_page;
108 int page_flipping;
109
110 wait_queue_head_t irq_queue;
111 atomic_t irq_received;
112 atomic_t irq_emitted;
113
114 int front_offset;
115} drm_i810_private_t;
116
117 /* i810_dma.c */
118extern int i810_driver_dma_quiescent(struct drm_device * dev);
119extern void i810_driver_reclaim_buffers_locked(struct drm_device * dev,
120 struct drm_file *file_priv);
121extern int i810_driver_load(struct drm_device *, unsigned long flags);
122extern void i810_driver_lastclose(struct drm_device * dev);
123extern void i810_driver_preclose(struct drm_device * dev,
124 struct drm_file *file_priv);
125extern void i810_driver_reclaim_buffers_locked(struct drm_device * dev,
126 struct drm_file *file_priv);
127extern int i810_driver_device_is_agp(struct drm_device * dev);
128
129extern struct drm_ioctl_desc i810_ioctls[];
130extern int i810_max_ioctl;
131
132#define I810_BASE(reg) ((unsigned long) \
133 dev_priv->mmio_map->handle)
134#define I810_ADDR(reg) (I810_BASE(reg) + reg)
135#define I810_DEREF(reg) *(__volatile__ int *)I810_ADDR(reg)
136#define I810_READ(reg) I810_DEREF(reg)
137#define I810_WRITE(reg,val) do { I810_DEREF(reg) = val; } while (0)
138#define I810_DEREF16(reg) *(__volatile__ u16 *)I810_ADDR(reg)
139#define I810_READ16(reg) I810_DEREF16(reg)
140#define I810_WRITE16(reg,val) do { I810_DEREF16(reg) = val; } while (0)
141
142#define I810_VERBOSE 0
143#define RING_LOCALS unsigned int outring, ringmask; \
144 volatile char *virt;
145
146#define BEGIN_LP_RING(n) do { \
147 if (I810_VERBOSE) \
148 DRM_DEBUG("BEGIN_LP_RING(%d)\n", n); \
149 if (dev_priv->ring.space < n*4) \
150 i810_wait_ring(dev, n*4); \
151 dev_priv->ring.space -= n*4; \
152 outring = dev_priv->ring.tail; \
153 ringmask = dev_priv->ring.tail_mask; \
154 virt = dev_priv->ring.virtual_start; \
155} while (0)
156
157#define ADVANCE_LP_RING() do { \
158 if (I810_VERBOSE) DRM_DEBUG("ADVANCE_LP_RING\n"); \
159 dev_priv->ring.tail = outring; \
160 I810_WRITE(LP_RING + RING_TAIL, outring); \
161} while(0)
162
163#define OUT_RING(n) do { \
164 if (I810_VERBOSE) DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \
165 *(volatile unsigned int *)(virt + outring) = n; \
166 outring += 4; \
167 outring &= ringmask; \
168} while (0)
169
170#define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23))
171#define GFX_OP_BREAKPOINT_INTERRUPT ((0<<29)|(1<<23))
172#define CMD_REPORT_HEAD (7<<23)
173#define CMD_STORE_DWORD_IDX ((0x21<<23) | 0x1)
174#define CMD_OP_BATCH_BUFFER ((0x0<<29)|(0x30<<23)|0x1)
175
176#define INST_PARSER_CLIENT 0x00000000
177#define INST_OP_FLUSH 0x02000000
178#define INST_FLUSH_MAP_CACHE 0x00000001
179
180#define BB1_START_ADDR_MASK (~0x7)
181#define BB1_PROTECTED (1<<0)
182#define BB1_UNPROTECTED (0<<0)
183#define BB2_END_ADDR_MASK (~0x7)
184
185#define I810REG_HWSTAM 0x02098
186#define I810REG_INT_IDENTITY_R 0x020a4
187#define I810REG_INT_MASK_R 0x020a8
188#define I810REG_INT_ENABLE_R 0x020a0
189
190#define LP_RING 0x2030
191#define HP_RING 0x2040
192#define RING_TAIL 0x00
193#define TAIL_ADDR 0x000FFFF8
194#define RING_HEAD 0x04
195#define HEAD_WRAP_COUNT 0xFFE00000
196#define HEAD_WRAP_ONE 0x00200000
197#define HEAD_ADDR 0x001FFFFC
198#define RING_START 0x08
199#define START_ADDR 0x00FFFFF8
200#define RING_LEN 0x0C
201#define RING_NR_PAGES 0x000FF000
202#define RING_REPORT_MASK 0x00000006
203#define RING_REPORT_64K 0x00000002
204#define RING_REPORT_128K 0x00000004
205#define RING_NO_REPORT 0x00000000
206#define RING_VALID_MASK 0x00000001
207#define RING_VALID 0x00000001
208#define RING_INVALID 0x00000000
209
210#define GFX_OP_SCISSOR ((0x3<<29)|(0x1c<<24)|(0x10<<19))
211#define SC_UPDATE_SCISSOR (0x1<<1)
212#define SC_ENABLE_MASK (0x1<<0)
213#define SC_ENABLE (0x1<<0)
214
215#define GFX_OP_SCISSOR_INFO ((0x3<<29)|(0x1d<<24)|(0x81<<16)|(0x1))
216#define SCI_YMIN_MASK (0xffff<<16)
217#define SCI_XMIN_MASK (0xffff<<0)
218#define SCI_YMAX_MASK (0xffff<<16)
219#define SCI_XMAX_MASK (0xffff<<0)
220
221#define GFX_OP_COLOR_FACTOR ((0x3<<29)|(0x1d<<24)|(0x1<<16)|0x0)
222#define GFX_OP_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16))
223#define GFX_OP_MAP_INFO ((0x3<<29)|(0x1d<<24)|0x2)
224#define GFX_OP_DESTBUFFER_VARS ((0x3<<29)|(0x1d<<24)|(0x85<<16)|0x0)
225#define GFX_OP_DRAWRECT_INFO ((0x3<<29)|(0x1d<<24)|(0x80<<16)|(0x3))
226#define GFX_OP_PRIMITIVE ((0x3<<29)|(0x1f<<24))
227
228#define CMD_OP_Z_BUFFER_INFO ((0x0<<29)|(0x16<<23))
229#define CMD_OP_DESTBUFFER_INFO ((0x0<<29)|(0x15<<23))
230#define CMD_OP_FRONTBUFFER_INFO ((0x0<<29)|(0x14<<23))
231#define CMD_OP_WAIT_FOR_EVENT ((0x0<<29)|(0x03<<23))
232
233#define BR00_BITBLT_CLIENT 0x40000000
234#define BR00_OP_COLOR_BLT 0x10000000
235#define BR00_OP_SRC_COPY_BLT 0x10C00000
236#define BR13_SOLID_PATTERN 0x80000000
237
238#define WAIT_FOR_PLANE_A_SCANLINES (1<<1)
239#define WAIT_FOR_PLANE_A_FLIP (1<<2)
240#define WAIT_FOR_VBLANK (1<<3)
241
242#endif
diff --git a/drivers/char/drm/i830_dma.c b/drivers/char/drm/i830_dma.c
deleted file mode 100644
index a86ab30b4620..000000000000
--- a/drivers/char/drm/i830_dma.c
+++ /dev/null
@@ -1,1553 +0,0 @@
1/* i830_dma.c -- DMA support for the I830 -*- linux-c -*-
2 * Created: Mon Dec 13 01:50:01 1999 by jhartmann@precisioninsight.com
3 *
4 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
5 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
6 * All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice (including the next
16 * paragraph) shall be included in all copies or substantial portions of the
17 * Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
23 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 * DEALINGS IN THE SOFTWARE.
26 *
27 * Authors: Rickard E. (Rik) Faith <faith@valinux.com>
28 * Jeff Hartmann <jhartmann@valinux.com>
29 * Keith Whitwell <keith@tungstengraphics.com>
30 * Abraham vd Merwe <abraham@2d3d.co.za>
31 *
32 */
33
34#include "drmP.h"
35#include "drm.h"
36#include "i830_drm.h"
37#include "i830_drv.h"
38#include <linux/interrupt.h> /* For task queue support */
39#include <linux/pagemap.h>
40#include <linux/delay.h>
41#include <asm/uaccess.h>
42
43#define I830_BUF_FREE 2
44#define I830_BUF_CLIENT 1
45#define I830_BUF_HARDWARE 0
46
47#define I830_BUF_UNMAPPED 0
48#define I830_BUF_MAPPED 1
49
50static struct drm_buf *i830_freelist_get(struct drm_device * dev)
51{
52 struct drm_device_dma *dma = dev->dma;
53 int i;
54 int used;
55
56 /* Linear search might not be the best solution */
57
58 for (i = 0; i < dma->buf_count; i++) {
59 struct drm_buf *buf = dma->buflist[i];
60 drm_i830_buf_priv_t *buf_priv = buf->dev_private;
61 /* In use is already a pointer */
62 used = cmpxchg(buf_priv->in_use, I830_BUF_FREE,
63 I830_BUF_CLIENT);
64 if (used == I830_BUF_FREE) {
65 return buf;
66 }
67 }
68 return NULL;
69}
70
71/* This should only be called if the buffer is not sent to the hardware
72 * yet, the hardware updates in use for us once its on the ring buffer.
73 */
74
75static int i830_freelist_put(struct drm_device * dev, struct drm_buf * buf)
76{
77 drm_i830_buf_priv_t *buf_priv = buf->dev_private;
78 int used;
79
80 /* In use is already a pointer */
81 used = cmpxchg(buf_priv->in_use, I830_BUF_CLIENT, I830_BUF_FREE);
82 if (used != I830_BUF_CLIENT) {
83 DRM_ERROR("Freeing buffer thats not in use : %d\n", buf->idx);
84 return -EINVAL;
85 }
86
87 return 0;
88}
89
90static int i830_mmap_buffers(struct file *filp, struct vm_area_struct *vma)
91{
92 struct drm_file *priv = filp->private_data;
93 struct drm_device *dev;
94 drm_i830_private_t *dev_priv;
95 struct drm_buf *buf;
96 drm_i830_buf_priv_t *buf_priv;
97
98 lock_kernel();
99 dev = priv->minor->dev;
100 dev_priv = dev->dev_private;
101 buf = dev_priv->mmap_buffer;
102 buf_priv = buf->dev_private;
103
104 vma->vm_flags |= (VM_IO | VM_DONTCOPY);
105 vma->vm_file = filp;
106
107 buf_priv->currently_mapped = I830_BUF_MAPPED;
108 unlock_kernel();
109
110 if (io_remap_pfn_range(vma, vma->vm_start,
111 vma->vm_pgoff,
112 vma->vm_end - vma->vm_start, vma->vm_page_prot))
113 return -EAGAIN;
114 return 0;
115}
116
117static const struct file_operations i830_buffer_fops = {
118 .open = drm_open,
119 .release = drm_release,
120 .ioctl = drm_ioctl,
121 .mmap = i830_mmap_buffers,
122 .fasync = drm_fasync,
123};
124
125static int i830_map_buffer(struct drm_buf * buf, struct drm_file *file_priv)
126{
127 struct drm_device *dev = file_priv->minor->dev;
128 drm_i830_buf_priv_t *buf_priv = buf->dev_private;
129 drm_i830_private_t *dev_priv = dev->dev_private;
130 const struct file_operations *old_fops;
131 unsigned long virtual;
132 int retcode = 0;
133
134 if (buf_priv->currently_mapped == I830_BUF_MAPPED)
135 return -EINVAL;
136
137 down_write(&current->mm->mmap_sem);
138 old_fops = file_priv->filp->f_op;
139 file_priv->filp->f_op = &i830_buffer_fops;
140 dev_priv->mmap_buffer = buf;
141 virtual = do_mmap(file_priv->filp, 0, buf->total, PROT_READ | PROT_WRITE,
142 MAP_SHARED, buf->bus_address);
143 dev_priv->mmap_buffer = NULL;
144 file_priv->filp->f_op = old_fops;
145 if (IS_ERR((void *)virtual)) { /* ugh */
146 /* Real error */
147 DRM_ERROR("mmap error\n");
148 retcode = PTR_ERR((void *)virtual);
149 buf_priv->virtual = NULL;
150 } else {
151 buf_priv->virtual = (void __user *)virtual;
152 }
153 up_write(&current->mm->mmap_sem);
154
155 return retcode;
156}
157
158static int i830_unmap_buffer(struct drm_buf * buf)
159{
160 drm_i830_buf_priv_t *buf_priv = buf->dev_private;
161 int retcode = 0;
162
163 if (buf_priv->currently_mapped != I830_BUF_MAPPED)
164 return -EINVAL;
165
166 down_write(&current->mm->mmap_sem);
167 retcode = do_munmap(current->mm,
168 (unsigned long)buf_priv->virtual,
169 (size_t) buf->total);
170 up_write(&current->mm->mmap_sem);
171
172 buf_priv->currently_mapped = I830_BUF_UNMAPPED;
173 buf_priv->virtual = NULL;
174
175 return retcode;
176}
177
178static int i830_dma_get_buffer(struct drm_device * dev, drm_i830_dma_t * d,
179 struct drm_file *file_priv)
180{
181 struct drm_buf *buf;
182 drm_i830_buf_priv_t *buf_priv;
183 int retcode = 0;
184
185 buf = i830_freelist_get(dev);
186 if (!buf) {
187 retcode = -ENOMEM;
188 DRM_DEBUG("retcode=%d\n", retcode);
189 return retcode;
190 }
191
192 retcode = i830_map_buffer(buf, file_priv);
193 if (retcode) {
194 i830_freelist_put(dev, buf);
195 DRM_ERROR("mapbuf failed, retcode %d\n", retcode);
196 return retcode;
197 }
198 buf->file_priv = file_priv;
199 buf_priv = buf->dev_private;
200 d->granted = 1;
201 d->request_idx = buf->idx;
202 d->request_size = buf->total;
203 d->virtual = buf_priv->virtual;
204
205 return retcode;
206}
207
208static int i830_dma_cleanup(struct drm_device * dev)
209{
210 struct drm_device_dma *dma = dev->dma;
211
212 /* Make sure interrupts are disabled here because the uninstall ioctl
213 * may not have been called from userspace and after dev_private
214 * is freed, it's too late.
215 */
216 if (dev->irq_enabled)
217 drm_irq_uninstall(dev);
218
219 if (dev->dev_private) {
220 int i;
221 drm_i830_private_t *dev_priv =
222 (drm_i830_private_t *) dev->dev_private;
223
224 if (dev_priv->ring.virtual_start) {
225 drm_core_ioremapfree(&dev_priv->ring.map, dev);
226 }
227 if (dev_priv->hw_status_page) {
228 pci_free_consistent(dev->pdev, PAGE_SIZE,
229 dev_priv->hw_status_page,
230 dev_priv->dma_status_page);
231 /* Need to rewrite hardware status page */
232 I830_WRITE(0x02080, 0x1ffff000);
233 }
234
235 drm_free(dev->dev_private, sizeof(drm_i830_private_t),
236 DRM_MEM_DRIVER);
237 dev->dev_private = NULL;
238
239 for (i = 0; i < dma->buf_count; i++) {
240 struct drm_buf *buf = dma->buflist[i];
241 drm_i830_buf_priv_t *buf_priv = buf->dev_private;
242 if (buf_priv->kernel_virtual && buf->total)
243 drm_core_ioremapfree(&buf_priv->map, dev);
244 }
245 }
246 return 0;
247}
248
249int i830_wait_ring(struct drm_device * dev, int n, const char *caller)
250{
251 drm_i830_private_t *dev_priv = dev->dev_private;
252 drm_i830_ring_buffer_t *ring = &(dev_priv->ring);
253 int iters = 0;
254 unsigned long end;
255 unsigned int last_head = I830_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
256
257 end = jiffies + (HZ * 3);
258 while (ring->space < n) {
259 ring->head = I830_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
260 ring->space = ring->head - (ring->tail + 8);
261 if (ring->space < 0)
262 ring->space += ring->Size;
263
264 if (ring->head != last_head) {
265 end = jiffies + (HZ * 3);
266 last_head = ring->head;
267 }
268
269 iters++;
270 if (time_before(end, jiffies)) {
271 DRM_ERROR("space: %d wanted %d\n", ring->space, n);
272 DRM_ERROR("lockup\n");
273 goto out_wait_ring;
274 }
275 udelay(1);
276 dev_priv->sarea_priv->perf_boxes |= I830_BOX_WAIT;
277 }
278
279 out_wait_ring:
280 return iters;
281}
282
283static void i830_kernel_lost_context(struct drm_device * dev)
284{
285 drm_i830_private_t *dev_priv = dev->dev_private;
286 drm_i830_ring_buffer_t *ring = &(dev_priv->ring);
287
288 ring->head = I830_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
289 ring->tail = I830_READ(LP_RING + RING_TAIL) & TAIL_ADDR;
290 ring->space = ring->head - (ring->tail + 8);
291 if (ring->space < 0)
292 ring->space += ring->Size;
293
294 if (ring->head == ring->tail)
295 dev_priv->sarea_priv->perf_boxes |= I830_BOX_RING_EMPTY;
296}
297
298static int i830_freelist_init(struct drm_device * dev, drm_i830_private_t * dev_priv)
299{
300 struct drm_device_dma *dma = dev->dma;
301 int my_idx = 36;
302 u32 *hw_status = (u32 *) (dev_priv->hw_status_page + my_idx);
303 int i;
304
305 if (dma->buf_count > 1019) {
306 /* Not enough space in the status page for the freelist */
307 return -EINVAL;
308 }
309
310 for (i = 0; i < dma->buf_count; i++) {
311 struct drm_buf *buf = dma->buflist[i];
312 drm_i830_buf_priv_t *buf_priv = buf->dev_private;
313
314 buf_priv->in_use = hw_status++;
315 buf_priv->my_use_idx = my_idx;
316 my_idx += 4;
317
318 *buf_priv->in_use = I830_BUF_FREE;
319
320 buf_priv->map.offset = buf->bus_address;
321 buf_priv->map.size = buf->total;
322 buf_priv->map.type = _DRM_AGP;
323 buf_priv->map.flags = 0;
324 buf_priv->map.mtrr = 0;
325
326 drm_core_ioremap(&buf_priv->map, dev);
327 buf_priv->kernel_virtual = buf_priv->map.handle;
328 }
329 return 0;
330}
331
332static int i830_dma_initialize(struct drm_device * dev,
333 drm_i830_private_t * dev_priv,
334 drm_i830_init_t * init)
335{
336 struct drm_map_list *r_list;
337
338 memset(dev_priv, 0, sizeof(drm_i830_private_t));
339
340 list_for_each_entry(r_list, &dev->maplist, head) {
341 if (r_list->map &&
342 r_list->map->type == _DRM_SHM &&
343 r_list->map->flags & _DRM_CONTAINS_LOCK) {
344 dev_priv->sarea_map = r_list->map;
345 break;
346 }
347 }
348
349 if (!dev_priv->sarea_map) {
350 dev->dev_private = (void *)dev_priv;
351 i830_dma_cleanup(dev);
352 DRM_ERROR("can not find sarea!\n");
353 return -EINVAL;
354 }
355 dev_priv->mmio_map = drm_core_findmap(dev, init->mmio_offset);
356 if (!dev_priv->mmio_map) {
357 dev->dev_private = (void *)dev_priv;
358 i830_dma_cleanup(dev);
359 DRM_ERROR("can not find mmio map!\n");
360 return -EINVAL;
361 }
362 dev->agp_buffer_token = init->buffers_offset;
363 dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset);
364 if (!dev->agp_buffer_map) {
365 dev->dev_private = (void *)dev_priv;
366 i830_dma_cleanup(dev);
367 DRM_ERROR("can not find dma buffer map!\n");
368 return -EINVAL;
369 }
370
371 dev_priv->sarea_priv = (drm_i830_sarea_t *)
372 ((u8 *) dev_priv->sarea_map->handle + init->sarea_priv_offset);
373
374 dev_priv->ring.Start = init->ring_start;
375 dev_priv->ring.End = init->ring_end;
376 dev_priv->ring.Size = init->ring_size;
377
378 dev_priv->ring.map.offset = dev->agp->base + init->ring_start;
379 dev_priv->ring.map.size = init->ring_size;
380 dev_priv->ring.map.type = _DRM_AGP;
381 dev_priv->ring.map.flags = 0;
382 dev_priv->ring.map.mtrr = 0;
383
384 drm_core_ioremap(&dev_priv->ring.map, dev);
385
386 if (dev_priv->ring.map.handle == NULL) {
387 dev->dev_private = (void *)dev_priv;
388 i830_dma_cleanup(dev);
389 DRM_ERROR("can not ioremap virtual address for"
390 " ring buffer\n");
391 return -ENOMEM;
392 }
393
394 dev_priv->ring.virtual_start = dev_priv->ring.map.handle;
395
396 dev_priv->ring.tail_mask = dev_priv->ring.Size - 1;
397
398 dev_priv->w = init->w;
399 dev_priv->h = init->h;
400 dev_priv->pitch = init->pitch;
401 dev_priv->back_offset = init->back_offset;
402 dev_priv->depth_offset = init->depth_offset;
403 dev_priv->front_offset = init->front_offset;
404
405 dev_priv->front_di1 = init->front_offset | init->pitch_bits;
406 dev_priv->back_di1 = init->back_offset | init->pitch_bits;
407 dev_priv->zi1 = init->depth_offset | init->pitch_bits;
408
409 DRM_DEBUG("front_di1 %x\n", dev_priv->front_di1);
410 DRM_DEBUG("back_offset %x\n", dev_priv->back_offset);
411 DRM_DEBUG("back_di1 %x\n", dev_priv->back_di1);
412 DRM_DEBUG("pitch_bits %x\n", init->pitch_bits);
413
414 dev_priv->cpp = init->cpp;
415 /* We are using separate values as placeholders for mechanisms for
416 * private backbuffer/depthbuffer usage.
417 */
418
419 dev_priv->back_pitch = init->back_pitch;
420 dev_priv->depth_pitch = init->depth_pitch;
421 dev_priv->do_boxes = 0;
422 dev_priv->use_mi_batchbuffer_start = 0;
423
424 /* Program Hardware Status Page */
425 dev_priv->hw_status_page =
426 pci_alloc_consistent(dev->pdev, PAGE_SIZE,
427 &dev_priv->dma_status_page);
428 if (!dev_priv->hw_status_page) {
429 dev->dev_private = (void *)dev_priv;
430 i830_dma_cleanup(dev);
431 DRM_ERROR("Can not allocate hardware status page\n");
432 return -ENOMEM;
433 }
434 memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
435 DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page);
436
437 I830_WRITE(0x02080, dev_priv->dma_status_page);
438 DRM_DEBUG("Enabled hardware status page\n");
439
440 /* Now we need to init our freelist */
441 if (i830_freelist_init(dev, dev_priv) != 0) {
442 dev->dev_private = (void *)dev_priv;
443 i830_dma_cleanup(dev);
444 DRM_ERROR("Not enough space in the status page for"
445 " the freelist\n");
446 return -ENOMEM;
447 }
448 dev->dev_private = (void *)dev_priv;
449
450 return 0;
451}
452
453static int i830_dma_init(struct drm_device *dev, void *data,
454 struct drm_file *file_priv)
455{
456 drm_i830_private_t *dev_priv;
457 drm_i830_init_t *init = data;
458 int retcode = 0;
459
460 switch (init->func) {
461 case I830_INIT_DMA:
462 dev_priv = drm_alloc(sizeof(drm_i830_private_t),
463 DRM_MEM_DRIVER);
464 if (dev_priv == NULL)
465 return -ENOMEM;
466 retcode = i830_dma_initialize(dev, dev_priv, init);
467 break;
468 case I830_CLEANUP_DMA:
469 retcode = i830_dma_cleanup(dev);
470 break;
471 default:
472 retcode = -EINVAL;
473 break;
474 }
475
476 return retcode;
477}
478
479#define GFX_OP_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16))
480#define ST1_ENABLE (1<<16)
481#define ST1_MASK (0xffff)
482
483/* Most efficient way to verify state for the i830 is as it is
484 * emitted. Non-conformant state is silently dropped.
485 */
486static void i830EmitContextVerified(struct drm_device * dev, unsigned int *code)
487{
488 drm_i830_private_t *dev_priv = dev->dev_private;
489 int i, j = 0;
490 unsigned int tmp;
491 RING_LOCALS;
492
493 BEGIN_LP_RING(I830_CTX_SETUP_SIZE + 4);
494
495 for (i = 0; i < I830_CTXREG_BLENDCOLR0; i++) {
496 tmp = code[i];
497 if ((tmp & (7 << 29)) == CMD_3D &&
498 (tmp & (0x1f << 24)) < (0x1d << 24)) {
499 OUT_RING(tmp);
500 j++;
501 } else {
502 DRM_ERROR("Skipping %d\n", i);
503 }
504 }
505
506 OUT_RING(STATE3D_CONST_BLEND_COLOR_CMD);
507 OUT_RING(code[I830_CTXREG_BLENDCOLR]);
508 j += 2;
509
510 for (i = I830_CTXREG_VF; i < I830_CTXREG_MCSB0; i++) {
511 tmp = code[i];
512 if ((tmp & (7 << 29)) == CMD_3D &&
513 (tmp & (0x1f << 24)) < (0x1d << 24)) {
514 OUT_RING(tmp);
515 j++;
516 } else {
517 DRM_ERROR("Skipping %d\n", i);
518 }
519 }
520
521 OUT_RING(STATE3D_MAP_COORD_SETBIND_CMD);
522 OUT_RING(code[I830_CTXREG_MCSB1]);
523 j += 2;
524
525 if (j & 1)
526 OUT_RING(0);
527
528 ADVANCE_LP_RING();
529}
530
531static void i830EmitTexVerified(struct drm_device * dev, unsigned int *code)
532{
533 drm_i830_private_t *dev_priv = dev->dev_private;
534 int i, j = 0;
535 unsigned int tmp;
536 RING_LOCALS;
537
538 if (code[I830_TEXREG_MI0] == GFX_OP_MAP_INFO ||
539 (code[I830_TEXREG_MI0] & ~(0xf * LOAD_TEXTURE_MAP0)) ==
540 (STATE3D_LOAD_STATE_IMMEDIATE_2 | 4)) {
541
542 BEGIN_LP_RING(I830_TEX_SETUP_SIZE);
543
544 OUT_RING(code[I830_TEXREG_MI0]); /* TM0LI */
545 OUT_RING(code[I830_TEXREG_MI1]); /* TM0S0 */
546 OUT_RING(code[I830_TEXREG_MI2]); /* TM0S1 */
547 OUT_RING(code[I830_TEXREG_MI3]); /* TM0S2 */
548 OUT_RING(code[I830_TEXREG_MI4]); /* TM0S3 */
549 OUT_RING(code[I830_TEXREG_MI5]); /* TM0S4 */
550
551 for (i = 6; i < I830_TEX_SETUP_SIZE; i++) {
552 tmp = code[i];
553 OUT_RING(tmp);
554 j++;
555 }
556
557 if (j & 1)
558 OUT_RING(0);
559
560 ADVANCE_LP_RING();
561 } else
562 printk("rejected packet %x\n", code[0]);
563}
564
565static void i830EmitTexBlendVerified(struct drm_device * dev,
566 unsigned int *code, unsigned int num)
567{
568 drm_i830_private_t *dev_priv = dev->dev_private;
569 int i, j = 0;
570 unsigned int tmp;
571 RING_LOCALS;
572
573 if (!num)
574 return;
575
576 BEGIN_LP_RING(num + 1);
577
578 for (i = 0; i < num; i++) {
579 tmp = code[i];
580 OUT_RING(tmp);
581 j++;
582 }
583
584 if (j & 1)
585 OUT_RING(0);
586
587 ADVANCE_LP_RING();
588}
589
590static void i830EmitTexPalette(struct drm_device * dev,
591 unsigned int *palette, int number, int is_shared)
592{
593 drm_i830_private_t *dev_priv = dev->dev_private;
594 int i;
595 RING_LOCALS;
596
597 return;
598
599 BEGIN_LP_RING(258);
600
601 if (is_shared == 1) {
602 OUT_RING(CMD_OP_MAP_PALETTE_LOAD |
603 MAP_PALETTE_NUM(0) | MAP_PALETTE_BOTH);
604 } else {
605 OUT_RING(CMD_OP_MAP_PALETTE_LOAD | MAP_PALETTE_NUM(number));
606 }
607 for (i = 0; i < 256; i++) {
608 OUT_RING(palette[i]);
609 }
610 OUT_RING(0);
611 /* KW: WHERE IS THE ADVANCE_LP_RING? This is effectively a noop!
612 */
613}
614
615/* Need to do some additional checking when setting the dest buffer.
616 */
617static void i830EmitDestVerified(struct drm_device * dev, unsigned int *code)
618{
619 drm_i830_private_t *dev_priv = dev->dev_private;
620 unsigned int tmp;
621 RING_LOCALS;
622
623 BEGIN_LP_RING(I830_DEST_SETUP_SIZE + 10);
624
625 tmp = code[I830_DESTREG_CBUFADDR];
626 if (tmp == dev_priv->front_di1 || tmp == dev_priv->back_di1) {
627 if (((int)outring) & 8) {
628 OUT_RING(0);
629 OUT_RING(0);
630 }
631
632 OUT_RING(CMD_OP_DESTBUFFER_INFO);
633 OUT_RING(BUF_3D_ID_COLOR_BACK |
634 BUF_3D_PITCH(dev_priv->back_pitch * dev_priv->cpp) |
635 BUF_3D_USE_FENCE);
636 OUT_RING(tmp);
637 OUT_RING(0);
638
639 OUT_RING(CMD_OP_DESTBUFFER_INFO);
640 OUT_RING(BUF_3D_ID_DEPTH | BUF_3D_USE_FENCE |
641 BUF_3D_PITCH(dev_priv->depth_pitch * dev_priv->cpp));
642 OUT_RING(dev_priv->zi1);
643 OUT_RING(0);
644 } else {
645 DRM_ERROR("bad di1 %x (allow %x or %x)\n",
646 tmp, dev_priv->front_di1, dev_priv->back_di1);
647 }
648
649 /* invarient:
650 */
651
652 OUT_RING(GFX_OP_DESTBUFFER_VARS);
653 OUT_RING(code[I830_DESTREG_DV1]);
654
655 OUT_RING(GFX_OP_DRAWRECT_INFO);
656 OUT_RING(code[I830_DESTREG_DR1]);
657 OUT_RING(code[I830_DESTREG_DR2]);
658 OUT_RING(code[I830_DESTREG_DR3]);
659 OUT_RING(code[I830_DESTREG_DR4]);
660
661 /* Need to verify this */
662 tmp = code[I830_DESTREG_SENABLE];
663 if ((tmp & ~0x3) == GFX_OP_SCISSOR_ENABLE) {
664 OUT_RING(tmp);
665 } else {
666 DRM_ERROR("bad scissor enable\n");
667 OUT_RING(0);
668 }
669
670 OUT_RING(GFX_OP_SCISSOR_RECT);
671 OUT_RING(code[I830_DESTREG_SR1]);
672 OUT_RING(code[I830_DESTREG_SR2]);
673 OUT_RING(0);
674
675 ADVANCE_LP_RING();
676}
677
678static void i830EmitStippleVerified(struct drm_device * dev, unsigned int *code)
679{
680 drm_i830_private_t *dev_priv = dev->dev_private;
681 RING_LOCALS;
682
683 BEGIN_LP_RING(2);
684 OUT_RING(GFX_OP_STIPPLE);
685 OUT_RING(code[1]);
686 ADVANCE_LP_RING();
687}
688
689static void i830EmitState(struct drm_device * dev)
690{
691 drm_i830_private_t *dev_priv = dev->dev_private;
692 drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv;
693 unsigned int dirty = sarea_priv->dirty;
694
695 DRM_DEBUG("%s %x\n", __func__, dirty);
696
697 if (dirty & I830_UPLOAD_BUFFERS) {
698 i830EmitDestVerified(dev, sarea_priv->BufferState);
699 sarea_priv->dirty &= ~I830_UPLOAD_BUFFERS;
700 }
701
702 if (dirty & I830_UPLOAD_CTX) {
703 i830EmitContextVerified(dev, sarea_priv->ContextState);
704 sarea_priv->dirty &= ~I830_UPLOAD_CTX;
705 }
706
707 if (dirty & I830_UPLOAD_TEX0) {
708 i830EmitTexVerified(dev, sarea_priv->TexState[0]);
709 sarea_priv->dirty &= ~I830_UPLOAD_TEX0;
710 }
711
712 if (dirty & I830_UPLOAD_TEX1) {
713 i830EmitTexVerified(dev, sarea_priv->TexState[1]);
714 sarea_priv->dirty &= ~I830_UPLOAD_TEX1;
715 }
716
717 if (dirty & I830_UPLOAD_TEXBLEND0) {
718 i830EmitTexBlendVerified(dev, sarea_priv->TexBlendState[0],
719 sarea_priv->TexBlendStateWordsUsed[0]);
720 sarea_priv->dirty &= ~I830_UPLOAD_TEXBLEND0;
721 }
722
723 if (dirty & I830_UPLOAD_TEXBLEND1) {
724 i830EmitTexBlendVerified(dev, sarea_priv->TexBlendState[1],
725 sarea_priv->TexBlendStateWordsUsed[1]);
726 sarea_priv->dirty &= ~I830_UPLOAD_TEXBLEND1;
727 }
728
729 if (dirty & I830_UPLOAD_TEX_PALETTE_SHARED) {
730 i830EmitTexPalette(dev, sarea_priv->Palette[0], 0, 1);
731 } else {
732 if (dirty & I830_UPLOAD_TEX_PALETTE_N(0)) {
733 i830EmitTexPalette(dev, sarea_priv->Palette[0], 0, 0);
734 sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(0);
735 }
736 if (dirty & I830_UPLOAD_TEX_PALETTE_N(1)) {
737 i830EmitTexPalette(dev, sarea_priv->Palette[1], 1, 0);
738 sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(1);
739 }
740
741 /* 1.3:
742 */
743#if 0
744 if (dirty & I830_UPLOAD_TEX_PALETTE_N(2)) {
745 i830EmitTexPalette(dev, sarea_priv->Palette2[0], 0, 0);
746 sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(2);
747 }
748 if (dirty & I830_UPLOAD_TEX_PALETTE_N(3)) {
749 i830EmitTexPalette(dev, sarea_priv->Palette2[1], 1, 0);
750 sarea_priv->dirty &= ~I830_UPLOAD_TEX_PALETTE_N(2);
751 }
752#endif
753 }
754
755 /* 1.3:
756 */
757 if (dirty & I830_UPLOAD_STIPPLE) {
758 i830EmitStippleVerified(dev, sarea_priv->StippleState);
759 sarea_priv->dirty &= ~I830_UPLOAD_STIPPLE;
760 }
761
762 if (dirty & I830_UPLOAD_TEX2) {
763 i830EmitTexVerified(dev, sarea_priv->TexState2);
764 sarea_priv->dirty &= ~I830_UPLOAD_TEX2;
765 }
766
767 if (dirty & I830_UPLOAD_TEX3) {
768 i830EmitTexVerified(dev, sarea_priv->TexState3);
769 sarea_priv->dirty &= ~I830_UPLOAD_TEX3;
770 }
771
772 if (dirty & I830_UPLOAD_TEXBLEND2) {
773 i830EmitTexBlendVerified(dev,
774 sarea_priv->TexBlendState2,
775 sarea_priv->TexBlendStateWordsUsed2);
776
777 sarea_priv->dirty &= ~I830_UPLOAD_TEXBLEND2;
778 }
779
780 if (dirty & I830_UPLOAD_TEXBLEND3) {
781 i830EmitTexBlendVerified(dev,
782 sarea_priv->TexBlendState3,
783 sarea_priv->TexBlendStateWordsUsed3);
784 sarea_priv->dirty &= ~I830_UPLOAD_TEXBLEND3;
785 }
786}
787
788/* ================================================================
789 * Performance monitoring functions
790 */
791
792static void i830_fill_box(struct drm_device * dev,
793 int x, int y, int w, int h, int r, int g, int b)
794{
795 drm_i830_private_t *dev_priv = dev->dev_private;
796 u32 color;
797 unsigned int BR13, CMD;
798 RING_LOCALS;
799
800 BR13 = (0xF0 << 16) | (dev_priv->pitch * dev_priv->cpp) | (1 << 24);
801 CMD = XY_COLOR_BLT_CMD;
802 x += dev_priv->sarea_priv->boxes[0].x1;
803 y += dev_priv->sarea_priv->boxes[0].y1;
804
805 if (dev_priv->cpp == 4) {
806 BR13 |= (1 << 25);
807 CMD |= (XY_COLOR_BLT_WRITE_ALPHA | XY_COLOR_BLT_WRITE_RGB);
808 color = (((0xff) << 24) | (r << 16) | (g << 8) | b);
809 } else {
810 color = (((r & 0xf8) << 8) |
811 ((g & 0xfc) << 3) | ((b & 0xf8) >> 3));
812 }
813
814 BEGIN_LP_RING(6);
815 OUT_RING(CMD);
816 OUT_RING(BR13);
817 OUT_RING((y << 16) | x);
818 OUT_RING(((y + h) << 16) | (x + w));
819
820 if (dev_priv->current_page == 1) {
821 OUT_RING(dev_priv->front_offset);
822 } else {
823 OUT_RING(dev_priv->back_offset);
824 }
825
826 OUT_RING(color);
827 ADVANCE_LP_RING();
828}
829
830static void i830_cp_performance_boxes(struct drm_device * dev)
831{
832 drm_i830_private_t *dev_priv = dev->dev_private;
833
834 /* Purple box for page flipping
835 */
836 if (dev_priv->sarea_priv->perf_boxes & I830_BOX_FLIP)
837 i830_fill_box(dev, 4, 4, 8, 8, 255, 0, 255);
838
839 /* Red box if we have to wait for idle at any point
840 */
841 if (dev_priv->sarea_priv->perf_boxes & I830_BOX_WAIT)
842 i830_fill_box(dev, 16, 4, 8, 8, 255, 0, 0);
843
844 /* Blue box: lost context?
845 */
846 if (dev_priv->sarea_priv->perf_boxes & I830_BOX_LOST_CONTEXT)
847 i830_fill_box(dev, 28, 4, 8, 8, 0, 0, 255);
848
849 /* Yellow box for texture swaps
850 */
851 if (dev_priv->sarea_priv->perf_boxes & I830_BOX_TEXTURE_LOAD)
852 i830_fill_box(dev, 40, 4, 8, 8, 255, 255, 0);
853
854 /* Green box if hardware never idles (as far as we can tell)
855 */
856 if (!(dev_priv->sarea_priv->perf_boxes & I830_BOX_RING_EMPTY))
857 i830_fill_box(dev, 64, 4, 8, 8, 0, 255, 0);
858
859 /* Draw bars indicating number of buffers allocated
860 * (not a great measure, easily confused)
861 */
862 if (dev_priv->dma_used) {
863 int bar = dev_priv->dma_used / 10240;
864 if (bar > 100)
865 bar = 100;
866 if (bar < 1)
867 bar = 1;
868 i830_fill_box(dev, 4, 16, bar, 4, 196, 128, 128);
869 dev_priv->dma_used = 0;
870 }
871
872 dev_priv->sarea_priv->perf_boxes = 0;
873}
874
875static void i830_dma_dispatch_clear(struct drm_device * dev, int flags,
876 unsigned int clear_color,
877 unsigned int clear_zval,
878 unsigned int clear_depthmask)
879{
880 drm_i830_private_t *dev_priv = dev->dev_private;
881 drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv;
882 int nbox = sarea_priv->nbox;
883 struct drm_clip_rect *pbox = sarea_priv->boxes;
884 int pitch = dev_priv->pitch;
885 int cpp = dev_priv->cpp;
886 int i;
887 unsigned int BR13, CMD, D_CMD;
888 RING_LOCALS;
889
890 if (dev_priv->current_page == 1) {
891 unsigned int tmp = flags;
892
893 flags &= ~(I830_FRONT | I830_BACK);
894 if (tmp & I830_FRONT)
895 flags |= I830_BACK;
896 if (tmp & I830_BACK)
897 flags |= I830_FRONT;
898 }
899
900 i830_kernel_lost_context(dev);
901
902 switch (cpp) {
903 case 2:
904 BR13 = (0xF0 << 16) | (pitch * cpp) | (1 << 24);
905 D_CMD = CMD = XY_COLOR_BLT_CMD;
906 break;
907 case 4:
908 BR13 = (0xF0 << 16) | (pitch * cpp) | (1 << 24) | (1 << 25);
909 CMD = (XY_COLOR_BLT_CMD | XY_COLOR_BLT_WRITE_ALPHA |
910 XY_COLOR_BLT_WRITE_RGB);
911 D_CMD = XY_COLOR_BLT_CMD;
912 if (clear_depthmask & 0x00ffffff)
913 D_CMD |= XY_COLOR_BLT_WRITE_RGB;
914 if (clear_depthmask & 0xff000000)
915 D_CMD |= XY_COLOR_BLT_WRITE_ALPHA;
916 break;
917 default:
918 BR13 = (0xF0 << 16) | (pitch * cpp) | (1 << 24);
919 D_CMD = CMD = XY_COLOR_BLT_CMD;
920 break;
921 }
922
923 if (nbox > I830_NR_SAREA_CLIPRECTS)
924 nbox = I830_NR_SAREA_CLIPRECTS;
925
926 for (i = 0; i < nbox; i++, pbox++) {
927 if (pbox->x1 > pbox->x2 ||
928 pbox->y1 > pbox->y2 ||
929 pbox->x2 > dev_priv->w || pbox->y2 > dev_priv->h)
930 continue;
931
932 if (flags & I830_FRONT) {
933 DRM_DEBUG("clear front\n");
934 BEGIN_LP_RING(6);
935 OUT_RING(CMD);
936 OUT_RING(BR13);
937 OUT_RING((pbox->y1 << 16) | pbox->x1);
938 OUT_RING((pbox->y2 << 16) | pbox->x2);
939 OUT_RING(dev_priv->front_offset);
940 OUT_RING(clear_color);
941 ADVANCE_LP_RING();
942 }
943
944 if (flags & I830_BACK) {
945 DRM_DEBUG("clear back\n");
946 BEGIN_LP_RING(6);
947 OUT_RING(CMD);
948 OUT_RING(BR13);
949 OUT_RING((pbox->y1 << 16) | pbox->x1);
950 OUT_RING((pbox->y2 << 16) | pbox->x2);
951 OUT_RING(dev_priv->back_offset);
952 OUT_RING(clear_color);
953 ADVANCE_LP_RING();
954 }
955
956 if (flags & I830_DEPTH) {
957 DRM_DEBUG("clear depth\n");
958 BEGIN_LP_RING(6);
959 OUT_RING(D_CMD);
960 OUT_RING(BR13);
961 OUT_RING((pbox->y1 << 16) | pbox->x1);
962 OUT_RING((pbox->y2 << 16) | pbox->x2);
963 OUT_RING(dev_priv->depth_offset);
964 OUT_RING(clear_zval);
965 ADVANCE_LP_RING();
966 }
967 }
968}
969
970static void i830_dma_dispatch_swap(struct drm_device * dev)
971{
972 drm_i830_private_t *dev_priv = dev->dev_private;
973 drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv;
974 int nbox = sarea_priv->nbox;
975 struct drm_clip_rect *pbox = sarea_priv->boxes;
976 int pitch = dev_priv->pitch;
977 int cpp = dev_priv->cpp;
978 int i;
979 unsigned int CMD, BR13;
980 RING_LOCALS;
981
982 DRM_DEBUG("swapbuffers\n");
983
984 i830_kernel_lost_context(dev);
985
986 if (dev_priv->do_boxes)
987 i830_cp_performance_boxes(dev);
988
989 switch (cpp) {
990 case 2:
991 BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24);
992 CMD = XY_SRC_COPY_BLT_CMD;
993 break;
994 case 4:
995 BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24) | (1 << 25);
996 CMD = (XY_SRC_COPY_BLT_CMD | XY_SRC_COPY_BLT_WRITE_ALPHA |
997 XY_SRC_COPY_BLT_WRITE_RGB);
998 break;
999 default:
1000 BR13 = (pitch * cpp) | (0xCC << 16) | (1 << 24);
1001 CMD = XY_SRC_COPY_BLT_CMD;
1002 break;
1003 }
1004
1005 if (nbox > I830_NR_SAREA_CLIPRECTS)
1006 nbox = I830_NR_SAREA_CLIPRECTS;
1007
1008 for (i = 0; i < nbox; i++, pbox++) {
1009 if (pbox->x1 > pbox->x2 ||
1010 pbox->y1 > pbox->y2 ||
1011 pbox->x2 > dev_priv->w || pbox->y2 > dev_priv->h)
1012 continue;
1013
1014 DRM_DEBUG("dispatch swap %d,%d-%d,%d!\n",
1015 pbox->x1, pbox->y1, pbox->x2, pbox->y2);
1016
1017 BEGIN_LP_RING(8);
1018 OUT_RING(CMD);
1019 OUT_RING(BR13);
1020 OUT_RING((pbox->y1 << 16) | pbox->x1);
1021 OUT_RING((pbox->y2 << 16) | pbox->x2);
1022
1023 if (dev_priv->current_page == 0)
1024 OUT_RING(dev_priv->front_offset);
1025 else
1026 OUT_RING(dev_priv->back_offset);
1027
1028 OUT_RING((pbox->y1 << 16) | pbox->x1);
1029 OUT_RING(BR13 & 0xffff);
1030
1031 if (dev_priv->current_page == 0)
1032 OUT_RING(dev_priv->back_offset);
1033 else
1034 OUT_RING(dev_priv->front_offset);
1035
1036 ADVANCE_LP_RING();
1037 }
1038}
1039
1040static void i830_dma_dispatch_flip(struct drm_device * dev)
1041{
1042 drm_i830_private_t *dev_priv = dev->dev_private;
1043 RING_LOCALS;
1044
1045 DRM_DEBUG("%s: page=%d pfCurrentPage=%d\n",
1046 __func__,
1047 dev_priv->current_page,
1048 dev_priv->sarea_priv->pf_current_page);
1049
1050 i830_kernel_lost_context(dev);
1051
1052 if (dev_priv->do_boxes) {
1053 dev_priv->sarea_priv->perf_boxes |= I830_BOX_FLIP;
1054 i830_cp_performance_boxes(dev);
1055 }
1056
1057 BEGIN_LP_RING(2);
1058 OUT_RING(INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE);
1059 OUT_RING(0);
1060 ADVANCE_LP_RING();
1061
1062 BEGIN_LP_RING(6);
1063 OUT_RING(CMD_OP_DISPLAYBUFFER_INFO | ASYNC_FLIP);
1064 OUT_RING(0);
1065 if (dev_priv->current_page == 0) {
1066 OUT_RING(dev_priv->back_offset);
1067 dev_priv->current_page = 1;
1068 } else {
1069 OUT_RING(dev_priv->front_offset);
1070 dev_priv->current_page = 0;
1071 }
1072 OUT_RING(0);
1073 ADVANCE_LP_RING();
1074
1075 BEGIN_LP_RING(2);
1076 OUT_RING(MI_WAIT_FOR_EVENT | MI_WAIT_FOR_PLANE_A_FLIP);
1077 OUT_RING(0);
1078 ADVANCE_LP_RING();
1079
1080 dev_priv->sarea_priv->pf_current_page = dev_priv->current_page;
1081}
1082
1083static void i830_dma_dispatch_vertex(struct drm_device * dev,
1084 struct drm_buf * buf, int discard, int used)
1085{
1086 drm_i830_private_t *dev_priv = dev->dev_private;
1087 drm_i830_buf_priv_t *buf_priv = buf->dev_private;
1088 drm_i830_sarea_t *sarea_priv = dev_priv->sarea_priv;
1089 struct drm_clip_rect *box = sarea_priv->boxes;
1090 int nbox = sarea_priv->nbox;
1091 unsigned long address = (unsigned long)buf->bus_address;
1092 unsigned long start = address - dev->agp->base;
1093 int i = 0, u;
1094 RING_LOCALS;
1095
1096 i830_kernel_lost_context(dev);
1097
1098 if (nbox > I830_NR_SAREA_CLIPRECTS)
1099 nbox = I830_NR_SAREA_CLIPRECTS;
1100
1101 if (discard) {
1102 u = cmpxchg(buf_priv->in_use, I830_BUF_CLIENT,
1103 I830_BUF_HARDWARE);
1104 if (u != I830_BUF_CLIENT) {
1105 DRM_DEBUG("xxxx 2\n");
1106 }
1107 }
1108
1109 if (used > 4 * 1023)
1110 used = 0;
1111
1112 if (sarea_priv->dirty)
1113 i830EmitState(dev);
1114
1115 DRM_DEBUG("dispatch vertex addr 0x%lx, used 0x%x nbox %d\n",
1116 address, used, nbox);
1117
1118 dev_priv->counter++;
1119 DRM_DEBUG("dispatch counter : %ld\n", dev_priv->counter);
1120 DRM_DEBUG("i830_dma_dispatch\n");
1121 DRM_DEBUG("start : %lx\n", start);
1122 DRM_DEBUG("used : %d\n", used);
1123 DRM_DEBUG("start + used - 4 : %ld\n", start + used - 4);
1124
1125 if (buf_priv->currently_mapped == I830_BUF_MAPPED) {
1126 u32 *vp = buf_priv->kernel_virtual;
1127
1128 vp[0] = (GFX_OP_PRIMITIVE |
1129 sarea_priv->vertex_prim | ((used / 4) - 2));
1130
1131 if (dev_priv->use_mi_batchbuffer_start) {
1132 vp[used / 4] = MI_BATCH_BUFFER_END;
1133 used += 4;
1134 }
1135
1136 if (used & 4) {
1137 vp[used / 4] = 0;
1138 used += 4;
1139 }
1140
1141 i830_unmap_buffer(buf);
1142 }
1143
1144 if (used) {
1145 do {
1146 if (i < nbox) {
1147 BEGIN_LP_RING(6);
1148 OUT_RING(GFX_OP_DRAWRECT_INFO);
1149 OUT_RING(sarea_priv->
1150 BufferState[I830_DESTREG_DR1]);
1151 OUT_RING(box[i].x1 | (box[i].y1 << 16));
1152 OUT_RING(box[i].x2 | (box[i].y2 << 16));
1153 OUT_RING(sarea_priv->
1154 BufferState[I830_DESTREG_DR4]);
1155 OUT_RING(0);
1156 ADVANCE_LP_RING();
1157 }
1158
1159 if (dev_priv->use_mi_batchbuffer_start) {
1160 BEGIN_LP_RING(2);
1161 OUT_RING(MI_BATCH_BUFFER_START | (2 << 6));
1162 OUT_RING(start | MI_BATCH_NON_SECURE);
1163 ADVANCE_LP_RING();
1164 } else {
1165 BEGIN_LP_RING(4);
1166 OUT_RING(MI_BATCH_BUFFER);
1167 OUT_RING(start | MI_BATCH_NON_SECURE);
1168 OUT_RING(start + used - 4);
1169 OUT_RING(0);
1170 ADVANCE_LP_RING();
1171 }
1172
1173 } while (++i < nbox);
1174 }
1175
1176 if (discard) {
1177 dev_priv->counter++;
1178
1179 (void)cmpxchg(buf_priv->in_use, I830_BUF_CLIENT,
1180 I830_BUF_HARDWARE);
1181
1182 BEGIN_LP_RING(8);
1183 OUT_RING(CMD_STORE_DWORD_IDX);
1184 OUT_RING(20);
1185 OUT_RING(dev_priv->counter);
1186 OUT_RING(CMD_STORE_DWORD_IDX);
1187 OUT_RING(buf_priv->my_use_idx);
1188 OUT_RING(I830_BUF_FREE);
1189 OUT_RING(CMD_REPORT_HEAD);
1190 OUT_RING(0);
1191 ADVANCE_LP_RING();
1192 }
1193}
1194
1195static void i830_dma_quiescent(struct drm_device * dev)
1196{
1197 drm_i830_private_t *dev_priv = dev->dev_private;
1198 RING_LOCALS;
1199
1200 i830_kernel_lost_context(dev);
1201
1202 BEGIN_LP_RING(4);
1203 OUT_RING(INST_PARSER_CLIENT | INST_OP_FLUSH | INST_FLUSH_MAP_CACHE);
1204 OUT_RING(CMD_REPORT_HEAD);
1205 OUT_RING(0);
1206 OUT_RING(0);
1207 ADVANCE_LP_RING();
1208
1209 i830_wait_ring(dev, dev_priv->ring.Size - 8, __func__);
1210}
1211
1212static int i830_flush_queue(struct drm_device * dev)
1213{
1214 drm_i830_private_t *dev_priv = dev->dev_private;
1215 struct drm_device_dma *dma = dev->dma;
1216 int i, ret = 0;
1217 RING_LOCALS;
1218
1219 i830_kernel_lost_context(dev);
1220
1221 BEGIN_LP_RING(2);
1222 OUT_RING(CMD_REPORT_HEAD);
1223 OUT_RING(0);
1224 ADVANCE_LP_RING();
1225
1226 i830_wait_ring(dev, dev_priv->ring.Size - 8, __func__);
1227
1228 for (i = 0; i < dma->buf_count; i++) {
1229 struct drm_buf *buf = dma->buflist[i];
1230 drm_i830_buf_priv_t *buf_priv = buf->dev_private;
1231
1232 int used = cmpxchg(buf_priv->in_use, I830_BUF_HARDWARE,
1233 I830_BUF_FREE);
1234
1235 if (used == I830_BUF_HARDWARE)
1236 DRM_DEBUG("reclaimed from HARDWARE\n");
1237 if (used == I830_BUF_CLIENT)
1238 DRM_DEBUG("still on client\n");
1239 }
1240
1241 return ret;
1242}
1243
1244/* Must be called with the lock held */
1245static void i830_reclaim_buffers(struct drm_device * dev, struct drm_file *file_priv)
1246{
1247 struct drm_device_dma *dma = dev->dma;
1248 int i;
1249
1250 if (!dma)
1251 return;
1252 if (!dev->dev_private)
1253 return;
1254 if (!dma->buflist)
1255 return;
1256
1257 i830_flush_queue(dev);
1258
1259 for (i = 0; i < dma->buf_count; i++) {
1260 struct drm_buf *buf = dma->buflist[i];
1261 drm_i830_buf_priv_t *buf_priv = buf->dev_private;
1262
1263 if (buf->file_priv == file_priv && buf_priv) {
1264 int used = cmpxchg(buf_priv->in_use, I830_BUF_CLIENT,
1265 I830_BUF_FREE);
1266
1267 if (used == I830_BUF_CLIENT)
1268 DRM_DEBUG("reclaimed from client\n");
1269 if (buf_priv->currently_mapped == I830_BUF_MAPPED)
1270 buf_priv->currently_mapped = I830_BUF_UNMAPPED;
1271 }
1272 }
1273}
1274
1275static int i830_flush_ioctl(struct drm_device *dev, void *data,
1276 struct drm_file *file_priv)
1277{
1278 LOCK_TEST_WITH_RETURN(dev, file_priv);
1279
1280 i830_flush_queue(dev);
1281 return 0;
1282}
1283
1284static int i830_dma_vertex(struct drm_device *dev, void *data,
1285 struct drm_file *file_priv)
1286{
1287 struct drm_device_dma *dma = dev->dma;
1288 drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private;
1289 u32 *hw_status = dev_priv->hw_status_page;
1290 drm_i830_sarea_t *sarea_priv = (drm_i830_sarea_t *)
1291 dev_priv->sarea_priv;
1292 drm_i830_vertex_t *vertex = data;
1293
1294 LOCK_TEST_WITH_RETURN(dev, file_priv);
1295
1296 DRM_DEBUG("i830 dma vertex, idx %d used %d discard %d\n",
1297 vertex->idx, vertex->used, vertex->discard);
1298
1299 if (vertex->idx < 0 || vertex->idx > dma->buf_count)
1300 return -EINVAL;
1301
1302 i830_dma_dispatch_vertex(dev,
1303 dma->buflist[vertex->idx],
1304 vertex->discard, vertex->used);
1305
1306 sarea_priv->last_enqueue = dev_priv->counter - 1;
1307 sarea_priv->last_dispatch = (int)hw_status[5];
1308
1309 return 0;
1310}
1311
1312static int i830_clear_bufs(struct drm_device *dev, void *data,
1313 struct drm_file *file_priv)
1314{
1315 drm_i830_clear_t *clear = data;
1316
1317 LOCK_TEST_WITH_RETURN(dev, file_priv);
1318
1319 /* GH: Someone's doing nasty things... */
1320 if (!dev->dev_private) {
1321 return -EINVAL;
1322 }
1323
1324 i830_dma_dispatch_clear(dev, clear->flags,
1325 clear->clear_color,
1326 clear->clear_depth, clear->clear_depthmask);
1327 return 0;
1328}
1329
1330static int i830_swap_bufs(struct drm_device *dev, void *data,
1331 struct drm_file *file_priv)
1332{
1333 DRM_DEBUG("i830_swap_bufs\n");
1334
1335 LOCK_TEST_WITH_RETURN(dev, file_priv);
1336
1337 i830_dma_dispatch_swap(dev);
1338 return 0;
1339}
1340
1341/* Not sure why this isn't set all the time:
1342 */
1343static void i830_do_init_pageflip(struct drm_device * dev)
1344{
1345 drm_i830_private_t *dev_priv = dev->dev_private;
1346
1347 DRM_DEBUG("%s\n", __func__);
1348 dev_priv->page_flipping = 1;
1349 dev_priv->current_page = 0;
1350 dev_priv->sarea_priv->pf_current_page = dev_priv->current_page;
1351}
1352
1353static int i830_do_cleanup_pageflip(struct drm_device * dev)
1354{
1355 drm_i830_private_t *dev_priv = dev->dev_private;
1356
1357 DRM_DEBUG("%s\n", __func__);
1358 if (dev_priv->current_page != 0)
1359 i830_dma_dispatch_flip(dev);
1360
1361 dev_priv->page_flipping = 0;
1362 return 0;
1363}
1364
1365static int i830_flip_bufs(struct drm_device *dev, void *data,
1366 struct drm_file *file_priv)
1367{
1368 drm_i830_private_t *dev_priv = dev->dev_private;
1369
1370 DRM_DEBUG("%s\n", __func__);
1371
1372 LOCK_TEST_WITH_RETURN(dev, file_priv);
1373
1374 if (!dev_priv->page_flipping)
1375 i830_do_init_pageflip(dev);
1376
1377 i830_dma_dispatch_flip(dev);
1378 return 0;
1379}
1380
1381static int i830_getage(struct drm_device *dev, void *data,
1382 struct drm_file *file_priv)
1383{
1384 drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private;
1385 u32 *hw_status = dev_priv->hw_status_page;
1386 drm_i830_sarea_t *sarea_priv = (drm_i830_sarea_t *)
1387 dev_priv->sarea_priv;
1388
1389 sarea_priv->last_dispatch = (int)hw_status[5];
1390 return 0;
1391}
1392
1393static int i830_getbuf(struct drm_device *dev, void *data,
1394 struct drm_file *file_priv)
1395{
1396 int retcode = 0;
1397 drm_i830_dma_t *d = data;
1398 drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private;
1399 u32 *hw_status = dev_priv->hw_status_page;
1400 drm_i830_sarea_t *sarea_priv = (drm_i830_sarea_t *)
1401 dev_priv->sarea_priv;
1402
1403 DRM_DEBUG("getbuf\n");
1404
1405 LOCK_TEST_WITH_RETURN(dev, file_priv);
1406
1407 d->granted = 0;
1408
1409 retcode = i830_dma_get_buffer(dev, d, file_priv);
1410
1411 DRM_DEBUG("i830_dma: %d returning %d, granted = %d\n",
1412 task_pid_nr(current), retcode, d->granted);
1413
1414 sarea_priv->last_dispatch = (int)hw_status[5];
1415
1416 return retcode;
1417}
1418
1419static int i830_copybuf(struct drm_device *dev, void *data,
1420 struct drm_file *file_priv)
1421{
1422 /* Never copy - 2.4.x doesn't need it */
1423 return 0;
1424}
1425
1426static int i830_docopy(struct drm_device *dev, void *data,
1427 struct drm_file *file_priv)
1428{
1429 return 0;
1430}
1431
1432static int i830_getparam(struct drm_device *dev, void *data,
1433 struct drm_file *file_priv)
1434{
1435 drm_i830_private_t *dev_priv = dev->dev_private;
1436 drm_i830_getparam_t *param = data;
1437 int value;
1438
1439 if (!dev_priv) {
1440 DRM_ERROR("%s called with no initialization\n", __func__);
1441 return -EINVAL;
1442 }
1443
1444 switch (param->param) {
1445 case I830_PARAM_IRQ_ACTIVE:
1446 value = dev->irq_enabled;
1447 break;
1448 default:
1449 return -EINVAL;
1450 }
1451
1452 if (copy_to_user(param->value, &value, sizeof(int))) {
1453 DRM_ERROR("copy_to_user\n");
1454 return -EFAULT;
1455 }
1456
1457 return 0;
1458}
1459
1460static int i830_setparam(struct drm_device *dev, void *data,
1461 struct drm_file *file_priv)
1462{
1463 drm_i830_private_t *dev_priv = dev->dev_private;
1464 drm_i830_setparam_t *param = data;
1465
1466 if (!dev_priv) {
1467 DRM_ERROR("%s called with no initialization\n", __func__);
1468 return -EINVAL;
1469 }
1470
1471 switch (param->param) {
1472 case I830_SETPARAM_USE_MI_BATCHBUFFER_START:
1473 dev_priv->use_mi_batchbuffer_start = param->value;
1474 break;
1475 default:
1476 return -EINVAL;
1477 }
1478
1479 return 0;
1480}
1481
1482int i830_driver_load(struct drm_device *dev, unsigned long flags)
1483{
1484 /* i830 has 4 more counters */
1485 dev->counters += 4;
1486 dev->types[6] = _DRM_STAT_IRQ;
1487 dev->types[7] = _DRM_STAT_PRIMARY;
1488 dev->types[8] = _DRM_STAT_SECONDARY;
1489 dev->types[9] = _DRM_STAT_DMA;
1490
1491 return 0;
1492}
1493
1494void i830_driver_lastclose(struct drm_device * dev)
1495{
1496 i830_dma_cleanup(dev);
1497}
1498
1499void i830_driver_preclose(struct drm_device * dev, struct drm_file *file_priv)
1500{
1501 if (dev->dev_private) {
1502 drm_i830_private_t *dev_priv = dev->dev_private;
1503 if (dev_priv->page_flipping) {
1504 i830_do_cleanup_pageflip(dev);
1505 }
1506 }
1507}
1508
1509void i830_driver_reclaim_buffers_locked(struct drm_device * dev, struct drm_file *file_priv)
1510{
1511 i830_reclaim_buffers(dev, file_priv);
1512}
1513
1514int i830_driver_dma_quiescent(struct drm_device * dev)
1515{
1516 i830_dma_quiescent(dev);
1517 return 0;
1518}
1519
1520struct drm_ioctl_desc i830_ioctls[] = {
1521 DRM_IOCTL_DEF(DRM_I830_INIT, i830_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
1522 DRM_IOCTL_DEF(DRM_I830_VERTEX, i830_dma_vertex, DRM_AUTH),
1523 DRM_IOCTL_DEF(DRM_I830_CLEAR, i830_clear_bufs, DRM_AUTH),
1524 DRM_IOCTL_DEF(DRM_I830_FLUSH, i830_flush_ioctl, DRM_AUTH),
1525 DRM_IOCTL_DEF(DRM_I830_GETAGE, i830_getage, DRM_AUTH),
1526 DRM_IOCTL_DEF(DRM_I830_GETBUF, i830_getbuf, DRM_AUTH),
1527 DRM_IOCTL_DEF(DRM_I830_SWAP, i830_swap_bufs, DRM_AUTH),
1528 DRM_IOCTL_DEF(DRM_I830_COPY, i830_copybuf, DRM_AUTH),
1529 DRM_IOCTL_DEF(DRM_I830_DOCOPY, i830_docopy, DRM_AUTH),
1530 DRM_IOCTL_DEF(DRM_I830_FLIP, i830_flip_bufs, DRM_AUTH),
1531 DRM_IOCTL_DEF(DRM_I830_IRQ_EMIT, i830_irq_emit, DRM_AUTH),
1532 DRM_IOCTL_DEF(DRM_I830_IRQ_WAIT, i830_irq_wait, DRM_AUTH),
1533 DRM_IOCTL_DEF(DRM_I830_GETPARAM, i830_getparam, DRM_AUTH),
1534 DRM_IOCTL_DEF(DRM_I830_SETPARAM, i830_setparam, DRM_AUTH)
1535};
1536
1537int i830_max_ioctl = DRM_ARRAY_SIZE(i830_ioctls);
1538
1539/**
1540 * Determine if the device really is AGP or not.
1541 *
1542 * All Intel graphics chipsets are treated as AGP, even if they are really
1543 * PCI-e.
1544 *
1545 * \param dev The device to be tested.
1546 *
1547 * \returns
1548 * A value of 1 is always retured to indictate every i8xx is AGP.
1549 */
1550int i830_driver_device_is_agp(struct drm_device * dev)
1551{
1552 return 1;
1553}
diff --git a/drivers/char/drm/i830_drm.h b/drivers/char/drm/i830_drm.h
deleted file mode 100644
index 4b00d2dd4f68..000000000000
--- a/drivers/char/drm/i830_drm.h
+++ /dev/null
@@ -1,342 +0,0 @@
1#ifndef _I830_DRM_H_
2#define _I830_DRM_H_
3
4/* WARNING: These defines must be the same as what the Xserver uses.
5 * if you change them, you must change the defines in the Xserver.
6 *
7 * KW: Actually, you can't ever change them because doing so would
8 * break backwards compatibility.
9 */
10
11#ifndef _I830_DEFINES_
12#define _I830_DEFINES_
13
14#define I830_DMA_BUF_ORDER 12
15#define I830_DMA_BUF_SZ (1<<I830_DMA_BUF_ORDER)
16#define I830_DMA_BUF_NR 256
17#define I830_NR_SAREA_CLIPRECTS 8
18
19/* Each region is a minimum of 64k, and there are at most 64 of them.
20 */
21#define I830_NR_TEX_REGIONS 64
22#define I830_LOG_MIN_TEX_REGION_SIZE 16
23
24/* KW: These aren't correct but someone set them to two and then
25 * released the module. Now we can't change them as doing so would
26 * break backwards compatibility.
27 */
28#define I830_TEXTURE_COUNT 2
29#define I830_TEXBLEND_COUNT I830_TEXTURE_COUNT
30
31#define I830_TEXBLEND_SIZE 12 /* (4 args + op) * 2 + COLOR_FACTOR */
32
33#define I830_UPLOAD_CTX 0x1
34#define I830_UPLOAD_BUFFERS 0x2
35#define I830_UPLOAD_CLIPRECTS 0x4
36#define I830_UPLOAD_TEX0_IMAGE 0x100 /* handled clientside */
37#define I830_UPLOAD_TEX0_CUBE 0x200 /* handled clientside */
38#define I830_UPLOAD_TEX1_IMAGE 0x400 /* handled clientside */
39#define I830_UPLOAD_TEX1_CUBE 0x800 /* handled clientside */
40#define I830_UPLOAD_TEX2_IMAGE 0x1000 /* handled clientside */
41#define I830_UPLOAD_TEX2_CUBE 0x2000 /* handled clientside */
42#define I830_UPLOAD_TEX3_IMAGE 0x4000 /* handled clientside */
43#define I830_UPLOAD_TEX3_CUBE 0x8000 /* handled clientside */
44#define I830_UPLOAD_TEX_N_IMAGE(n) (0x100 << (n * 2))
45#define I830_UPLOAD_TEX_N_CUBE(n) (0x200 << (n * 2))
46#define I830_UPLOAD_TEXIMAGE_MASK 0xff00
47#define I830_UPLOAD_TEX0 0x10000
48#define I830_UPLOAD_TEX1 0x20000
49#define I830_UPLOAD_TEX2 0x40000
50#define I830_UPLOAD_TEX3 0x80000
51#define I830_UPLOAD_TEX_N(n) (0x10000 << (n))
52#define I830_UPLOAD_TEX_MASK 0xf0000
53#define I830_UPLOAD_TEXBLEND0 0x100000
54#define I830_UPLOAD_TEXBLEND1 0x200000
55#define I830_UPLOAD_TEXBLEND2 0x400000
56#define I830_UPLOAD_TEXBLEND3 0x800000
57#define I830_UPLOAD_TEXBLEND_N(n) (0x100000 << (n))
58#define I830_UPLOAD_TEXBLEND_MASK 0xf00000
59#define I830_UPLOAD_TEX_PALETTE_N(n) (0x1000000 << (n))
60#define I830_UPLOAD_TEX_PALETTE_SHARED 0x4000000
61#define I830_UPLOAD_STIPPLE 0x8000000
62
63/* Indices into buf.Setup where various bits of state are mirrored per
64 * context and per buffer. These can be fired at the card as a unit,
65 * or in a piecewise fashion as required.
66 */
67
68/* Destbuffer state
69 * - backbuffer linear offset and pitch -- invarient in the current dri
70 * - zbuffer linear offset and pitch -- also invarient
71 * - drawing origin in back and depth buffers.
72 *
73 * Keep the depth/back buffer state here to accommodate private buffers
74 * in the future.
75 */
76
77#define I830_DESTREG_CBUFADDR 0
78#define I830_DESTREG_DBUFADDR 1
79#define I830_DESTREG_DV0 2
80#define I830_DESTREG_DV1 3
81#define I830_DESTREG_SENABLE 4
82#define I830_DESTREG_SR0 5
83#define I830_DESTREG_SR1 6
84#define I830_DESTREG_SR2 7
85#define I830_DESTREG_DR0 8
86#define I830_DESTREG_DR1 9
87#define I830_DESTREG_DR2 10
88#define I830_DESTREG_DR3 11
89#define I830_DESTREG_DR4 12
90#define I830_DEST_SETUP_SIZE 13
91
92/* Context state
93 */
94#define I830_CTXREG_STATE1 0
95#define I830_CTXREG_STATE2 1
96#define I830_CTXREG_STATE3 2
97#define I830_CTXREG_STATE4 3
98#define I830_CTXREG_STATE5 4
99#define I830_CTXREG_IALPHAB 5
100#define I830_CTXREG_STENCILTST 6
101#define I830_CTXREG_ENABLES_1 7
102#define I830_CTXREG_ENABLES_2 8
103#define I830_CTXREG_AA 9
104#define I830_CTXREG_FOGCOLOR 10
105#define I830_CTXREG_BLENDCOLR0 11
106#define I830_CTXREG_BLENDCOLR 12 /* Dword 1 of 2 dword command */
107#define I830_CTXREG_VF 13
108#define I830_CTXREG_VF2 14
109#define I830_CTXREG_MCSB0 15
110#define I830_CTXREG_MCSB1 16
111#define I830_CTX_SETUP_SIZE 17
112
113/* 1.3: Stipple state
114 */
115#define I830_STPREG_ST0 0
116#define I830_STPREG_ST1 1
117#define I830_STP_SETUP_SIZE 2
118
119/* Texture state (per tex unit)
120 */
121
122#define I830_TEXREG_MI0 0 /* GFX_OP_MAP_INFO (6 dwords) */
123#define I830_TEXREG_MI1 1
124#define I830_TEXREG_MI2 2
125#define I830_TEXREG_MI3 3
126#define I830_TEXREG_MI4 4
127#define I830_TEXREG_MI5 5
128#define I830_TEXREG_MF 6 /* GFX_OP_MAP_FILTER */
129#define I830_TEXREG_MLC 7 /* GFX_OP_MAP_LOD_CTL */
130#define I830_TEXREG_MLL 8 /* GFX_OP_MAP_LOD_LIMITS */
131#define I830_TEXREG_MCS 9 /* GFX_OP_MAP_COORD_SETS */
132#define I830_TEX_SETUP_SIZE 10
133
134#define I830_TEXREG_TM0LI 0 /* load immediate 2 texture map n */
135#define I830_TEXREG_TM0S0 1
136#define I830_TEXREG_TM0S1 2
137#define I830_TEXREG_TM0S2 3
138#define I830_TEXREG_TM0S3 4
139#define I830_TEXREG_TM0S4 5
140#define I830_TEXREG_NOP0 6 /* noop */
141#define I830_TEXREG_NOP1 7 /* noop */
142#define I830_TEXREG_NOP2 8 /* noop */
143#define __I830_TEXREG_MCS 9 /* GFX_OP_MAP_COORD_SETS -- shared */
144#define __I830_TEX_SETUP_SIZE 10
145
146#define I830_FRONT 0x1
147#define I830_BACK 0x2
148#define I830_DEPTH 0x4
149
150#endif /* _I830_DEFINES_ */
151
152typedef struct _drm_i830_init {
153 enum {
154 I830_INIT_DMA = 0x01,
155 I830_CLEANUP_DMA = 0x02
156 } func;
157 unsigned int mmio_offset;
158 unsigned int buffers_offset;
159 int sarea_priv_offset;
160 unsigned int ring_start;
161 unsigned int ring_end;
162 unsigned int ring_size;
163 unsigned int front_offset;
164 unsigned int back_offset;
165 unsigned int depth_offset;
166 unsigned int w;
167 unsigned int h;
168 unsigned int pitch;
169 unsigned int pitch_bits;
170 unsigned int back_pitch;
171 unsigned int depth_pitch;
172 unsigned int cpp;
173} drm_i830_init_t;
174
175/* Warning: If you change the SAREA structure you must change the Xserver
176 * structure as well */
177
178typedef struct _drm_i830_tex_region {
179 unsigned char next, prev; /* indices to form a circular LRU */
180 unsigned char in_use; /* owned by a client, or free? */
181 int age; /* tracked by clients to update local LRU's */
182} drm_i830_tex_region_t;
183
184typedef struct _drm_i830_sarea {
185 unsigned int ContextState[I830_CTX_SETUP_SIZE];
186 unsigned int BufferState[I830_DEST_SETUP_SIZE];
187 unsigned int TexState[I830_TEXTURE_COUNT][I830_TEX_SETUP_SIZE];
188 unsigned int TexBlendState[I830_TEXBLEND_COUNT][I830_TEXBLEND_SIZE];
189 unsigned int TexBlendStateWordsUsed[I830_TEXBLEND_COUNT];
190 unsigned int Palette[2][256];
191 unsigned int dirty;
192
193 unsigned int nbox;
194 struct drm_clip_rect boxes[I830_NR_SAREA_CLIPRECTS];
195
196 /* Maintain an LRU of contiguous regions of texture space. If
197 * you think you own a region of texture memory, and it has an
198 * age different to the one you set, then you are mistaken and
199 * it has been stolen by another client. If global texAge
200 * hasn't changed, there is no need to walk the list.
201 *
202 * These regions can be used as a proxy for the fine-grained
203 * texture information of other clients - by maintaining them
204 * in the same lru which is used to age their own textures,
205 * clients have an approximate lru for the whole of global
206 * texture space, and can make informed decisions as to which
207 * areas to kick out. There is no need to choose whether to
208 * kick out your own texture or someone else's - simply eject
209 * them all in LRU order.
210 */
211
212 drm_i830_tex_region_t texList[I830_NR_TEX_REGIONS + 1];
213 /* Last elt is sentinal */
214 int texAge; /* last time texture was uploaded */
215 int last_enqueue; /* last time a buffer was enqueued */
216 int last_dispatch; /* age of the most recently dispatched buffer */
217 int last_quiescent; /* */
218 int ctxOwner; /* last context to upload state */
219
220 int vertex_prim;
221
222 int pf_enabled; /* is pageflipping allowed? */
223 int pf_active;
224 int pf_current_page; /* which buffer is being displayed? */
225
226 int perf_boxes; /* performance boxes to be displayed */
227
228 /* Here's the state for texunits 2,3:
229 */
230 unsigned int TexState2[I830_TEX_SETUP_SIZE];
231 unsigned int TexBlendState2[I830_TEXBLEND_SIZE];
232 unsigned int TexBlendStateWordsUsed2;
233
234 unsigned int TexState3[I830_TEX_SETUP_SIZE];
235 unsigned int TexBlendState3[I830_TEXBLEND_SIZE];
236 unsigned int TexBlendStateWordsUsed3;
237
238 unsigned int StippleState[I830_STP_SETUP_SIZE];
239} drm_i830_sarea_t;
240
241/* Flags for perf_boxes
242 */
243#define I830_BOX_RING_EMPTY 0x1 /* populated by kernel */
244#define I830_BOX_FLIP 0x2 /* populated by kernel */
245#define I830_BOX_WAIT 0x4 /* populated by kernel & client */
246#define I830_BOX_TEXTURE_LOAD 0x8 /* populated by kernel */
247#define I830_BOX_LOST_CONTEXT 0x10 /* populated by client */
248
249/* I830 specific ioctls
250 * The device specific ioctl range is 0x40 to 0x79.
251 */
252#define DRM_I830_INIT 0x00
253#define DRM_I830_VERTEX 0x01
254#define DRM_I830_CLEAR 0x02
255#define DRM_I830_FLUSH 0x03
256#define DRM_I830_GETAGE 0x04
257#define DRM_I830_GETBUF 0x05
258#define DRM_I830_SWAP 0x06
259#define DRM_I830_COPY 0x07
260#define DRM_I830_DOCOPY 0x08
261#define DRM_I830_FLIP 0x09
262#define DRM_I830_IRQ_EMIT 0x0a
263#define DRM_I830_IRQ_WAIT 0x0b
264#define DRM_I830_GETPARAM 0x0c
265#define DRM_I830_SETPARAM 0x0d
266
267#define DRM_IOCTL_I830_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_IOCTL_I830_INIT, drm_i830_init_t)
268#define DRM_IOCTL_I830_VERTEX DRM_IOW( DRM_COMMAND_BASE + DRM_IOCTL_I830_VERTEX, drm_i830_vertex_t)
269#define DRM_IOCTL_I830_CLEAR DRM_IOW( DRM_COMMAND_BASE + DRM_IOCTL_I830_CLEAR, drm_i830_clear_t)
270#define DRM_IOCTL_I830_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_IOCTL_I830_FLUSH)
271#define DRM_IOCTL_I830_GETAGE DRM_IO ( DRM_COMMAND_BASE + DRM_IOCTL_I830_GETAGE)
272#define DRM_IOCTL_I830_GETBUF DRM_IOWR(DRM_COMMAND_BASE + DRM_IOCTL_I830_GETBUF, drm_i830_dma_t)
273#define DRM_IOCTL_I830_SWAP DRM_IO ( DRM_COMMAND_BASE + DRM_IOCTL_I830_SWAP)
274#define DRM_IOCTL_I830_COPY DRM_IOW( DRM_COMMAND_BASE + DRM_IOCTL_I830_COPY, drm_i830_copy_t)
275#define DRM_IOCTL_I830_DOCOPY DRM_IO ( DRM_COMMAND_BASE + DRM_IOCTL_I830_DOCOPY)
276#define DRM_IOCTL_I830_FLIP DRM_IO ( DRM_COMMAND_BASE + DRM_IOCTL_I830_FLIP)
277#define DRM_IOCTL_I830_IRQ_EMIT DRM_IOWR(DRM_COMMAND_BASE + DRM_IOCTL_I830_IRQ_EMIT, drm_i830_irq_emit_t)
278#define DRM_IOCTL_I830_IRQ_WAIT DRM_IOW( DRM_COMMAND_BASE + DRM_IOCTL_I830_IRQ_WAIT, drm_i830_irq_wait_t)
279#define DRM_IOCTL_I830_GETPARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_IOCTL_I830_GETPARAM, drm_i830_getparam_t)
280#define DRM_IOCTL_I830_SETPARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_IOCTL_I830_SETPARAM, drm_i830_setparam_t)
281
282typedef struct _drm_i830_clear {
283 int clear_color;
284 int clear_depth;
285 int flags;
286 unsigned int clear_colormask;
287 unsigned int clear_depthmask;
288} drm_i830_clear_t;
289
290/* These may be placeholders if we have more cliprects than
291 * I830_NR_SAREA_CLIPRECTS. In that case, the client sets discard to
292 * false, indicating that the buffer will be dispatched again with a
293 * new set of cliprects.
294 */
295typedef struct _drm_i830_vertex {
296 int idx; /* buffer index */
297 int used; /* nr bytes in use */
298 int discard; /* client is finished with the buffer? */
299} drm_i830_vertex_t;
300
301typedef struct _drm_i830_copy_t {
302 int idx; /* buffer index */
303 int used; /* nr bytes in use */
304 void __user *address; /* Address to copy from */
305} drm_i830_copy_t;
306
307typedef struct drm_i830_dma {
308 void __user *virtual;
309 int request_idx;
310 int request_size;
311 int granted;
312} drm_i830_dma_t;
313
314/* 1.3: Userspace can request & wait on irq's:
315 */
316typedef struct drm_i830_irq_emit {
317 int __user *irq_seq;
318} drm_i830_irq_emit_t;
319
320typedef struct drm_i830_irq_wait {
321 int irq_seq;
322} drm_i830_irq_wait_t;
323
324/* 1.3: New ioctl to query kernel params:
325 */
326#define I830_PARAM_IRQ_ACTIVE 1
327
328typedef struct drm_i830_getparam {
329 int param;
330 int __user *value;
331} drm_i830_getparam_t;
332
333/* 1.3: New ioctl to set kernel params:
334 */
335#define I830_SETPARAM_USE_MI_BATCHBUFFER_START 1
336
337typedef struct drm_i830_setparam {
338 int param;
339 int value;
340} drm_i830_setparam_t;
341
342#endif /* _I830_DRM_H_ */
diff --git a/drivers/char/drm/i830_drv.c b/drivers/char/drm/i830_drv.c
deleted file mode 100644
index 389597e4a623..000000000000
--- a/drivers/char/drm/i830_drv.c
+++ /dev/null
@@ -1,108 +0,0 @@
1/* i830_drv.c -- I810 driver -*- linux-c -*-
2 * Created: Mon Dec 13 01:56:22 1999 by jhartmann@precisioninsight.com
3 *
4 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
5 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
6 * All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice (including the next
16 * paragraph) shall be included in all copies or substantial portions of the
17 * Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
23 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25 * OTHER DEALINGS IN THE SOFTWARE.
26 *
27 * Authors:
28 * Rickard E. (Rik) Faith <faith@valinux.com>
29 * Jeff Hartmann <jhartmann@valinux.com>
30 * Gareth Hughes <gareth@valinux.com>
31 * Abraham vd Merwe <abraham@2d3d.co.za>
32 * Keith Whitwell <keith@tungstengraphics.com>
33 */
34
35#include "drmP.h"
36#include "drm.h"
37#include "i830_drm.h"
38#include "i830_drv.h"
39
40#include "drm_pciids.h"
41
42static struct pci_device_id pciidlist[] = {
43 i830_PCI_IDS
44};
45
46static struct drm_driver driver = {
47 .driver_features =
48 DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | DRIVER_USE_MTRR |
49 DRIVER_HAVE_DMA | DRIVER_DMA_QUEUE,
50#if USE_IRQS
51 .driver_features |= DRIVER_HAVE_IRQ | DRIVER_SHARED_IRQ,
52#endif
53 .dev_priv_size = sizeof(drm_i830_buf_priv_t),
54 .load = i830_driver_load,
55 .lastclose = i830_driver_lastclose,
56 .preclose = i830_driver_preclose,
57 .device_is_agp = i830_driver_device_is_agp,
58 .reclaim_buffers_locked = i830_driver_reclaim_buffers_locked,
59 .dma_quiescent = i830_driver_dma_quiescent,
60 .get_map_ofs = drm_core_get_map_ofs,
61 .get_reg_ofs = drm_core_get_reg_ofs,
62#if USE_IRQS
63 .irq_preinstall = i830_driver_irq_preinstall,
64 .irq_postinstall = i830_driver_irq_postinstall,
65 .irq_uninstall = i830_driver_irq_uninstall,
66 .irq_handler = i830_driver_irq_handler,
67#endif
68 .ioctls = i830_ioctls,
69 .fops = {
70 .owner = THIS_MODULE,
71 .open = drm_open,
72 .release = drm_release,
73 .ioctl = drm_ioctl,
74 .mmap = drm_mmap,
75 .poll = drm_poll,
76 .fasync = drm_fasync,
77 },
78
79 .pci_driver = {
80 .name = DRIVER_NAME,
81 .id_table = pciidlist,
82 },
83
84 .name = DRIVER_NAME,
85 .desc = DRIVER_DESC,
86 .date = DRIVER_DATE,
87 .major = DRIVER_MAJOR,
88 .minor = DRIVER_MINOR,
89 .patchlevel = DRIVER_PATCHLEVEL,
90};
91
92static int __init i830_init(void)
93{
94 driver.num_ioctls = i830_max_ioctl;
95 return drm_init(&driver);
96}
97
98static void __exit i830_exit(void)
99{
100 drm_exit(&driver);
101}
102
103module_init(i830_init);
104module_exit(i830_exit);
105
106MODULE_AUTHOR(DRIVER_AUTHOR);
107MODULE_DESCRIPTION(DRIVER_DESC);
108MODULE_LICENSE("GPL and additional rights");
diff --git a/drivers/char/drm/i830_drv.h b/drivers/char/drm/i830_drv.h
deleted file mode 100644
index b5bf8cc0fdaa..000000000000
--- a/drivers/char/drm/i830_drv.h
+++ /dev/null
@@ -1,292 +0,0 @@
1/* i830_drv.h -- Private header for the I830 driver -*- linux-c -*-
2 * Created: Mon Dec 13 01:50:01 1999 by jhartmann@precisioninsight.com
3 *
4 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
5 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
6 * All rights reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice (including the next
16 * paragraph) shall be included in all copies or substantial portions of the
17 * Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
23 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 * DEALINGS IN THE SOFTWARE.
26 *
27 * Authors: Rickard E. (Rik) Faith <faith@valinux.com>
28 * Jeff Hartmann <jhartmann@valinux.com>
29 *
30 */
31
32#ifndef _I830_DRV_H_
33#define _I830_DRV_H_
34
35/* General customization:
36 */
37
38#define DRIVER_AUTHOR "VA Linux Systems Inc."
39
40#define DRIVER_NAME "i830"
41#define DRIVER_DESC "Intel 830M"
42#define DRIVER_DATE "20021108"
43
44/* Interface history:
45 *
46 * 1.1: Original.
47 * 1.2: ?
48 * 1.3: New irq emit/wait ioctls.
49 * New pageflip ioctl.
50 * New getparam ioctl.
51 * State for texunits 3&4 in sarea.
52 * New (alternative) layout for texture state.
53 */
54#define DRIVER_MAJOR 1
55#define DRIVER_MINOR 3
56#define DRIVER_PATCHLEVEL 2
57
58/* Driver will work either way: IRQ's save cpu time when waiting for
59 * the card, but are subject to subtle interactions between bios,
60 * hardware and the driver.
61 */
62/* XXX: Add vblank support? */
63#define USE_IRQS 0
64
65typedef struct drm_i830_buf_priv {
66 u32 *in_use;
67 int my_use_idx;
68 int currently_mapped;
69 void __user *virtual;
70 void *kernel_virtual;
71 drm_local_map_t map;
72} drm_i830_buf_priv_t;
73
74typedef struct _drm_i830_ring_buffer {
75 int tail_mask;
76 unsigned long Start;
77 unsigned long End;
78 unsigned long Size;
79 u8 *virtual_start;
80 int head;
81 int tail;
82 int space;
83 drm_local_map_t map;
84} drm_i830_ring_buffer_t;
85
86typedef struct drm_i830_private {
87 struct drm_map *sarea_map;
88 struct drm_map *mmio_map;
89
90 drm_i830_sarea_t *sarea_priv;
91 drm_i830_ring_buffer_t ring;
92
93 void *hw_status_page;
94 unsigned long counter;
95
96 dma_addr_t dma_status_page;
97
98 struct drm_buf *mmap_buffer;
99
100 u32 front_di1, back_di1, zi1;
101
102 int back_offset;
103 int depth_offset;
104 int front_offset;
105 int w, h;
106 int pitch;
107 int back_pitch;
108 int depth_pitch;
109 unsigned int cpp;
110
111 int do_boxes;
112 int dma_used;
113
114 int current_page;
115 int page_flipping;
116
117 wait_queue_head_t irq_queue;
118 atomic_t irq_received;
119 atomic_t irq_emitted;
120
121 int use_mi_batchbuffer_start;
122
123} drm_i830_private_t;
124
125extern struct drm_ioctl_desc i830_ioctls[];
126extern int i830_max_ioctl;
127
128/* i830_irq.c */
129extern int i830_irq_emit(struct drm_device *dev, void *data,
130 struct drm_file *file_priv);
131extern int i830_irq_wait(struct drm_device *dev, void *data,
132 struct drm_file *file_priv);
133
134extern irqreturn_t i830_driver_irq_handler(DRM_IRQ_ARGS);
135extern void i830_driver_irq_preinstall(struct drm_device * dev);
136extern void i830_driver_irq_postinstall(struct drm_device * dev);
137extern void i830_driver_irq_uninstall(struct drm_device * dev);
138extern int i830_driver_load(struct drm_device *, unsigned long flags);
139extern void i830_driver_preclose(struct drm_device * dev,
140 struct drm_file *file_priv);
141extern void i830_driver_lastclose(struct drm_device * dev);
142extern void i830_driver_reclaim_buffers_locked(struct drm_device * dev,
143 struct drm_file *file_priv);
144extern int i830_driver_dma_quiescent(struct drm_device * dev);
145extern int i830_driver_device_is_agp(struct drm_device * dev);
146
147#define I830_READ(reg) DRM_READ32(dev_priv->mmio_map, reg)
148#define I830_WRITE(reg,val) DRM_WRITE32(dev_priv->mmio_map, reg, val)
149#define I830_READ16(reg) DRM_READ16(dev_priv->mmio_map, reg)
150#define I830_WRITE16(reg,val) DRM_WRITE16(dev_priv->mmio_map, reg, val)
151
152#define I830_VERBOSE 0
153
154#define RING_LOCALS unsigned int outring, ringmask, outcount; \
155 volatile char *virt;
156
157#define BEGIN_LP_RING(n) do { \
158 if (I830_VERBOSE) \
159 printk("BEGIN_LP_RING(%d)\n", (n)); \
160 if (dev_priv->ring.space < n*4) \
161 i830_wait_ring(dev, n*4, __func__); \
162 outcount = 0; \
163 outring = dev_priv->ring.tail; \
164 ringmask = dev_priv->ring.tail_mask; \
165 virt = dev_priv->ring.virtual_start; \
166} while (0)
167
168#define OUT_RING(n) do { \
169 if (I830_VERBOSE) printk(" OUT_RING %x\n", (int)(n)); \
170 *(volatile unsigned int *)(virt + outring) = n; \
171 outcount++; \
172 outring += 4; \
173 outring &= ringmask; \
174} while (0)
175
176#define ADVANCE_LP_RING() do { \
177 if (I830_VERBOSE) printk("ADVANCE_LP_RING %x\n", outring); \
178 dev_priv->ring.tail = outring; \
179 dev_priv->ring.space -= outcount * 4; \
180 I830_WRITE(LP_RING + RING_TAIL, outring); \
181} while(0)
182
183extern int i830_wait_ring(struct drm_device * dev, int n, const char *caller);
184
185#define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23))
186#define GFX_OP_BREAKPOINT_INTERRUPT ((0<<29)|(1<<23))
187#define CMD_REPORT_HEAD (7<<23)
188#define CMD_STORE_DWORD_IDX ((0x21<<23) | 0x1)
189#define CMD_OP_BATCH_BUFFER ((0x0<<29)|(0x30<<23)|0x1)
190
191#define STATE3D_LOAD_STATE_IMMEDIATE_2 ((0x3<<29)|(0x1d<<24)|(0x03<<16))
192#define LOAD_TEXTURE_MAP0 (1<<11)
193
194#define INST_PARSER_CLIENT 0x00000000
195#define INST_OP_FLUSH 0x02000000
196#define INST_FLUSH_MAP_CACHE 0x00000001
197
198#define BB1_START_ADDR_MASK (~0x7)
199#define BB1_PROTECTED (1<<0)
200#define BB1_UNPROTECTED (0<<0)
201#define BB2_END_ADDR_MASK (~0x7)
202
203#define I830REG_HWSTAM 0x02098
204#define I830REG_INT_IDENTITY_R 0x020a4
205#define I830REG_INT_MASK_R 0x020a8
206#define I830REG_INT_ENABLE_R 0x020a0
207
208#define I830_IRQ_RESERVED ((1<<13)|(3<<2))
209
210#define LP_RING 0x2030
211#define HP_RING 0x2040
212#define RING_TAIL 0x00
213#define TAIL_ADDR 0x001FFFF8
214#define RING_HEAD 0x04
215#define HEAD_WRAP_COUNT 0xFFE00000
216#define HEAD_WRAP_ONE 0x00200000
217#define HEAD_ADDR 0x001FFFFC
218#define RING_START 0x08
219#define START_ADDR 0x0xFFFFF000
220#define RING_LEN 0x0C
221#define RING_NR_PAGES 0x001FF000
222#define RING_REPORT_MASK 0x00000006
223#define RING_REPORT_64K 0x00000002
224#define RING_REPORT_128K 0x00000004
225#define RING_NO_REPORT 0x00000000
226#define RING_VALID_MASK 0x00000001
227#define RING_VALID 0x00000001
228#define RING_INVALID 0x00000000
229
230#define GFX_OP_SCISSOR ((0x3<<29)|(0x1c<<24)|(0x10<<19))
231#define SC_UPDATE_SCISSOR (0x1<<1)
232#define SC_ENABLE_MASK (0x1<<0)
233#define SC_ENABLE (0x1<<0)
234
235#define GFX_OP_SCISSOR_INFO ((0x3<<29)|(0x1d<<24)|(0x81<<16)|(0x1))
236#define SCI_YMIN_MASK (0xffff<<16)
237#define SCI_XMIN_MASK (0xffff<<0)
238#define SCI_YMAX_MASK (0xffff<<16)
239#define SCI_XMAX_MASK (0xffff<<0)
240
241#define GFX_OP_SCISSOR_ENABLE ((0x3<<29)|(0x1c<<24)|(0x10<<19))
242#define GFX_OP_SCISSOR_RECT ((0x3<<29)|(0x1d<<24)|(0x81<<16)|1)
243#define GFX_OP_COLOR_FACTOR ((0x3<<29)|(0x1d<<24)|(0x1<<16)|0x0)
244#define GFX_OP_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16))
245#define GFX_OP_MAP_INFO ((0x3<<29)|(0x1d<<24)|0x4)
246#define GFX_OP_DESTBUFFER_VARS ((0x3<<29)|(0x1d<<24)|(0x85<<16)|0x0)
247#define GFX_OP_DRAWRECT_INFO ((0x3<<29)|(0x1d<<24)|(0x80<<16)|(0x3))
248#define GFX_OP_PRIMITIVE ((0x3<<29)|(0x1f<<24))
249
250#define CMD_OP_DESTBUFFER_INFO ((0x3<<29)|(0x1d<<24)|(0x8e<<16)|1)
251
252#define CMD_OP_DISPLAYBUFFER_INFO ((0x0<<29)|(0x14<<23)|2)
253#define ASYNC_FLIP (1<<22)
254
255#define CMD_3D (0x3<<29)
256#define STATE3D_CONST_BLEND_COLOR_CMD (CMD_3D|(0x1d<<24)|(0x88<<16))
257#define STATE3D_MAP_COORD_SETBIND_CMD (CMD_3D|(0x1d<<24)|(0x02<<16))
258
259#define BR00_BITBLT_CLIENT 0x40000000
260#define BR00_OP_COLOR_BLT 0x10000000
261#define BR00_OP_SRC_COPY_BLT 0x10C00000
262#define BR13_SOLID_PATTERN 0x80000000
263
264#define BUF_3D_ID_COLOR_BACK (0x3<<24)
265#define BUF_3D_ID_DEPTH (0x7<<24)
266#define BUF_3D_USE_FENCE (1<<23)
267#define BUF_3D_PITCH(x) (((x)/4)<<2)
268
269#define CMD_OP_MAP_PALETTE_LOAD ((3<<29)|(0x1d<<24)|(0x82<<16)|255)
270#define MAP_PALETTE_NUM(x) ((x<<8) & (1<<8))
271#define MAP_PALETTE_BOTH (1<<11)
272
273#define XY_COLOR_BLT_CMD ((2<<29)|(0x50<<22)|0x4)
274#define XY_COLOR_BLT_WRITE_ALPHA (1<<21)
275#define XY_COLOR_BLT_WRITE_RGB (1<<20)
276
277#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6)
278#define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21)
279#define XY_SRC_COPY_BLT_WRITE_RGB (1<<20)
280
281#define MI_BATCH_BUFFER ((0x30<<23)|1)
282#define MI_BATCH_BUFFER_START (0x31<<23)
283#define MI_BATCH_BUFFER_END (0xA<<23)
284#define MI_BATCH_NON_SECURE (1)
285
286#define MI_WAIT_FOR_EVENT ((0x3<<23))
287#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2)
288#define MI_WAIT_FOR_PLANE_A_SCANLINES (1<<1)
289
290#define MI_LOAD_SCAN_LINES_INCL ((0x12<<23))
291
292#endif
diff --git a/drivers/char/drm/i830_irq.c b/drivers/char/drm/i830_irq.c
deleted file mode 100644
index 91ec2bb497e9..000000000000
--- a/drivers/char/drm/i830_irq.c
+++ /dev/null
@@ -1,186 +0,0 @@
1/* i830_dma.c -- DMA support for the I830 -*- linux-c -*-
2 *
3 * Copyright 2002 Tungsten Graphics, Inc.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the next
14 * paragraph) shall be included in all copies or substantial portions of the
15 * Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 * DEALINGS IN THE SOFTWARE.
24 *
25 * Authors: Keith Whitwell <keith@tungstengraphics.com>
26 *
27 */
28
29#include "drmP.h"
30#include "drm.h"
31#include "i830_drm.h"
32#include "i830_drv.h"
33#include <linux/interrupt.h> /* For task queue support */
34#include <linux/delay.h>
35
36irqreturn_t i830_driver_irq_handler(DRM_IRQ_ARGS)
37{
38 struct drm_device *dev = (struct drm_device *) arg;
39 drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private;
40 u16 temp;
41
42 temp = I830_READ16(I830REG_INT_IDENTITY_R);
43 DRM_DEBUG("%x\n", temp);
44
45 if (!(temp & 2))
46 return IRQ_NONE;
47
48 I830_WRITE16(I830REG_INT_IDENTITY_R, temp);
49
50 atomic_inc(&dev_priv->irq_received);
51 wake_up_interruptible(&dev_priv->irq_queue);
52
53 return IRQ_HANDLED;
54}
55
56static int i830_emit_irq(struct drm_device * dev)
57{
58 drm_i830_private_t *dev_priv = dev->dev_private;
59 RING_LOCALS;
60
61 DRM_DEBUG("%s\n", __func__);
62
63 atomic_inc(&dev_priv->irq_emitted);
64
65 BEGIN_LP_RING(2);
66 OUT_RING(0);
67 OUT_RING(GFX_OP_USER_INTERRUPT);
68 ADVANCE_LP_RING();
69
70 return atomic_read(&dev_priv->irq_emitted);
71}
72
73static int i830_wait_irq(struct drm_device * dev, int irq_nr)
74{
75 drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private;
76 DECLARE_WAITQUEUE(entry, current);
77 unsigned long end = jiffies + HZ * 3;
78 int ret = 0;
79
80 DRM_DEBUG("%s\n", __func__);
81
82 if (atomic_read(&dev_priv->irq_received) >= irq_nr)
83 return 0;
84
85 dev_priv->sarea_priv->perf_boxes |= I830_BOX_WAIT;
86
87 add_wait_queue(&dev_priv->irq_queue, &entry);
88
89 for (;;) {
90 __set_current_state(TASK_INTERRUPTIBLE);
91 if (atomic_read(&dev_priv->irq_received) >= irq_nr)
92 break;
93 if ((signed)(end - jiffies) <= 0) {
94 DRM_ERROR("timeout iir %x imr %x ier %x hwstam %x\n",
95 I830_READ16(I830REG_INT_IDENTITY_R),
96 I830_READ16(I830REG_INT_MASK_R),
97 I830_READ16(I830REG_INT_ENABLE_R),
98 I830_READ16(I830REG_HWSTAM));
99
100 ret = -EBUSY; /* Lockup? Missed irq? */
101 break;
102 }
103 schedule_timeout(HZ * 3);
104 if (signal_pending(current)) {
105 ret = -EINTR;
106 break;
107 }
108 }
109
110 __set_current_state(TASK_RUNNING);
111 remove_wait_queue(&dev_priv->irq_queue, &entry);
112 return ret;
113}
114
115/* Needs the lock as it touches the ring.
116 */
117int i830_irq_emit(struct drm_device *dev, void *data,
118 struct drm_file *file_priv)
119{
120 drm_i830_private_t *dev_priv = dev->dev_private;
121 drm_i830_irq_emit_t *emit = data;
122 int result;
123
124 LOCK_TEST_WITH_RETURN(dev, file_priv);
125
126 if (!dev_priv) {
127 DRM_ERROR("%s called with no initialization\n", __func__);
128 return -EINVAL;
129 }
130
131 result = i830_emit_irq(dev);
132
133 if (copy_to_user(emit->irq_seq, &result, sizeof(int))) {
134 DRM_ERROR("copy_to_user\n");
135 return -EFAULT;
136 }
137
138 return 0;
139}
140
141/* Doesn't need the hardware lock.
142 */
143int i830_irq_wait(struct drm_device *dev, void *data,
144 struct drm_file *file_priv)
145{
146 drm_i830_private_t *dev_priv = dev->dev_private;
147 drm_i830_irq_wait_t *irqwait = data;
148
149 if (!dev_priv) {
150 DRM_ERROR("%s called with no initialization\n", __func__);
151 return -EINVAL;
152 }
153
154 return i830_wait_irq(dev, irqwait->irq_seq);
155}
156
157/* drm_dma.h hooks
158*/
159void i830_driver_irq_preinstall(struct drm_device * dev)
160{
161 drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private;
162
163 I830_WRITE16(I830REG_HWSTAM, 0xffff);
164 I830_WRITE16(I830REG_INT_MASK_R, 0x0);
165 I830_WRITE16(I830REG_INT_ENABLE_R, 0x0);
166 atomic_set(&dev_priv->irq_received, 0);
167 atomic_set(&dev_priv->irq_emitted, 0);
168 init_waitqueue_head(&dev_priv->irq_queue);
169}
170
171void i830_driver_irq_postinstall(struct drm_device * dev)
172{
173 drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private;
174
175 I830_WRITE16(I830REG_INT_ENABLE_R, 0x2);
176}
177
178void i830_driver_irq_uninstall(struct drm_device * dev)
179{
180 drm_i830_private_t *dev_priv = (drm_i830_private_t *) dev->dev_private;
181 if (!dev_priv)
182 return;
183
184 I830_WRITE16(I830REG_INT_MASK_R, 0xffff);
185 I830_WRITE16(I830REG_INT_ENABLE_R, 0x0);
186}
diff --git a/drivers/char/drm/i915_dma.c b/drivers/char/drm/i915_dma.c
deleted file mode 100644
index f47e46e3529f..000000000000
--- a/drivers/char/drm/i915_dma.c
+++ /dev/null
@@ -1,936 +0,0 @@
1/* i915_dma.c -- DMA support for the I915 -*- linux-c -*-
2 */
3/*
4 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
5 * All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the
9 * "Software"), to deal in the Software without restriction, including
10 * without limitation the rights to use, copy, modify, merge, publish,
11 * distribute, sub license, and/or sell copies of the Software, and to
12 * permit persons to whom the Software is furnished to do so, subject to
13 * the following conditions:
14 *
15 * The above copyright notice and this permission notice (including the
16 * next paragraph) shall be included in all copies or substantial portions
17 * of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
23 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 *
27 */
28
29#include "drmP.h"
30#include "drm.h"
31#include "i915_drm.h"
32#include "i915_drv.h"
33
34/* Really want an OS-independent resettable timer. Would like to have
35 * this loop run for (eg) 3 sec, but have the timer reset every time
36 * the head pointer changes, so that EBUSY only happens if the ring
37 * actually stalls for (eg) 3 seconds.
38 */
39int i915_wait_ring(struct drm_device * dev, int n, const char *caller)
40{
41 drm_i915_private_t *dev_priv = dev->dev_private;
42 drm_i915_ring_buffer_t *ring = &(dev_priv->ring);
43 u32 last_head = I915_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
44 int i;
45
46 for (i = 0; i < 10000; i++) {
47 ring->head = I915_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
48 ring->space = ring->head - (ring->tail + 8);
49 if (ring->space < 0)
50 ring->space += ring->Size;
51 if (ring->space >= n)
52 return 0;
53
54 dev_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT;
55
56 if (ring->head != last_head)
57 i = 0;
58
59 last_head = ring->head;
60 }
61
62 return -EBUSY;
63}
64
65void i915_kernel_lost_context(struct drm_device * dev)
66{
67 drm_i915_private_t *dev_priv = dev->dev_private;
68 drm_i915_ring_buffer_t *ring = &(dev_priv->ring);
69
70 ring->head = I915_READ(LP_RING + RING_HEAD) & HEAD_ADDR;
71 ring->tail = I915_READ(LP_RING + RING_TAIL) & TAIL_ADDR;
72 ring->space = ring->head - (ring->tail + 8);
73 if (ring->space < 0)
74 ring->space += ring->Size;
75
76 if (ring->head == ring->tail)
77 dev_priv->sarea_priv->perf_boxes |= I915_BOX_RING_EMPTY;
78}
79
80static int i915_dma_cleanup(struct drm_device * dev)
81{
82 drm_i915_private_t *dev_priv = dev->dev_private;
83 /* Make sure interrupts are disabled here because the uninstall ioctl
84 * may not have been called from userspace and after dev_private
85 * is freed, it's too late.
86 */
87 if (dev->irq)
88 drm_irq_uninstall(dev);
89
90 if (dev_priv->ring.virtual_start) {
91 drm_core_ioremapfree(&dev_priv->ring.map, dev);
92 dev_priv->ring.virtual_start = 0;
93 dev_priv->ring.map.handle = 0;
94 dev_priv->ring.map.size = 0;
95 }
96
97 if (dev_priv->status_page_dmah) {
98 drm_pci_free(dev, dev_priv->status_page_dmah);
99 dev_priv->status_page_dmah = NULL;
100 /* Need to rewrite hardware status page */
101 I915_WRITE(0x02080, 0x1ffff000);
102 }
103
104 if (dev_priv->status_gfx_addr) {
105 dev_priv->status_gfx_addr = 0;
106 drm_core_ioremapfree(&dev_priv->hws_map, dev);
107 I915_WRITE(0x2080, 0x1ffff000);
108 }
109
110 return 0;
111}
112
113static int i915_initialize(struct drm_device * dev, drm_i915_init_t * init)
114{
115 drm_i915_private_t *dev_priv = dev->dev_private;
116
117 dev_priv->sarea = drm_getsarea(dev);
118 if (!dev_priv->sarea) {
119 DRM_ERROR("can not find sarea!\n");
120 i915_dma_cleanup(dev);
121 return -EINVAL;
122 }
123
124 dev_priv->mmio_map = drm_core_findmap(dev, init->mmio_offset);
125 if (!dev_priv->mmio_map) {
126 i915_dma_cleanup(dev);
127 DRM_ERROR("can not find mmio map!\n");
128 return -EINVAL;
129 }
130
131 dev_priv->sarea_priv = (drm_i915_sarea_t *)
132 ((u8 *) dev_priv->sarea->handle + init->sarea_priv_offset);
133
134 dev_priv->ring.Start = init->ring_start;
135 dev_priv->ring.End = init->ring_end;
136 dev_priv->ring.Size = init->ring_size;
137 dev_priv->ring.tail_mask = dev_priv->ring.Size - 1;
138
139 dev_priv->ring.map.offset = init->ring_start;
140 dev_priv->ring.map.size = init->ring_size;
141 dev_priv->ring.map.type = 0;
142 dev_priv->ring.map.flags = 0;
143 dev_priv->ring.map.mtrr = 0;
144
145 drm_core_ioremap(&dev_priv->ring.map, dev);
146
147 if (dev_priv->ring.map.handle == NULL) {
148 i915_dma_cleanup(dev);
149 DRM_ERROR("can not ioremap virtual address for"
150 " ring buffer\n");
151 return -ENOMEM;
152 }
153
154 dev_priv->ring.virtual_start = dev_priv->ring.map.handle;
155
156 dev_priv->cpp = init->cpp;
157 dev_priv->back_offset = init->back_offset;
158 dev_priv->front_offset = init->front_offset;
159 dev_priv->current_page = 0;
160 dev_priv->sarea_priv->pf_current_page = dev_priv->current_page;
161
162 /* We are using separate values as placeholders for mechanisms for
163 * private backbuffer/depthbuffer usage.
164 */
165 dev_priv->use_mi_batchbuffer_start = 0;
166 if (IS_I965G(dev)) /* 965 doesn't support older method */
167 dev_priv->use_mi_batchbuffer_start = 1;
168
169 /* Allow hardware batchbuffers unless told otherwise.
170 */
171 dev_priv->allow_batchbuffer = 1;
172
173 /* Program Hardware Status Page */
174 if (!I915_NEED_GFX_HWS(dev)) {
175 dev_priv->status_page_dmah =
176 drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 0xffffffff);
177
178 if (!dev_priv->status_page_dmah) {
179 i915_dma_cleanup(dev);
180 DRM_ERROR("Can not allocate hardware status page\n");
181 return -ENOMEM;
182 }
183 dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr;
184 dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr;
185
186 memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
187 I915_WRITE(0x02080, dev_priv->dma_status_page);
188 }
189 DRM_DEBUG("Enabled hardware status page\n");
190 return 0;
191}
192
193static int i915_dma_resume(struct drm_device * dev)
194{
195 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
196
197 DRM_DEBUG("%s\n", __func__);
198
199 if (!dev_priv->sarea) {
200 DRM_ERROR("can not find sarea!\n");
201 return -EINVAL;
202 }
203
204 if (!dev_priv->mmio_map) {
205 DRM_ERROR("can not find mmio map!\n");
206 return -EINVAL;
207 }
208
209 if (dev_priv->ring.map.handle == NULL) {
210 DRM_ERROR("can not ioremap virtual address for"
211 " ring buffer\n");
212 return -ENOMEM;
213 }
214
215 /* Program Hardware Status Page */
216 if (!dev_priv->hw_status_page) {
217 DRM_ERROR("Can not find hardware status page\n");
218 return -EINVAL;
219 }
220 DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page);
221
222 if (dev_priv->status_gfx_addr != 0)
223 I915_WRITE(0x02080, dev_priv->status_gfx_addr);
224 else
225 I915_WRITE(0x02080, dev_priv->dma_status_page);
226 DRM_DEBUG("Enabled hardware status page\n");
227
228 return 0;
229}
230
231static int i915_dma_init(struct drm_device *dev, void *data,
232 struct drm_file *file_priv)
233{
234 drm_i915_init_t *init = data;
235 int retcode = 0;
236
237 switch (init->func) {
238 case I915_INIT_DMA:
239 retcode = i915_initialize(dev, init);
240 break;
241 case I915_CLEANUP_DMA:
242 retcode = i915_dma_cleanup(dev);
243 break;
244 case I915_RESUME_DMA:
245 retcode = i915_dma_resume(dev);
246 break;
247 default:
248 retcode = -EINVAL;
249 break;
250 }
251
252 return retcode;
253}
254
255/* Implement basically the same security restrictions as hardware does
256 * for MI_BATCH_NON_SECURE. These can be made stricter at any time.
257 *
258 * Most of the calculations below involve calculating the size of a
259 * particular instruction. It's important to get the size right as
260 * that tells us where the next instruction to check is. Any illegal
261 * instruction detected will be given a size of zero, which is a
262 * signal to abort the rest of the buffer.
263 */
264static int do_validate_cmd(int cmd)
265{
266 switch (((cmd >> 29) & 0x7)) {
267 case 0x0:
268 switch ((cmd >> 23) & 0x3f) {
269 case 0x0:
270 return 1; /* MI_NOOP */
271 case 0x4:
272 return 1; /* MI_FLUSH */
273 default:
274 return 0; /* disallow everything else */
275 }
276 break;
277 case 0x1:
278 return 0; /* reserved */
279 case 0x2:
280 return (cmd & 0xff) + 2; /* 2d commands */
281 case 0x3:
282 if (((cmd >> 24) & 0x1f) <= 0x18)
283 return 1;
284
285 switch ((cmd >> 24) & 0x1f) {
286 case 0x1c:
287 return 1;
288 case 0x1d:
289 switch ((cmd >> 16) & 0xff) {
290 case 0x3:
291 return (cmd & 0x1f) + 2;
292 case 0x4:
293 return (cmd & 0xf) + 2;
294 default:
295 return (cmd & 0xffff) + 2;
296 }
297 case 0x1e:
298 if (cmd & (1 << 23))
299 return (cmd & 0xffff) + 1;
300 else
301 return 1;
302 case 0x1f:
303 if ((cmd & (1 << 23)) == 0) /* inline vertices */
304 return (cmd & 0x1ffff) + 2;
305 else if (cmd & (1 << 17)) /* indirect random */
306 if ((cmd & 0xffff) == 0)
307 return 0; /* unknown length, too hard */
308 else
309 return (((cmd & 0xffff) + 1) / 2) + 1;
310 else
311 return 2; /* indirect sequential */
312 default:
313 return 0;
314 }
315 default:
316 return 0;
317 }
318
319 return 0;
320}
321
322static int validate_cmd(int cmd)
323{
324 int ret = do_validate_cmd(cmd);
325
326/* printk("validate_cmd( %x ): %d\n", cmd, ret); */
327
328 return ret;
329}
330
331static int i915_emit_cmds(struct drm_device * dev, int __user * buffer, int dwords)
332{
333 drm_i915_private_t *dev_priv = dev->dev_private;
334 int i;
335 RING_LOCALS;
336
337 if ((dwords+1) * sizeof(int) >= dev_priv->ring.Size - 8)
338 return -EINVAL;
339
340 BEGIN_LP_RING((dwords+1)&~1);
341
342 for (i = 0; i < dwords;) {
343 int cmd, sz;
344
345 if (DRM_COPY_FROM_USER_UNCHECKED(&cmd, &buffer[i], sizeof(cmd)))
346 return -EINVAL;
347
348 if ((sz = validate_cmd(cmd)) == 0 || i + sz > dwords)
349 return -EINVAL;
350
351 OUT_RING(cmd);
352
353 while (++i, --sz) {
354 if (DRM_COPY_FROM_USER_UNCHECKED(&cmd, &buffer[i],
355 sizeof(cmd))) {
356 return -EINVAL;
357 }
358 OUT_RING(cmd);
359 }
360 }
361
362 if (dwords & 1)
363 OUT_RING(0);
364
365 ADVANCE_LP_RING();
366
367 return 0;
368}
369
370static int i915_emit_box(struct drm_device * dev,
371 struct drm_clip_rect __user * boxes,
372 int i, int DR1, int DR4)
373{
374 drm_i915_private_t *dev_priv = dev->dev_private;
375 struct drm_clip_rect box;
376 RING_LOCALS;
377
378 if (DRM_COPY_FROM_USER_UNCHECKED(&box, &boxes[i], sizeof(box))) {
379 return -EFAULT;
380 }
381
382 if (box.y2 <= box.y1 || box.x2 <= box.x1 || box.y2 <= 0 || box.x2 <= 0) {
383 DRM_ERROR("Bad box %d,%d..%d,%d\n",
384 box.x1, box.y1, box.x2, box.y2);
385 return -EINVAL;
386 }
387
388 if (IS_I965G(dev)) {
389 BEGIN_LP_RING(4);
390 OUT_RING(GFX_OP_DRAWRECT_INFO_I965);
391 OUT_RING((box.x1 & 0xffff) | (box.y1 << 16));
392 OUT_RING(((box.x2 - 1) & 0xffff) | ((box.y2 - 1) << 16));
393 OUT_RING(DR4);
394 ADVANCE_LP_RING();
395 } else {
396 BEGIN_LP_RING(6);
397 OUT_RING(GFX_OP_DRAWRECT_INFO);
398 OUT_RING(DR1);
399 OUT_RING((box.x1 & 0xffff) | (box.y1 << 16));
400 OUT_RING(((box.x2 - 1) & 0xffff) | ((box.y2 - 1) << 16));
401 OUT_RING(DR4);
402 OUT_RING(0);
403 ADVANCE_LP_RING();
404 }
405
406 return 0;
407}
408
409/* XXX: Emitting the counter should really be moved to part of the IRQ
410 * emit. For now, do it in both places:
411 */
412
413static void i915_emit_breadcrumb(struct drm_device *dev)
414{
415 drm_i915_private_t *dev_priv = dev->dev_private;
416 RING_LOCALS;
417
418 if (++dev_priv->counter > BREADCRUMB_MASK) {
419 dev_priv->counter = 1;
420 DRM_DEBUG("Breadcrumb counter wrapped around\n");
421 }
422
423 if (dev_priv->sarea_priv)
424 dev_priv->sarea_priv->last_enqueue = dev_priv->counter;
425
426 BEGIN_LP_RING(4);
427 OUT_RING(CMD_STORE_DWORD_IDX);
428 OUT_RING(20);
429 OUT_RING(dev_priv->counter);
430 OUT_RING(0);
431 ADVANCE_LP_RING();
432}
433
434int i915_emit_mi_flush(struct drm_device *dev, uint32_t flush)
435{
436 drm_i915_private_t *dev_priv = dev->dev_private;
437 uint32_t flush_cmd = CMD_MI_FLUSH;
438 RING_LOCALS;
439
440 flush_cmd |= flush;
441
442 i915_kernel_lost_context(dev);
443
444 BEGIN_LP_RING(4);
445 OUT_RING(flush_cmd);
446 OUT_RING(0);
447 OUT_RING(0);
448 OUT_RING(0);
449 ADVANCE_LP_RING();
450
451 return 0;
452}
453
454static int i915_dispatch_cmdbuffer(struct drm_device * dev,
455 drm_i915_cmdbuffer_t * cmd)
456{
457 int nbox = cmd->num_cliprects;
458 int i = 0, count, ret;
459
460 if (cmd->sz & 0x3) {
461 DRM_ERROR("alignment");
462 return -EINVAL;
463 }
464
465 i915_kernel_lost_context(dev);
466
467 count = nbox ? nbox : 1;
468
469 for (i = 0; i < count; i++) {
470 if (i < nbox) {
471 ret = i915_emit_box(dev, cmd->cliprects, i,
472 cmd->DR1, cmd->DR4);
473 if (ret)
474 return ret;
475 }
476
477 ret = i915_emit_cmds(dev, (int __user *)cmd->buf, cmd->sz / 4);
478 if (ret)
479 return ret;
480 }
481
482 i915_emit_breadcrumb(dev);
483 return 0;
484}
485
486static int i915_dispatch_batchbuffer(struct drm_device * dev,
487 drm_i915_batchbuffer_t * batch)
488{
489 drm_i915_private_t *dev_priv = dev->dev_private;
490 struct drm_clip_rect __user *boxes = batch->cliprects;
491 int nbox = batch->num_cliprects;
492 int i = 0, count;
493 RING_LOCALS;
494
495 if ((batch->start | batch->used) & 0x7) {
496 DRM_ERROR("alignment");
497 return -EINVAL;
498 }
499
500 i915_kernel_lost_context(dev);
501
502 count = nbox ? nbox : 1;
503
504 for (i = 0; i < count; i++) {
505 if (i < nbox) {
506 int ret = i915_emit_box(dev, boxes, i,
507 batch->DR1, batch->DR4);
508 if (ret)
509 return ret;
510 }
511
512 if (dev_priv->use_mi_batchbuffer_start) {
513 BEGIN_LP_RING(2);
514 if (IS_I965G(dev)) {
515 OUT_RING(MI_BATCH_BUFFER_START | (2 << 6) | MI_BATCH_NON_SECURE_I965);
516 OUT_RING(batch->start);
517 } else {
518 OUT_RING(MI_BATCH_BUFFER_START | (2 << 6));
519 OUT_RING(batch->start | MI_BATCH_NON_SECURE);
520 }
521 ADVANCE_LP_RING();
522 } else {
523 BEGIN_LP_RING(4);
524 OUT_RING(MI_BATCH_BUFFER);
525 OUT_RING(batch->start | MI_BATCH_NON_SECURE);
526 OUT_RING(batch->start + batch->used - 4);
527 OUT_RING(0);
528 ADVANCE_LP_RING();
529 }
530 }
531
532 i915_emit_breadcrumb(dev);
533
534 return 0;
535}
536
537static void i915_do_dispatch_flip(struct drm_device * dev, int plane, int sync)
538{
539 drm_i915_private_t *dev_priv = dev->dev_private;
540 u32 num_pages, current_page, next_page, dspbase;
541 int shift = 2 * plane, x, y;
542 RING_LOCALS;
543
544 /* Calculate display base offset */
545 num_pages = dev_priv->sarea_priv->third_handle ? 3 : 2;
546 current_page = (dev_priv->sarea_priv->pf_current_page >> shift) & 0x3;
547 next_page = (current_page + 1) % num_pages;
548
549 switch (next_page) {
550 default:
551 case 0:
552 dspbase = dev_priv->sarea_priv->front_offset;
553 break;
554 case 1:
555 dspbase = dev_priv->sarea_priv->back_offset;
556 break;
557 case 2:
558 dspbase = dev_priv->sarea_priv->third_offset;
559 break;
560 }
561
562 if (plane == 0) {
563 x = dev_priv->sarea_priv->planeA_x;
564 y = dev_priv->sarea_priv->planeA_y;
565 } else {
566 x = dev_priv->sarea_priv->planeB_x;
567 y = dev_priv->sarea_priv->planeB_y;
568 }
569
570 dspbase += (y * dev_priv->sarea_priv->pitch + x) * dev_priv->cpp;
571
572 DRM_DEBUG("plane=%d current_page=%d dspbase=0x%x\n", plane, current_page,
573 dspbase);
574
575 BEGIN_LP_RING(4);
576 OUT_RING(sync ? 0 :
577 (MI_WAIT_FOR_EVENT | (plane ? MI_WAIT_FOR_PLANE_B_FLIP :
578 MI_WAIT_FOR_PLANE_A_FLIP)));
579 OUT_RING(CMD_OP_DISPLAYBUFFER_INFO | (sync ? 0 : ASYNC_FLIP) |
580 (plane ? DISPLAY_PLANE_B : DISPLAY_PLANE_A));
581 OUT_RING(dev_priv->sarea_priv->pitch * dev_priv->cpp);
582 OUT_RING(dspbase);
583 ADVANCE_LP_RING();
584
585 dev_priv->sarea_priv->pf_current_page &= ~(0x3 << shift);
586 dev_priv->sarea_priv->pf_current_page |= next_page << shift;
587}
588
589void i915_dispatch_flip(struct drm_device * dev, int planes, int sync)
590{
591 drm_i915_private_t *dev_priv = dev->dev_private;
592 int i;
593
594 DRM_DEBUG("planes=0x%x pfCurrentPage=%d\n",
595 planes, dev_priv->sarea_priv->pf_current_page);
596
597 i915_emit_mi_flush(dev, MI_READ_FLUSH | MI_EXE_FLUSH);
598
599 for (i = 0; i < 2; i++)
600 if (planes & (1 << i))
601 i915_do_dispatch_flip(dev, i, sync);
602
603 i915_emit_breadcrumb(dev);
604
605}
606
607static int i915_quiescent(struct drm_device * dev)
608{
609 drm_i915_private_t *dev_priv = dev->dev_private;
610
611 i915_kernel_lost_context(dev);
612 return i915_wait_ring(dev, dev_priv->ring.Size - 8, __func__);
613}
614
615static int i915_flush_ioctl(struct drm_device *dev, void *data,
616 struct drm_file *file_priv)
617{
618 LOCK_TEST_WITH_RETURN(dev, file_priv);
619
620 return i915_quiescent(dev);
621}
622
623static int i915_batchbuffer(struct drm_device *dev, void *data,
624 struct drm_file *file_priv)
625{
626 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
627 drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *)
628 dev_priv->sarea_priv;
629 drm_i915_batchbuffer_t *batch = data;
630 int ret;
631
632 if (!dev_priv->allow_batchbuffer) {
633 DRM_ERROR("Batchbuffer ioctl disabled\n");
634 return -EINVAL;
635 }
636
637 DRM_DEBUG("i915 batchbuffer, start %x used %d cliprects %d\n",
638 batch->start, batch->used, batch->num_cliprects);
639
640 LOCK_TEST_WITH_RETURN(dev, file_priv);
641
642 if (batch->num_cliprects && DRM_VERIFYAREA_READ(batch->cliprects,
643 batch->num_cliprects *
644 sizeof(struct drm_clip_rect)))
645 return -EFAULT;
646
647 ret = i915_dispatch_batchbuffer(dev, batch);
648
649 sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
650 return ret;
651}
652
653static int i915_cmdbuffer(struct drm_device *dev, void *data,
654 struct drm_file *file_priv)
655{
656 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
657 drm_i915_sarea_t *sarea_priv = (drm_i915_sarea_t *)
658 dev_priv->sarea_priv;
659 drm_i915_cmdbuffer_t *cmdbuf = data;
660 int ret;
661
662 DRM_DEBUG("i915 cmdbuffer, buf %p sz %d cliprects %d\n",
663 cmdbuf->buf, cmdbuf->sz, cmdbuf->num_cliprects);
664
665 LOCK_TEST_WITH_RETURN(dev, file_priv);
666
667 if (cmdbuf->num_cliprects &&
668 DRM_VERIFYAREA_READ(cmdbuf->cliprects,
669 cmdbuf->num_cliprects *
670 sizeof(struct drm_clip_rect))) {
671 DRM_ERROR("Fault accessing cliprects\n");
672 return -EFAULT;
673 }
674
675 ret = i915_dispatch_cmdbuffer(dev, cmdbuf);
676 if (ret) {
677 DRM_ERROR("i915_dispatch_cmdbuffer failed\n");
678 return ret;
679 }
680
681 sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
682 return 0;
683}
684
685static int i915_do_cleanup_pageflip(struct drm_device * dev)
686{
687 drm_i915_private_t *dev_priv = dev->dev_private;
688 int i, planes, num_pages = dev_priv->sarea_priv->third_handle ? 3 : 2;
689
690 DRM_DEBUG("\n");
691
692 for (i = 0, planes = 0; i < 2; i++)
693 if (dev_priv->sarea_priv->pf_current_page & (0x3 << (2 * i))) {
694 dev_priv->sarea_priv->pf_current_page =
695 (dev_priv->sarea_priv->pf_current_page &
696 ~(0x3 << (2 * i))) | ((num_pages - 1) << (2 * i));
697
698 planes |= 1 << i;
699 }
700
701 if (planes)
702 i915_dispatch_flip(dev, planes, 0);
703
704 return 0;
705}
706
707static int i915_flip_bufs(struct drm_device *dev, void *data,
708 struct drm_file *file_priv)
709{
710 drm_i915_flip_t *param = data;
711
712 DRM_DEBUG("\n");
713
714 LOCK_TEST_WITH_RETURN(dev, file_priv);
715
716 /* This is really planes */
717 if (param->pipes & ~0x3) {
718 DRM_ERROR("Invalid planes 0x%x, only <= 0x3 is valid\n",
719 param->pipes);
720 return -EINVAL;
721 }
722
723 i915_dispatch_flip(dev, param->pipes, 0);
724
725 return 0;
726}
727
728static int i915_getparam(struct drm_device *dev, void *data,
729 struct drm_file *file_priv)
730{
731 drm_i915_private_t *dev_priv = dev->dev_private;
732 drm_i915_getparam_t *param = data;
733 int value;
734
735 if (!dev_priv) {
736 DRM_ERROR("called with no initialization\n");
737 return -EINVAL;
738 }
739
740 switch (param->param) {
741 case I915_PARAM_IRQ_ACTIVE:
742 value = dev->irq ? 1 : 0;
743 break;
744 case I915_PARAM_ALLOW_BATCHBUFFER:
745 value = dev_priv->allow_batchbuffer ? 1 : 0;
746 break;
747 case I915_PARAM_LAST_DISPATCH:
748 value = READ_BREADCRUMB(dev_priv);
749 break;
750 default:
751 DRM_ERROR("Unknown parameter %d\n", param->param);
752 return -EINVAL;
753 }
754
755 if (DRM_COPY_TO_USER(param->value, &value, sizeof(int))) {
756 DRM_ERROR("DRM_COPY_TO_USER failed\n");
757 return -EFAULT;
758 }
759
760 return 0;
761}
762
763static int i915_setparam(struct drm_device *dev, void *data,
764 struct drm_file *file_priv)
765{
766 drm_i915_private_t *dev_priv = dev->dev_private;
767 drm_i915_setparam_t *param = data;
768
769 if (!dev_priv) {
770 DRM_ERROR("called with no initialization\n");
771 return -EINVAL;
772 }
773
774 switch (param->param) {
775 case I915_SETPARAM_USE_MI_BATCHBUFFER_START:
776 if (!IS_I965G(dev))
777 dev_priv->use_mi_batchbuffer_start = param->value;
778 break;
779 case I915_SETPARAM_TEX_LRU_LOG_GRANULARITY:
780 dev_priv->tex_lru_log_granularity = param->value;
781 break;
782 case I915_SETPARAM_ALLOW_BATCHBUFFER:
783 dev_priv->allow_batchbuffer = param->value;
784 break;
785 default:
786 DRM_ERROR("unknown parameter %d\n", param->param);
787 return -EINVAL;
788 }
789
790 return 0;
791}
792
793static int i915_set_status_page(struct drm_device *dev, void *data,
794 struct drm_file *file_priv)
795{
796 drm_i915_private_t *dev_priv = dev->dev_private;
797 drm_i915_hws_addr_t *hws = data;
798
799 if (!I915_NEED_GFX_HWS(dev))
800 return -EINVAL;
801
802 if (!dev_priv) {
803 DRM_ERROR("called with no initialization\n");
804 return -EINVAL;
805 }
806
807 printk(KERN_DEBUG "set status page addr 0x%08x\n", (u32)hws->addr);
808
809 dev_priv->status_gfx_addr = hws->addr & (0x1ffff<<12);
810
811 dev_priv->hws_map.offset = dev->agp->base + hws->addr;
812 dev_priv->hws_map.size = 4*1024;
813 dev_priv->hws_map.type = 0;
814 dev_priv->hws_map.flags = 0;
815 dev_priv->hws_map.mtrr = 0;
816
817 drm_core_ioremap(&dev_priv->hws_map, dev);
818 if (dev_priv->hws_map.handle == NULL) {
819 i915_dma_cleanup(dev);
820 dev_priv->status_gfx_addr = 0;
821 DRM_ERROR("can not ioremap virtual address for"
822 " G33 hw status page\n");
823 return -ENOMEM;
824 }
825 dev_priv->hw_status_page = dev_priv->hws_map.handle;
826
827 memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
828 I915_WRITE(0x02080, dev_priv->status_gfx_addr);
829 DRM_DEBUG("load hws 0x2080 with gfx mem 0x%x\n",
830 dev_priv->status_gfx_addr);
831 DRM_DEBUG("load hws at %p\n", dev_priv->hw_status_page);
832 return 0;
833}
834
835int i915_driver_load(struct drm_device *dev, unsigned long flags)
836{
837 struct drm_i915_private *dev_priv = dev->dev_private;
838 unsigned long base, size;
839 int ret = 0, mmio_bar = IS_I9XX(dev) ? 0 : 1;
840
841 /* i915 has 4 more counters */
842 dev->counters += 4;
843 dev->types[6] = _DRM_STAT_IRQ;
844 dev->types[7] = _DRM_STAT_PRIMARY;
845 dev->types[8] = _DRM_STAT_SECONDARY;
846 dev->types[9] = _DRM_STAT_DMA;
847
848 dev_priv = drm_alloc(sizeof(drm_i915_private_t), DRM_MEM_DRIVER);
849 if (dev_priv == NULL)
850 return -ENOMEM;
851
852 memset(dev_priv, 0, sizeof(drm_i915_private_t));
853
854 dev->dev_private = (void *)dev_priv;
855
856 /* Add register map (needed for suspend/resume) */
857 base = drm_get_resource_start(dev, mmio_bar);
858 size = drm_get_resource_len(dev, mmio_bar);
859
860 ret = drm_addmap(dev, base, size, _DRM_REGISTERS,
861 _DRM_KERNEL | _DRM_DRIVER,
862 &dev_priv->mmio_map);
863 return ret;
864}
865
866int i915_driver_unload(struct drm_device *dev)
867{
868 struct drm_i915_private *dev_priv = dev->dev_private;
869
870 if (dev_priv->mmio_map)
871 drm_rmmap(dev, dev_priv->mmio_map);
872
873 drm_free(dev->dev_private, sizeof(drm_i915_private_t),
874 DRM_MEM_DRIVER);
875
876 return 0;
877}
878
879void i915_driver_lastclose(struct drm_device * dev)
880{
881 drm_i915_private_t *dev_priv = dev->dev_private;
882
883 if (!dev_priv)
884 return;
885
886 if (drm_getsarea(dev) && dev_priv->sarea_priv)
887 i915_do_cleanup_pageflip(dev);
888 if (dev_priv->agp_heap)
889 i915_mem_takedown(&(dev_priv->agp_heap));
890
891 i915_dma_cleanup(dev);
892}
893
894void i915_driver_preclose(struct drm_device * dev, struct drm_file *file_priv)
895{
896 drm_i915_private_t *dev_priv = dev->dev_private;
897 i915_mem_release(dev, file_priv, dev_priv->agp_heap);
898}
899
900struct drm_ioctl_desc i915_ioctls[] = {
901 DRM_IOCTL_DEF(DRM_I915_INIT, i915_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
902 DRM_IOCTL_DEF(DRM_I915_FLUSH, i915_flush_ioctl, DRM_AUTH),
903 DRM_IOCTL_DEF(DRM_I915_FLIP, i915_flip_bufs, DRM_AUTH),
904 DRM_IOCTL_DEF(DRM_I915_BATCHBUFFER, i915_batchbuffer, DRM_AUTH),
905 DRM_IOCTL_DEF(DRM_I915_IRQ_EMIT, i915_irq_emit, DRM_AUTH),
906 DRM_IOCTL_DEF(DRM_I915_IRQ_WAIT, i915_irq_wait, DRM_AUTH),
907 DRM_IOCTL_DEF(DRM_I915_GETPARAM, i915_getparam, DRM_AUTH),
908 DRM_IOCTL_DEF(DRM_I915_SETPARAM, i915_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
909 DRM_IOCTL_DEF(DRM_I915_ALLOC, i915_mem_alloc, DRM_AUTH),
910 DRM_IOCTL_DEF(DRM_I915_FREE, i915_mem_free, DRM_AUTH),
911 DRM_IOCTL_DEF(DRM_I915_INIT_HEAP, i915_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
912 DRM_IOCTL_DEF(DRM_I915_CMDBUFFER, i915_cmdbuffer, DRM_AUTH),
913 DRM_IOCTL_DEF(DRM_I915_DESTROY_HEAP, i915_mem_destroy_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY ),
914 DRM_IOCTL_DEF(DRM_I915_SET_VBLANK_PIPE, i915_vblank_pipe_set, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY ),
915 DRM_IOCTL_DEF(DRM_I915_GET_VBLANK_PIPE, i915_vblank_pipe_get, DRM_AUTH ),
916 DRM_IOCTL_DEF(DRM_I915_VBLANK_SWAP, i915_vblank_swap, DRM_AUTH),
917 DRM_IOCTL_DEF(DRM_I915_HWS_ADDR, i915_set_status_page, DRM_AUTH),
918};
919
920int i915_max_ioctl = DRM_ARRAY_SIZE(i915_ioctls);
921
922/**
923 * Determine if the device really is AGP or not.
924 *
925 * All Intel graphics chipsets are treated as AGP, even if they are really
926 * PCI-e.
927 *
928 * \param dev The device to be tested.
929 *
930 * \returns
931 * A value of 1 is always retured to indictate every i9x5 is AGP.
932 */
933int i915_driver_device_is_agp(struct drm_device * dev)
934{
935 return 1;
936}
diff --git a/drivers/char/drm/i915_drm.h b/drivers/char/drm/i915_drm.h
deleted file mode 100644
index 0431c00e2289..000000000000
--- a/drivers/char/drm/i915_drm.h
+++ /dev/null
@@ -1,297 +0,0 @@
1/*
2 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
3 * All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the
7 * "Software"), to deal in the Software without restriction, including
8 * without limitation the rights to use, copy, modify, merge, publish,
9 * distribute, sub license, and/or sell copies of the Software, and to
10 * permit persons to whom the Software is furnished to do so, subject to
11 * the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial portions
15 * of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
20 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
21 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
22 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
23 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 *
25 */
26
27#ifndef _I915_DRM_H_
28#define _I915_DRM_H_
29
30/* Please note that modifications to all structs defined here are
31 * subject to backwards-compatibility constraints.
32 */
33
34#include "drm.h"
35
36/* Each region is a minimum of 16k, and there are at most 255 of them.
37 */
38#define I915_NR_TEX_REGIONS 255 /* table size 2k - maximum due to use
39 * of chars for next/prev indices */
40#define I915_LOG_MIN_TEX_REGION_SIZE 14
41
42typedef struct _drm_i915_init {
43 enum {
44 I915_INIT_DMA = 0x01,
45 I915_CLEANUP_DMA = 0x02,
46 I915_RESUME_DMA = 0x03
47 } func;
48 unsigned int mmio_offset;
49 int sarea_priv_offset;
50 unsigned int ring_start;
51 unsigned int ring_end;
52 unsigned int ring_size;
53 unsigned int front_offset;
54 unsigned int back_offset;
55 unsigned int depth_offset;
56 unsigned int w;
57 unsigned int h;
58 unsigned int pitch;
59 unsigned int pitch_bits;
60 unsigned int back_pitch;
61 unsigned int depth_pitch;
62 unsigned int cpp;
63 unsigned int chipset;
64} drm_i915_init_t;
65
66typedef struct _drm_i915_sarea {
67 struct drm_tex_region texList[I915_NR_TEX_REGIONS + 1];
68 int last_upload; /* last time texture was uploaded */
69 int last_enqueue; /* last time a buffer was enqueued */
70 int last_dispatch; /* age of the most recently dispatched buffer */
71 int ctxOwner; /* last context to upload state */
72 int texAge;
73 int pf_enabled; /* is pageflipping allowed? */
74 int pf_active;
75 int pf_current_page; /* which buffer is being displayed? */
76 int perf_boxes; /* performance boxes to be displayed */
77 int width, height; /* screen size in pixels */
78
79 drm_handle_t front_handle;
80 int front_offset;
81 int front_size;
82
83 drm_handle_t back_handle;
84 int back_offset;
85 int back_size;
86
87 drm_handle_t depth_handle;
88 int depth_offset;
89 int depth_size;
90
91 drm_handle_t tex_handle;
92 int tex_offset;
93 int tex_size;
94 int log_tex_granularity;
95 int pitch;
96 int rotation; /* 0, 90, 180 or 270 */
97 int rotated_offset;
98 int rotated_size;
99 int rotated_pitch;
100 int virtualX, virtualY;
101
102 unsigned int front_tiled;
103 unsigned int back_tiled;
104 unsigned int depth_tiled;
105 unsigned int rotated_tiled;
106 unsigned int rotated2_tiled;
107
108 int planeA_x;
109 int planeA_y;
110 int planeA_w;
111 int planeA_h;
112 int planeB_x;
113 int planeB_y;
114 int planeB_w;
115 int planeB_h;
116
117 /* Triple buffering */
118 drm_handle_t third_handle;
119 int third_offset;
120 int third_size;
121 unsigned int third_tiled;
122
123 /* buffer object handles for the static buffers. May change
124 * over the lifetime of the client, though it doesn't in our current
125 * implementation.
126 */
127 unsigned int front_bo_handle;
128 unsigned int back_bo_handle;
129 unsigned int third_bo_handle;
130 unsigned int depth_bo_handle;
131} drm_i915_sarea_t;
132
133/* Flags for perf_boxes
134 */
135#define I915_BOX_RING_EMPTY 0x1
136#define I915_BOX_FLIP 0x2
137#define I915_BOX_WAIT 0x4
138#define I915_BOX_TEXTURE_LOAD 0x8
139#define I915_BOX_LOST_CONTEXT 0x10
140
141/* I915 specific ioctls
142 * The device specific ioctl range is 0x40 to 0x79.
143 */
144#define DRM_I915_INIT 0x00
145#define DRM_I915_FLUSH 0x01
146#define DRM_I915_FLIP 0x02
147#define DRM_I915_BATCHBUFFER 0x03
148#define DRM_I915_IRQ_EMIT 0x04
149#define DRM_I915_IRQ_WAIT 0x05
150#define DRM_I915_GETPARAM 0x06
151#define DRM_I915_SETPARAM 0x07
152#define DRM_I915_ALLOC 0x08
153#define DRM_I915_FREE 0x09
154#define DRM_I915_INIT_HEAP 0x0a
155#define DRM_I915_CMDBUFFER 0x0b
156#define DRM_I915_DESTROY_HEAP 0x0c
157#define DRM_I915_SET_VBLANK_PIPE 0x0d
158#define DRM_I915_GET_VBLANK_PIPE 0x0e
159#define DRM_I915_VBLANK_SWAP 0x0f
160#define DRM_I915_HWS_ADDR 0x11
161
162#define DRM_IOCTL_I915_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT, drm_i915_init_t)
163#define DRM_IOCTL_I915_FLUSH DRM_IO ( DRM_COMMAND_BASE + DRM_I915_FLUSH)
164#define DRM_IOCTL_I915_FLIP DRM_IOW( DRM_COMMAND_BASE + DRM_I915_FLIP, drm_i915_flip_t)
165#define DRM_IOCTL_I915_BATCHBUFFER DRM_IOW( DRM_COMMAND_BASE + DRM_I915_BATCHBUFFER, drm_i915_batchbuffer_t)
166#define DRM_IOCTL_I915_IRQ_EMIT DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_IRQ_EMIT, drm_i915_irq_emit_t)
167#define DRM_IOCTL_I915_IRQ_WAIT DRM_IOW( DRM_COMMAND_BASE + DRM_I915_IRQ_WAIT, drm_i915_irq_wait_t)
168#define DRM_IOCTL_I915_GETPARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_GETPARAM, drm_i915_getparam_t)
169#define DRM_IOCTL_I915_SETPARAM DRM_IOW( DRM_COMMAND_BASE + DRM_I915_SETPARAM, drm_i915_setparam_t)
170#define DRM_IOCTL_I915_ALLOC DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_ALLOC, drm_i915_mem_alloc_t)
171#define DRM_IOCTL_I915_FREE DRM_IOW( DRM_COMMAND_BASE + DRM_I915_FREE, drm_i915_mem_free_t)
172#define DRM_IOCTL_I915_INIT_HEAP DRM_IOW( DRM_COMMAND_BASE + DRM_I915_INIT_HEAP, drm_i915_mem_init_heap_t)
173#define DRM_IOCTL_I915_CMDBUFFER DRM_IOW( DRM_COMMAND_BASE + DRM_I915_CMDBUFFER, drm_i915_cmdbuffer_t)
174#define DRM_IOCTL_I915_DESTROY_HEAP DRM_IOW( DRM_COMMAND_BASE + DRM_I915_DESTROY_HEAP, drm_i915_mem_destroy_heap_t)
175#define DRM_IOCTL_I915_SET_VBLANK_PIPE DRM_IOW( DRM_COMMAND_BASE + DRM_I915_SET_VBLANK_PIPE, drm_i915_vblank_pipe_t)
176#define DRM_IOCTL_I915_GET_VBLANK_PIPE DRM_IOR( DRM_COMMAND_BASE + DRM_I915_GET_VBLANK_PIPE, drm_i915_vblank_pipe_t)
177#define DRM_IOCTL_I915_VBLANK_SWAP DRM_IOWR(DRM_COMMAND_BASE + DRM_I915_VBLANK_SWAP, drm_i915_vblank_swap_t)
178
179/* Asynchronous page flipping:
180 */
181typedef struct drm_i915_flip {
182 /*
183 * This is really talking about planes, and we could rename it
184 * except for the fact that some of the duplicated i915_drm.h files
185 * out there check for HAVE_I915_FLIP and so might pick up this
186 * version.
187 */
188 int pipes;
189} drm_i915_flip_t;
190
191/* Allow drivers to submit batchbuffers directly to hardware, relying
192 * on the security mechanisms provided by hardware.
193 */
194typedef struct _drm_i915_batchbuffer {
195 int start; /* agp offset */
196 int used; /* nr bytes in use */
197 int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */
198 int DR4; /* window origin for GFX_OP_DRAWRECT_INFO */
199 int num_cliprects; /* mulitpass with multiple cliprects? */
200 struct drm_clip_rect __user *cliprects; /* pointer to userspace cliprects */
201} drm_i915_batchbuffer_t;
202
203/* As above, but pass a pointer to userspace buffer which can be
204 * validated by the kernel prior to sending to hardware.
205 */
206typedef struct _drm_i915_cmdbuffer {
207 char __user *buf; /* pointer to userspace command buffer */
208 int sz; /* nr bytes in buf */
209 int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */
210 int DR4; /* window origin for GFX_OP_DRAWRECT_INFO */
211 int num_cliprects; /* mulitpass with multiple cliprects? */
212 struct drm_clip_rect __user *cliprects; /* pointer to userspace cliprects */
213} drm_i915_cmdbuffer_t;
214
215/* Userspace can request & wait on irq's:
216 */
217typedef struct drm_i915_irq_emit {
218 int __user *irq_seq;
219} drm_i915_irq_emit_t;
220
221typedef struct drm_i915_irq_wait {
222 int irq_seq;
223} drm_i915_irq_wait_t;
224
225/* Ioctl to query kernel params:
226 */
227#define I915_PARAM_IRQ_ACTIVE 1
228#define I915_PARAM_ALLOW_BATCHBUFFER 2
229#define I915_PARAM_LAST_DISPATCH 3
230
231typedef struct drm_i915_getparam {
232 int param;
233 int __user *value;
234} drm_i915_getparam_t;
235
236/* Ioctl to set kernel params:
237 */
238#define I915_SETPARAM_USE_MI_BATCHBUFFER_START 1
239#define I915_SETPARAM_TEX_LRU_LOG_GRANULARITY 2
240#define I915_SETPARAM_ALLOW_BATCHBUFFER 3
241
242typedef struct drm_i915_setparam {
243 int param;
244 int value;
245} drm_i915_setparam_t;
246
247/* A memory manager for regions of shared memory:
248 */
249#define I915_MEM_REGION_AGP 1
250
251typedef struct drm_i915_mem_alloc {
252 int region;
253 int alignment;
254 int size;
255 int __user *region_offset; /* offset from start of fb or agp */
256} drm_i915_mem_alloc_t;
257
258typedef struct drm_i915_mem_free {
259 int region;
260 int region_offset;
261} drm_i915_mem_free_t;
262
263typedef struct drm_i915_mem_init_heap {
264 int region;
265 int size;
266 int start;
267} drm_i915_mem_init_heap_t;
268
269/* Allow memory manager to be torn down and re-initialized (eg on
270 * rotate):
271 */
272typedef struct drm_i915_mem_destroy_heap {
273 int region;
274} drm_i915_mem_destroy_heap_t;
275
276/* Allow X server to configure which pipes to monitor for vblank signals
277 */
278#define DRM_I915_VBLANK_PIPE_A 1
279#define DRM_I915_VBLANK_PIPE_B 2
280
281typedef struct drm_i915_vblank_pipe {
282 int pipe;
283} drm_i915_vblank_pipe_t;
284
285/* Schedule buffer swap at given vertical blank:
286 */
287typedef struct drm_i915_vblank_swap {
288 drm_drawable_t drawable;
289 enum drm_vblank_seq_type seqtype;
290 unsigned int sequence;
291} drm_i915_vblank_swap_t;
292
293typedef struct drm_i915_hws_addr {
294 uint64_t addr;
295} drm_i915_hws_addr_t;
296
297#endif /* _I915_DRM_H_ */
diff --git a/drivers/char/drm/i915_drv.c b/drivers/char/drm/i915_drv.c
deleted file mode 100644
index bb8f1b2fb383..000000000000
--- a/drivers/char/drm/i915_drv.c
+++ /dev/null
@@ -1,597 +0,0 @@
1/* i915_drv.c -- i830,i845,i855,i865,i915 driver -*- linux-c -*-
2 */
3/*
4 *
5 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
6 * All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the
10 * "Software"), to deal in the Software without restriction, including
11 * without limitation the rights to use, copy, modify, merge, publish,
12 * distribute, sub license, and/or sell copies of the Software, and to
13 * permit persons to whom the Software is furnished to do so, subject to
14 * the following conditions:
15 *
16 * The above copyright notice and this permission notice (including the
17 * next paragraph) shall be included in all copies or substantial portions
18 * of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
23 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
24 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 *
28 */
29
30#include "drmP.h"
31#include "drm.h"
32#include "i915_drm.h"
33#include "i915_drv.h"
34
35#include "drm_pciids.h"
36
37static struct pci_device_id pciidlist[] = {
38 i915_PCI_IDS
39};
40
41enum pipe {
42 PIPE_A = 0,
43 PIPE_B,
44};
45
46static bool i915_pipe_enabled(struct drm_device *dev, enum pipe pipe)
47{
48 struct drm_i915_private *dev_priv = dev->dev_private;
49
50 if (pipe == PIPE_A)
51 return (I915_READ(DPLL_A) & DPLL_VCO_ENABLE);
52 else
53 return (I915_READ(DPLL_B) & DPLL_VCO_ENABLE);
54}
55
56static void i915_save_palette(struct drm_device *dev, enum pipe pipe)
57{
58 struct drm_i915_private *dev_priv = dev->dev_private;
59 unsigned long reg = (pipe == PIPE_A ? PALETTE_A : PALETTE_B);
60 u32 *array;
61 int i;
62
63 if (!i915_pipe_enabled(dev, pipe))
64 return;
65
66 if (pipe == PIPE_A)
67 array = dev_priv->save_palette_a;
68 else
69 array = dev_priv->save_palette_b;
70
71 for(i = 0; i < 256; i++)
72 array[i] = I915_READ(reg + (i << 2));
73}
74
75static void i915_restore_palette(struct drm_device *dev, enum pipe pipe)
76{
77 struct drm_i915_private *dev_priv = dev->dev_private;
78 unsigned long reg = (pipe == PIPE_A ? PALETTE_A : PALETTE_B);
79 u32 *array;
80 int i;
81
82 if (!i915_pipe_enabled(dev, pipe))
83 return;
84
85 if (pipe == PIPE_A)
86 array = dev_priv->save_palette_a;
87 else
88 array = dev_priv->save_palette_b;
89
90 for(i = 0; i < 256; i++)
91 I915_WRITE(reg + (i << 2), array[i]);
92}
93
94static u8 i915_read_indexed(u16 index_port, u16 data_port, u8 reg)
95{
96 outb(reg, index_port);
97 return inb(data_port);
98}
99
100static u8 i915_read_ar(u16 st01, u8 reg, u16 palette_enable)
101{
102 inb(st01);
103 outb(palette_enable | reg, VGA_AR_INDEX);
104 return inb(VGA_AR_DATA_READ);
105}
106
107static void i915_write_ar(u8 st01, u8 reg, u8 val, u16 palette_enable)
108{
109 inb(st01);
110 outb(palette_enable | reg, VGA_AR_INDEX);
111 outb(val, VGA_AR_DATA_WRITE);
112}
113
114static void i915_write_indexed(u16 index_port, u16 data_port, u8 reg, u8 val)
115{
116 outb(reg, index_port);
117 outb(val, data_port);
118}
119
120static void i915_save_vga(struct drm_device *dev)
121{
122 struct drm_i915_private *dev_priv = dev->dev_private;
123 int i;
124 u16 cr_index, cr_data, st01;
125
126 /* VGA color palette registers */
127 dev_priv->saveDACMASK = inb(VGA_DACMASK);
128 /* DACCRX automatically increments during read */
129 outb(0, VGA_DACRX);
130 /* Read 3 bytes of color data from each index */
131 for (i = 0; i < 256 * 3; i++)
132 dev_priv->saveDACDATA[i] = inb(VGA_DACDATA);
133
134 /* MSR bits */
135 dev_priv->saveMSR = inb(VGA_MSR_READ);
136 if (dev_priv->saveMSR & VGA_MSR_CGA_MODE) {
137 cr_index = VGA_CR_INDEX_CGA;
138 cr_data = VGA_CR_DATA_CGA;
139 st01 = VGA_ST01_CGA;
140 } else {
141 cr_index = VGA_CR_INDEX_MDA;
142 cr_data = VGA_CR_DATA_MDA;
143 st01 = VGA_ST01_MDA;
144 }
145
146 /* CRT controller regs */
147 i915_write_indexed(cr_index, cr_data, 0x11,
148 i915_read_indexed(cr_index, cr_data, 0x11) &
149 (~0x80));
150 for (i = 0; i < 0x24; i++)
151 dev_priv->saveCR[i] =
152 i915_read_indexed(cr_index, cr_data, i);
153 /* Make sure we don't turn off CR group 0 writes */
154 dev_priv->saveCR[0x11] &= ~0x80;
155
156 /* Attribute controller registers */
157 inb(st01);
158 dev_priv->saveAR_INDEX = inb(VGA_AR_INDEX);
159 for (i = 0; i < 20; i++)
160 dev_priv->saveAR[i] = i915_read_ar(st01, i, 0);
161 inb(st01);
162 outb(dev_priv->saveAR_INDEX, VGA_AR_INDEX);
163 inb(st01);
164
165 /* Graphics controller registers */
166 for (i = 0; i < 9; i++)
167 dev_priv->saveGR[i] =
168 i915_read_indexed(VGA_GR_INDEX, VGA_GR_DATA, i);
169
170 dev_priv->saveGR[0x10] =
171 i915_read_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x10);
172 dev_priv->saveGR[0x11] =
173 i915_read_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x11);
174 dev_priv->saveGR[0x18] =
175 i915_read_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x18);
176
177 /* Sequencer registers */
178 for (i = 0; i < 8; i++)
179 dev_priv->saveSR[i] =
180 i915_read_indexed(VGA_SR_INDEX, VGA_SR_DATA, i);
181}
182
183static void i915_restore_vga(struct drm_device *dev)
184{
185 struct drm_i915_private *dev_priv = dev->dev_private;
186 int i;
187 u16 cr_index, cr_data, st01;
188
189 /* MSR bits */
190 outb(dev_priv->saveMSR, VGA_MSR_WRITE);
191 if (dev_priv->saveMSR & VGA_MSR_CGA_MODE) {
192 cr_index = VGA_CR_INDEX_CGA;
193 cr_data = VGA_CR_DATA_CGA;
194 st01 = VGA_ST01_CGA;
195 } else {
196 cr_index = VGA_CR_INDEX_MDA;
197 cr_data = VGA_CR_DATA_MDA;
198 st01 = VGA_ST01_MDA;
199 }
200
201 /* Sequencer registers, don't write SR07 */
202 for (i = 0; i < 7; i++)
203 i915_write_indexed(VGA_SR_INDEX, VGA_SR_DATA, i,
204 dev_priv->saveSR[i]);
205
206 /* CRT controller regs */
207 /* Enable CR group 0 writes */
208 i915_write_indexed(cr_index, cr_data, 0x11, dev_priv->saveCR[0x11]);
209 for (i = 0; i < 0x24; i++)
210 i915_write_indexed(cr_index, cr_data, i, dev_priv->saveCR[i]);
211
212 /* Graphics controller regs */
213 for (i = 0; i < 9; i++)
214 i915_write_indexed(VGA_GR_INDEX, VGA_GR_DATA, i,
215 dev_priv->saveGR[i]);
216
217 i915_write_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x10,
218 dev_priv->saveGR[0x10]);
219 i915_write_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x11,
220 dev_priv->saveGR[0x11]);
221 i915_write_indexed(VGA_GR_INDEX, VGA_GR_DATA, 0x18,
222 dev_priv->saveGR[0x18]);
223
224 /* Attribute controller registers */
225 inb(st01);
226 for (i = 0; i < 20; i++)
227 i915_write_ar(st01, i, dev_priv->saveAR[i], 0);
228 inb(st01); /* switch back to index mode */
229 outb(dev_priv->saveAR_INDEX | 0x20, VGA_AR_INDEX);
230 inb(st01);
231
232 /* VGA color palette registers */
233 outb(dev_priv->saveDACMASK, VGA_DACMASK);
234 /* DACCRX automatically increments during read */
235 outb(0, VGA_DACWX);
236 /* Read 3 bytes of color data from each index */
237 for (i = 0; i < 256 * 3; i++)
238 outb(dev_priv->saveDACDATA[i], VGA_DACDATA);
239
240}
241
242static int i915_suspend(struct drm_device *dev, pm_message_t state)
243{
244 struct drm_i915_private *dev_priv = dev->dev_private;
245 int i;
246
247 if (!dev || !dev_priv) {
248 printk(KERN_ERR "dev: %p, dev_priv: %p\n", dev, dev_priv);
249 printk(KERN_ERR "DRM not initialized, aborting suspend.\n");
250 return -ENODEV;
251 }
252
253 if (state.event == PM_EVENT_PRETHAW)
254 return 0;
255
256 pci_save_state(dev->pdev);
257 pci_read_config_byte(dev->pdev, LBB, &dev_priv->saveLBB);
258
259 /* Pipe & plane A info */
260 dev_priv->savePIPEACONF = I915_READ(PIPEACONF);
261 dev_priv->savePIPEASRC = I915_READ(PIPEASRC);
262 dev_priv->saveFPA0 = I915_READ(FPA0);
263 dev_priv->saveFPA1 = I915_READ(FPA1);
264 dev_priv->saveDPLL_A = I915_READ(DPLL_A);
265 if (IS_I965G(dev))
266 dev_priv->saveDPLL_A_MD = I915_READ(DPLL_A_MD);
267 dev_priv->saveHTOTAL_A = I915_READ(HTOTAL_A);
268 dev_priv->saveHBLANK_A = I915_READ(HBLANK_A);
269 dev_priv->saveHSYNC_A = I915_READ(HSYNC_A);
270 dev_priv->saveVTOTAL_A = I915_READ(VTOTAL_A);
271 dev_priv->saveVBLANK_A = I915_READ(VBLANK_A);
272 dev_priv->saveVSYNC_A = I915_READ(VSYNC_A);
273 dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A);
274
275 dev_priv->saveDSPACNTR = I915_READ(DSPACNTR);
276 dev_priv->saveDSPASTRIDE = I915_READ(DSPASTRIDE);
277 dev_priv->saveDSPASIZE = I915_READ(DSPASIZE);
278 dev_priv->saveDSPAPOS = I915_READ(DSPAPOS);
279 dev_priv->saveDSPABASE = I915_READ(DSPABASE);
280 if (IS_I965G(dev)) {
281 dev_priv->saveDSPASURF = I915_READ(DSPASURF);
282 dev_priv->saveDSPATILEOFF = I915_READ(DSPATILEOFF);
283 }
284 i915_save_palette(dev, PIPE_A);
285 dev_priv->savePIPEASTAT = I915_READ(I915REG_PIPEASTAT);
286
287 /* Pipe & plane B info */
288 dev_priv->savePIPEBCONF = I915_READ(PIPEBCONF);
289 dev_priv->savePIPEBSRC = I915_READ(PIPEBSRC);
290 dev_priv->saveFPB0 = I915_READ(FPB0);
291 dev_priv->saveFPB1 = I915_READ(FPB1);
292 dev_priv->saveDPLL_B = I915_READ(DPLL_B);
293 if (IS_I965G(dev))
294 dev_priv->saveDPLL_B_MD = I915_READ(DPLL_B_MD);
295 dev_priv->saveHTOTAL_B = I915_READ(HTOTAL_B);
296 dev_priv->saveHBLANK_B = I915_READ(HBLANK_B);
297 dev_priv->saveHSYNC_B = I915_READ(HSYNC_B);
298 dev_priv->saveVTOTAL_B = I915_READ(VTOTAL_B);
299 dev_priv->saveVBLANK_B = I915_READ(VBLANK_B);
300 dev_priv->saveVSYNC_B = I915_READ(VSYNC_B);
301 dev_priv->saveBCLRPAT_A = I915_READ(BCLRPAT_A);
302
303 dev_priv->saveDSPBCNTR = I915_READ(DSPBCNTR);
304 dev_priv->saveDSPBSTRIDE = I915_READ(DSPBSTRIDE);
305 dev_priv->saveDSPBSIZE = I915_READ(DSPBSIZE);
306 dev_priv->saveDSPBPOS = I915_READ(DSPBPOS);
307 dev_priv->saveDSPBBASE = I915_READ(DSPBBASE);
308 if (IS_I965GM(dev) || IS_IGD_GM(dev)) {
309 dev_priv->saveDSPBSURF = I915_READ(DSPBSURF);
310 dev_priv->saveDSPBTILEOFF = I915_READ(DSPBTILEOFF);
311 }
312 i915_save_palette(dev, PIPE_B);
313 dev_priv->savePIPEBSTAT = I915_READ(I915REG_PIPEBSTAT);
314
315 /* CRT state */
316 dev_priv->saveADPA = I915_READ(ADPA);
317
318 /* LVDS state */
319 dev_priv->savePP_CONTROL = I915_READ(PP_CONTROL);
320 dev_priv->savePFIT_PGM_RATIOS = I915_READ(PFIT_PGM_RATIOS);
321 dev_priv->saveBLC_PWM_CTL = I915_READ(BLC_PWM_CTL);
322 if (IS_I965G(dev))
323 dev_priv->saveBLC_PWM_CTL2 = I915_READ(BLC_PWM_CTL2);
324 if (IS_MOBILE(dev) && !IS_I830(dev))
325 dev_priv->saveLVDS = I915_READ(LVDS);
326 if (!IS_I830(dev) && !IS_845G(dev))
327 dev_priv->savePFIT_CONTROL = I915_READ(PFIT_CONTROL);
328 dev_priv->saveLVDSPP_ON = I915_READ(LVDSPP_ON);
329 dev_priv->saveLVDSPP_OFF = I915_READ(LVDSPP_OFF);
330 dev_priv->savePP_CYCLE = I915_READ(PP_CYCLE);
331
332 /* FIXME: save TV & SDVO state */
333
334 /* FBC state */
335 dev_priv->saveFBC_CFB_BASE = I915_READ(FBC_CFB_BASE);
336 dev_priv->saveFBC_LL_BASE = I915_READ(FBC_LL_BASE);
337 dev_priv->saveFBC_CONTROL2 = I915_READ(FBC_CONTROL2);
338 dev_priv->saveFBC_CONTROL = I915_READ(FBC_CONTROL);
339
340 /* Interrupt state */
341 dev_priv->saveIIR = I915_READ(I915REG_INT_IDENTITY_R);
342 dev_priv->saveIER = I915_READ(I915REG_INT_ENABLE_R);
343 dev_priv->saveIMR = I915_READ(I915REG_INT_MASK_R);
344
345 /* VGA state */
346 dev_priv->saveVCLK_DIVISOR_VGA0 = I915_READ(VCLK_DIVISOR_VGA0);
347 dev_priv->saveVCLK_DIVISOR_VGA1 = I915_READ(VCLK_DIVISOR_VGA1);
348 dev_priv->saveVCLK_POST_DIV = I915_READ(VCLK_POST_DIV);
349 dev_priv->saveVGACNTRL = I915_READ(VGACNTRL);
350
351 /* Clock gating state */
352 dev_priv->saveDSPCLK_GATE_D = I915_READ(DSPCLK_GATE_D);
353
354 /* Cache mode state */
355 dev_priv->saveCACHE_MODE_0 = I915_READ(CACHE_MODE_0);
356
357 /* Memory Arbitration state */
358 dev_priv->saveMI_ARB_STATE = I915_READ(MI_ARB_STATE);
359
360 /* Scratch space */
361 for (i = 0; i < 16; i++) {
362 dev_priv->saveSWF0[i] = I915_READ(SWF0 + (i << 2));
363 dev_priv->saveSWF1[i] = I915_READ(SWF10 + (i << 2));
364 }
365 for (i = 0; i < 3; i++)
366 dev_priv->saveSWF2[i] = I915_READ(SWF30 + (i << 2));
367
368 i915_save_vga(dev);
369
370 if (state.event == PM_EVENT_SUSPEND) {
371 /* Shut down the device */
372 pci_disable_device(dev->pdev);
373 pci_set_power_state(dev->pdev, PCI_D3hot);
374 }
375
376 return 0;
377}
378
379static int i915_resume(struct drm_device *dev)
380{
381 struct drm_i915_private *dev_priv = dev->dev_private;
382 int i;
383
384 pci_set_power_state(dev->pdev, PCI_D0);
385 pci_restore_state(dev->pdev);
386 if (pci_enable_device(dev->pdev))
387 return -1;
388
389 pci_write_config_byte(dev->pdev, LBB, dev_priv->saveLBB);
390
391 /* Pipe & plane A info */
392 /* Prime the clock */
393 if (dev_priv->saveDPLL_A & DPLL_VCO_ENABLE) {
394 I915_WRITE(DPLL_A, dev_priv->saveDPLL_A &
395 ~DPLL_VCO_ENABLE);
396 udelay(150);
397 }
398 I915_WRITE(FPA0, dev_priv->saveFPA0);
399 I915_WRITE(FPA1, dev_priv->saveFPA1);
400 /* Actually enable it */
401 I915_WRITE(DPLL_A, dev_priv->saveDPLL_A);
402 udelay(150);
403 if (IS_I965G(dev))
404 I915_WRITE(DPLL_A_MD, dev_priv->saveDPLL_A_MD);
405 udelay(150);
406
407 /* Restore mode */
408 I915_WRITE(HTOTAL_A, dev_priv->saveHTOTAL_A);
409 I915_WRITE(HBLANK_A, dev_priv->saveHBLANK_A);
410 I915_WRITE(HSYNC_A, dev_priv->saveHSYNC_A);
411 I915_WRITE(VTOTAL_A, dev_priv->saveVTOTAL_A);
412 I915_WRITE(VBLANK_A, dev_priv->saveVBLANK_A);
413 I915_WRITE(VSYNC_A, dev_priv->saveVSYNC_A);
414 I915_WRITE(BCLRPAT_A, dev_priv->saveBCLRPAT_A);
415
416 /* Restore plane info */
417 I915_WRITE(DSPASIZE, dev_priv->saveDSPASIZE);
418 I915_WRITE(DSPAPOS, dev_priv->saveDSPAPOS);
419 I915_WRITE(PIPEASRC, dev_priv->savePIPEASRC);
420 I915_WRITE(DSPABASE, dev_priv->saveDSPABASE);
421 I915_WRITE(DSPASTRIDE, dev_priv->saveDSPASTRIDE);
422 if (IS_I965G(dev)) {
423 I915_WRITE(DSPASURF, dev_priv->saveDSPASURF);
424 I915_WRITE(DSPATILEOFF, dev_priv->saveDSPATILEOFF);
425 }
426
427 I915_WRITE(PIPEACONF, dev_priv->savePIPEACONF);
428
429 i915_restore_palette(dev, PIPE_A);
430 /* Enable the plane */
431 I915_WRITE(DSPACNTR, dev_priv->saveDSPACNTR);
432 I915_WRITE(DSPABASE, I915_READ(DSPABASE));
433
434 /* Pipe & plane B info */
435 if (dev_priv->saveDPLL_B & DPLL_VCO_ENABLE) {
436 I915_WRITE(DPLL_B, dev_priv->saveDPLL_B &
437 ~DPLL_VCO_ENABLE);
438 udelay(150);
439 }
440 I915_WRITE(FPB0, dev_priv->saveFPB0);
441 I915_WRITE(FPB1, dev_priv->saveFPB1);
442 /* Actually enable it */
443 I915_WRITE(DPLL_B, dev_priv->saveDPLL_B);
444 udelay(150);
445 if (IS_I965G(dev))
446 I915_WRITE(DPLL_B_MD, dev_priv->saveDPLL_B_MD);
447 udelay(150);
448
449 /* Restore mode */
450 I915_WRITE(HTOTAL_B, dev_priv->saveHTOTAL_B);
451 I915_WRITE(HBLANK_B, dev_priv->saveHBLANK_B);
452 I915_WRITE(HSYNC_B, dev_priv->saveHSYNC_B);
453 I915_WRITE(VTOTAL_B, dev_priv->saveVTOTAL_B);
454 I915_WRITE(VBLANK_B, dev_priv->saveVBLANK_B);
455 I915_WRITE(VSYNC_B, dev_priv->saveVSYNC_B);
456 I915_WRITE(BCLRPAT_B, dev_priv->saveBCLRPAT_B);
457
458 /* Restore plane info */
459 I915_WRITE(DSPBSIZE, dev_priv->saveDSPBSIZE);
460 I915_WRITE(DSPBPOS, dev_priv->saveDSPBPOS);
461 I915_WRITE(PIPEBSRC, dev_priv->savePIPEBSRC);
462 I915_WRITE(DSPBBASE, dev_priv->saveDSPBBASE);
463 I915_WRITE(DSPBSTRIDE, dev_priv->saveDSPBSTRIDE);
464 if (IS_I965G(dev)) {
465 I915_WRITE(DSPBSURF, dev_priv->saveDSPBSURF);
466 I915_WRITE(DSPBTILEOFF, dev_priv->saveDSPBTILEOFF);
467 }
468
469 I915_WRITE(PIPEBCONF, dev_priv->savePIPEBCONF);
470
471 i915_restore_palette(dev, PIPE_B);
472 /* Enable the plane */
473 I915_WRITE(DSPBCNTR, dev_priv->saveDSPBCNTR);
474 I915_WRITE(DSPBBASE, I915_READ(DSPBBASE));
475
476 /* CRT state */
477 I915_WRITE(ADPA, dev_priv->saveADPA);
478
479 /* LVDS state */
480 if (IS_I965G(dev))
481 I915_WRITE(BLC_PWM_CTL2, dev_priv->saveBLC_PWM_CTL2);
482 if (IS_MOBILE(dev) && !IS_I830(dev))
483 I915_WRITE(LVDS, dev_priv->saveLVDS);
484 if (!IS_I830(dev) && !IS_845G(dev))
485 I915_WRITE(PFIT_CONTROL, dev_priv->savePFIT_CONTROL);
486
487 I915_WRITE(PFIT_PGM_RATIOS, dev_priv->savePFIT_PGM_RATIOS);
488 I915_WRITE(BLC_PWM_CTL, dev_priv->saveBLC_PWM_CTL);
489 I915_WRITE(LVDSPP_ON, dev_priv->saveLVDSPP_ON);
490 I915_WRITE(LVDSPP_OFF, dev_priv->saveLVDSPP_OFF);
491 I915_WRITE(PP_CYCLE, dev_priv->savePP_CYCLE);
492 I915_WRITE(PP_CONTROL, dev_priv->savePP_CONTROL);
493
494 /* FIXME: restore TV & SDVO state */
495
496 /* FBC info */
497 I915_WRITE(FBC_CFB_BASE, dev_priv->saveFBC_CFB_BASE);
498 I915_WRITE(FBC_LL_BASE, dev_priv->saveFBC_LL_BASE);
499 I915_WRITE(FBC_CONTROL2, dev_priv->saveFBC_CONTROL2);
500 I915_WRITE(FBC_CONTROL, dev_priv->saveFBC_CONTROL);
501
502 /* VGA state */
503 I915_WRITE(VGACNTRL, dev_priv->saveVGACNTRL);
504 I915_WRITE(VCLK_DIVISOR_VGA0, dev_priv->saveVCLK_DIVISOR_VGA0);
505 I915_WRITE(VCLK_DIVISOR_VGA1, dev_priv->saveVCLK_DIVISOR_VGA1);
506 I915_WRITE(VCLK_POST_DIV, dev_priv->saveVCLK_POST_DIV);
507 udelay(150);
508
509 /* Clock gating state */
510 I915_WRITE (DSPCLK_GATE_D, dev_priv->saveDSPCLK_GATE_D);
511
512 /* Cache mode state */
513 I915_WRITE (CACHE_MODE_0, dev_priv->saveCACHE_MODE_0 | 0xffff0000);
514
515 /* Memory arbitration state */
516 I915_WRITE (MI_ARB_STATE, dev_priv->saveMI_ARB_STATE | 0xffff0000);
517
518 for (i = 0; i < 16; i++) {
519 I915_WRITE(SWF0 + (i << 2), dev_priv->saveSWF0[i]);
520 I915_WRITE(SWF10 + (i << 2), dev_priv->saveSWF1[i+7]);
521 }
522 for (i = 0; i < 3; i++)
523 I915_WRITE(SWF30 + (i << 2), dev_priv->saveSWF2[i]);
524
525 i915_restore_vga(dev);
526
527 return 0;
528}
529
530static struct drm_driver driver = {
531 /* don't use mtrr's here, the Xserver or user space app should
532 * deal with them for intel hardware.
533 */
534 .driver_features =
535 DRIVER_USE_AGP | DRIVER_REQUIRE_AGP | /* DRIVER_USE_MTRR |*/
536 DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED,
537 .load = i915_driver_load,
538 .unload = i915_driver_unload,
539 .lastclose = i915_driver_lastclose,
540 .preclose = i915_driver_preclose,
541 .suspend = i915_suspend,
542 .resume = i915_resume,
543 .device_is_agp = i915_driver_device_is_agp,
544 .get_vblank_counter = i915_get_vblank_counter,
545 .enable_vblank = i915_enable_vblank,
546 .disable_vblank = i915_disable_vblank,
547 .irq_preinstall = i915_driver_irq_preinstall,
548 .irq_postinstall = i915_driver_irq_postinstall,
549 .irq_uninstall = i915_driver_irq_uninstall,
550 .irq_handler = i915_driver_irq_handler,
551 .reclaim_buffers = drm_core_reclaim_buffers,
552 .get_map_ofs = drm_core_get_map_ofs,
553 .get_reg_ofs = drm_core_get_reg_ofs,
554 .ioctls = i915_ioctls,
555 .fops = {
556 .owner = THIS_MODULE,
557 .open = drm_open,
558 .release = drm_release,
559 .ioctl = drm_ioctl,
560 .mmap = drm_mmap,
561 .poll = drm_poll,
562 .fasync = drm_fasync,
563#ifdef CONFIG_COMPAT
564 .compat_ioctl = i915_compat_ioctl,
565#endif
566 },
567
568 .pci_driver = {
569 .name = DRIVER_NAME,
570 .id_table = pciidlist,
571 },
572
573 .name = DRIVER_NAME,
574 .desc = DRIVER_DESC,
575 .date = DRIVER_DATE,
576 .major = DRIVER_MAJOR,
577 .minor = DRIVER_MINOR,
578 .patchlevel = DRIVER_PATCHLEVEL,
579};
580
581static int __init i915_init(void)
582{
583 driver.num_ioctls = i915_max_ioctl;
584 return drm_init(&driver);
585}
586
587static void __exit i915_exit(void)
588{
589 drm_exit(&driver);
590}
591
592module_init(i915_init);
593module_exit(i915_exit);
594
595MODULE_AUTHOR(DRIVER_AUTHOR);
596MODULE_DESCRIPTION(DRIVER_DESC);
597MODULE_LICENSE("GPL and additional rights");
diff --git a/drivers/char/drm/i915_drv.h b/drivers/char/drm/i915_drv.h
deleted file mode 100644
index db7001f22561..000000000000
--- a/drivers/char/drm/i915_drv.h
+++ /dev/null
@@ -1,1204 +0,0 @@
1/* i915_drv.h -- Private header for the I915 driver -*- linux-c -*-
2 */
3/*
4 *
5 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
6 * All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the
10 * "Software"), to deal in the Software without restriction, including
11 * without limitation the rights to use, copy, modify, merge, publish,
12 * distribute, sub license, and/or sell copies of the Software, and to
13 * permit persons to whom the Software is furnished to do so, subject to
14 * the following conditions:
15 *
16 * The above copyright notice and this permission notice (including the
17 * next paragraph) shall be included in all copies or substantial portions
18 * of the Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
22 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
23 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
24 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
25 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
26 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 *
28 */
29
30#ifndef _I915_DRV_H_
31#define _I915_DRV_H_
32
33/* General customization:
34 */
35
36#define DRIVER_AUTHOR "Tungsten Graphics, Inc."
37
38#define DRIVER_NAME "i915"
39#define DRIVER_DESC "Intel Graphics"
40#define DRIVER_DATE "20060119"
41
42/* Interface history:
43 *
44 * 1.1: Original.
45 * 1.2: Add Power Management
46 * 1.3: Add vblank support
47 * 1.4: Fix cmdbuffer path, add heap destroy
48 * 1.5: Add vblank pipe configuration
49 * 1.6: - New ioctl for scheduling buffer swaps on vertical blank
50 * - Support vertical blank on secondary display pipe
51 */
52#define DRIVER_MAJOR 1
53#define DRIVER_MINOR 6
54#define DRIVER_PATCHLEVEL 0
55
56typedef struct _drm_i915_ring_buffer {
57 int tail_mask;
58 unsigned long Start;
59 unsigned long End;
60 unsigned long Size;
61 u8 *virtual_start;
62 int head;
63 int tail;
64 int space;
65 drm_local_map_t map;
66} drm_i915_ring_buffer_t;
67
68struct mem_block {
69 struct mem_block *next;
70 struct mem_block *prev;
71 int start;
72 int size;
73 struct drm_file *file_priv; /* NULL: free, -1: heap, other: real files */
74};
75
76typedef struct _drm_i915_vbl_swap {
77 struct list_head head;
78 drm_drawable_t drw_id;
79 unsigned int plane;
80 unsigned int sequence;
81 int flip;
82} drm_i915_vbl_swap_t;
83
84typedef struct drm_i915_private {
85 drm_local_map_t *sarea;
86 drm_local_map_t *mmio_map;
87
88 drm_i915_sarea_t *sarea_priv;
89 drm_i915_ring_buffer_t ring;
90
91 drm_dma_handle_t *status_page_dmah;
92 void *hw_status_page;
93 dma_addr_t dma_status_page;
94 uint32_t counter;
95 unsigned int status_gfx_addr;
96 drm_local_map_t hws_map;
97
98 unsigned int cpp;
99 int back_offset;
100 int front_offset;
101 int current_page;
102 int page_flipping;
103 int use_mi_batchbuffer_start;
104
105 wait_queue_head_t irq_queue;
106 atomic_t irq_received;
107 atomic_t irq_emited;
108
109 int tex_lru_log_granularity;
110 int allow_batchbuffer;
111 struct mem_block *agp_heap;
112 unsigned int sr01, adpa, ppcr, dvob, dvoc, lvds;
113 int vblank_pipe;
114 spinlock_t user_irq_lock;
115 int user_irq_refcount;
116 int fence_irq_on;
117 uint32_t irq_enable_reg;
118 int irq_enabled;
119
120 spinlock_t swaps_lock;
121 drm_i915_vbl_swap_t vbl_swaps;
122 unsigned int swaps_pending;
123
124 /* Register state */
125 u8 saveLBB;
126 u32 saveDSPACNTR;
127 u32 saveDSPBCNTR;
128 u32 savePIPEACONF;
129 u32 savePIPEBCONF;
130 u32 savePIPEASRC;
131 u32 savePIPEBSRC;
132 u32 saveFPA0;
133 u32 saveFPA1;
134 u32 saveDPLL_A;
135 u32 saveDPLL_A_MD;
136 u32 saveHTOTAL_A;
137 u32 saveHBLANK_A;
138 u32 saveHSYNC_A;
139 u32 saveVTOTAL_A;
140 u32 saveVBLANK_A;
141 u32 saveVSYNC_A;
142 u32 saveBCLRPAT_A;
143 u32 savePIPEASTAT;
144 u32 saveDSPASTRIDE;
145 u32 saveDSPASIZE;
146 u32 saveDSPAPOS;
147 u32 saveDSPABASE;
148 u32 saveDSPASURF;
149 u32 saveDSPATILEOFF;
150 u32 savePFIT_PGM_RATIOS;
151 u32 saveBLC_PWM_CTL;
152 u32 saveBLC_PWM_CTL2;
153 u32 saveFPB0;
154 u32 saveFPB1;
155 u32 saveDPLL_B;
156 u32 saveDPLL_B_MD;
157 u32 saveHTOTAL_B;
158 u32 saveHBLANK_B;
159 u32 saveHSYNC_B;
160 u32 saveVTOTAL_B;
161 u32 saveVBLANK_B;
162 u32 saveVSYNC_B;
163 u32 saveBCLRPAT_B;
164 u32 savePIPEBSTAT;
165 u32 saveDSPBSTRIDE;
166 u32 saveDSPBSIZE;
167 u32 saveDSPBPOS;
168 u32 saveDSPBBASE;
169 u32 saveDSPBSURF;
170 u32 saveDSPBTILEOFF;
171 u32 saveVCLK_DIVISOR_VGA0;
172 u32 saveVCLK_DIVISOR_VGA1;
173 u32 saveVCLK_POST_DIV;
174 u32 saveVGACNTRL;
175 u32 saveADPA;
176 u32 saveLVDS;
177 u32 saveLVDSPP_ON;
178 u32 saveLVDSPP_OFF;
179 u32 saveDVOA;
180 u32 saveDVOB;
181 u32 saveDVOC;
182 u32 savePP_ON;
183 u32 savePP_OFF;
184 u32 savePP_CONTROL;
185 u32 savePP_CYCLE;
186 u32 savePFIT_CONTROL;
187 u32 save_palette_a[256];
188 u32 save_palette_b[256];
189 u32 saveFBC_CFB_BASE;
190 u32 saveFBC_LL_BASE;
191 u32 saveFBC_CONTROL;
192 u32 saveFBC_CONTROL2;
193 u32 saveIER;
194 u32 saveIIR;
195 u32 saveIMR;
196 u32 saveCACHE_MODE_0;
197 u32 saveDSPCLK_GATE_D;
198 u32 saveMI_ARB_STATE;
199 u32 saveSWF0[16];
200 u32 saveSWF1[16];
201 u32 saveSWF2[3];
202 u8 saveMSR;
203 u8 saveSR[8];
204 u8 saveGR[25];
205 u8 saveAR_INDEX;
206 u8 saveAR[20];
207 u8 saveDACMASK;
208 u8 saveDACDATA[256*3]; /* 256 3-byte colors */
209 u8 saveCR[36];
210} drm_i915_private_t;
211
212extern struct drm_ioctl_desc i915_ioctls[];
213extern int i915_max_ioctl;
214
215 /* i915_dma.c */
216extern void i915_kernel_lost_context(struct drm_device * dev);
217extern int i915_driver_load(struct drm_device *, unsigned long flags);
218extern int i915_driver_unload(struct drm_device *);
219extern void i915_driver_lastclose(struct drm_device * dev);
220extern void i915_driver_preclose(struct drm_device *dev,
221 struct drm_file *file_priv);
222extern int i915_driver_device_is_agp(struct drm_device * dev);
223extern long i915_compat_ioctl(struct file *filp, unsigned int cmd,
224 unsigned long arg);
225extern void i915_dispatch_flip(struct drm_device * dev, int pipes, int sync);
226/* i915_irq.c */
227extern int i915_irq_emit(struct drm_device *dev, void *data,
228 struct drm_file *file_priv);
229extern int i915_irq_wait(struct drm_device *dev, void *data,
230 struct drm_file *file_priv);
231
232extern int i915_driver_vblank_wait(struct drm_device *dev, unsigned int *sequence);
233extern int i915_driver_vblank_wait2(struct drm_device *dev, unsigned int *sequence);
234extern irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS);
235extern void i915_driver_irq_preinstall(struct drm_device * dev);
236extern int i915_driver_irq_postinstall(struct drm_device * dev);
237extern void i915_driver_irq_uninstall(struct drm_device * dev);
238extern int i915_vblank_pipe_set(struct drm_device *dev, void *data,
239 struct drm_file *file_priv);
240extern int i915_vblank_pipe_get(struct drm_device *dev, void *data,
241 struct drm_file *file_priv);
242extern int i915_vblank_swap(struct drm_device *dev, void *data,
243 struct drm_file *file_priv);
244extern int i915_enable_vblank(struct drm_device *dev, int crtc);
245extern void i915_disable_vblank(struct drm_device *dev, int crtc);
246extern u32 i915_get_vblank_counter(struct drm_device *dev, int crtc);
247
248/* i915_mem.c */
249extern int i915_mem_alloc(struct drm_device *dev, void *data,
250 struct drm_file *file_priv);
251extern int i915_mem_free(struct drm_device *dev, void *data,
252 struct drm_file *file_priv);
253extern int i915_mem_init_heap(struct drm_device *dev, void *data,
254 struct drm_file *file_priv);
255extern int i915_mem_destroy_heap(struct drm_device *dev, void *data,
256 struct drm_file *file_priv);
257extern void i915_mem_takedown(struct mem_block **heap);
258extern void i915_mem_release(struct drm_device * dev,
259 struct drm_file *file_priv, struct mem_block *heap);
260
261#define I915_READ(reg) DRM_READ32(dev_priv->mmio_map, (reg))
262#define I915_WRITE(reg,val) DRM_WRITE32(dev_priv->mmio_map, (reg), (val))
263#define I915_READ16(reg) DRM_READ16(dev_priv->mmio_map, (reg))
264#define I915_WRITE16(reg,val) DRM_WRITE16(dev_priv->mmio_map, (reg), (val))
265
266#define I915_VERBOSE 0
267
268#define RING_LOCALS unsigned int outring, ringmask, outcount; \
269 volatile char *virt;
270
271#define BEGIN_LP_RING(n) do { \
272 if (I915_VERBOSE) \
273 DRM_DEBUG("BEGIN_LP_RING(%d)\n", (n)); \
274 if (dev_priv->ring.space < (n)*4) \
275 i915_wait_ring(dev, (n)*4, __func__); \
276 outcount = 0; \
277 outring = dev_priv->ring.tail; \
278 ringmask = dev_priv->ring.tail_mask; \
279 virt = dev_priv->ring.virtual_start; \
280} while (0)
281
282#define OUT_RING(n) do { \
283 if (I915_VERBOSE) DRM_DEBUG(" OUT_RING %x\n", (int)(n)); \
284 *(volatile unsigned int *)(virt + outring) = (n); \
285 outcount++; \
286 outring += 4; \
287 outring &= ringmask; \
288} while (0)
289
290#define ADVANCE_LP_RING() do { \
291 if (I915_VERBOSE) DRM_DEBUG("ADVANCE_LP_RING %x\n", outring); \
292 dev_priv->ring.tail = outring; \
293 dev_priv->ring.space -= outcount * 4; \
294 I915_WRITE(LP_RING + RING_TAIL, outring); \
295} while(0)
296
297extern int i915_wait_ring(struct drm_device * dev, int n, const char *caller);
298
299/* Extended config space */
300#define LBB 0xf4
301
302/* VGA stuff */
303
304#define VGA_ST01_MDA 0x3ba
305#define VGA_ST01_CGA 0x3da
306
307#define VGA_MSR_WRITE 0x3c2
308#define VGA_MSR_READ 0x3cc
309#define VGA_MSR_MEM_EN (1<<1)
310#define VGA_MSR_CGA_MODE (1<<0)
311
312#define VGA_SR_INDEX 0x3c4
313#define VGA_SR_DATA 0x3c5
314
315#define VGA_AR_INDEX 0x3c0
316#define VGA_AR_VID_EN (1<<5)
317#define VGA_AR_DATA_WRITE 0x3c0
318#define VGA_AR_DATA_READ 0x3c1
319
320#define VGA_GR_INDEX 0x3ce
321#define VGA_GR_DATA 0x3cf
322/* GR05 */
323#define VGA_GR_MEM_READ_MODE_SHIFT 3
324#define VGA_GR_MEM_READ_MODE_PLANE 1
325/* GR06 */
326#define VGA_GR_MEM_MODE_MASK 0xc
327#define VGA_GR_MEM_MODE_SHIFT 2
328#define VGA_GR_MEM_A0000_AFFFF 0
329#define VGA_GR_MEM_A0000_BFFFF 1
330#define VGA_GR_MEM_B0000_B7FFF 2
331#define VGA_GR_MEM_B0000_BFFFF 3
332
333#define VGA_DACMASK 0x3c6
334#define VGA_DACRX 0x3c7
335#define VGA_DACWX 0x3c8
336#define VGA_DACDATA 0x3c9
337
338#define VGA_CR_INDEX_MDA 0x3b4
339#define VGA_CR_DATA_MDA 0x3b5
340#define VGA_CR_INDEX_CGA 0x3d4
341#define VGA_CR_DATA_CGA 0x3d5
342
343#define GFX_OP_USER_INTERRUPT ((0<<29)|(2<<23))
344#define GFX_OP_BREAKPOINT_INTERRUPT ((0<<29)|(1<<23))
345#define CMD_REPORT_HEAD (7<<23)
346#define CMD_STORE_DWORD_IDX ((0x21<<23) | 0x1)
347#define CMD_OP_BATCH_BUFFER ((0x0<<29)|(0x30<<23)|0x1)
348
349#define INST_PARSER_CLIENT 0x00000000
350#define INST_OP_FLUSH 0x02000000
351#define INST_FLUSH_MAP_CACHE 0x00000001
352
353#define BB1_START_ADDR_MASK (~0x7)
354#define BB1_PROTECTED (1<<0)
355#define BB1_UNPROTECTED (0<<0)
356#define BB2_END_ADDR_MASK (~0x7)
357
358/* Framebuffer compression */
359#define FBC_CFB_BASE 0x03200 /* 4k page aligned */
360#define FBC_LL_BASE 0x03204 /* 4k page aligned */
361#define FBC_CONTROL 0x03208
362#define FBC_CTL_EN (1<<31)
363#define FBC_CTL_PERIODIC (1<<30)
364#define FBC_CTL_INTERVAL_SHIFT (16)
365#define FBC_CTL_UNCOMPRESSIBLE (1<<14)
366#define FBC_CTL_STRIDE_SHIFT (5)
367#define FBC_CTL_FENCENO (1<<0)
368#define FBC_COMMAND 0x0320c
369#define FBC_CMD_COMPRESS (1<<0)
370#define FBC_STATUS 0x03210
371#define FBC_STAT_COMPRESSING (1<<31)
372#define FBC_STAT_COMPRESSED (1<<30)
373#define FBC_STAT_MODIFIED (1<<29)
374#define FBC_STAT_CURRENT_LINE (1<<0)
375#define FBC_CONTROL2 0x03214
376#define FBC_CTL_FENCE_DBL (0<<4)
377#define FBC_CTL_IDLE_IMM (0<<2)
378#define FBC_CTL_IDLE_FULL (1<<2)
379#define FBC_CTL_IDLE_LINE (2<<2)
380#define FBC_CTL_IDLE_DEBUG (3<<2)
381#define FBC_CTL_CPU_FENCE (1<<1)
382#define FBC_CTL_PLANEA (0<<0)
383#define FBC_CTL_PLANEB (1<<0)
384#define FBC_FENCE_OFF 0x0321b
385
386#define FBC_LL_SIZE (1536)
387#define FBC_LL_PAD (32)
388
389/* Interrupt bits:
390 */
391#define I915_PIPE_CONTROL_NOTIFY_INTERRUPT (1<<18)
392#define I915_DISPLAY_PORT_INTERRUPT (1<<17)
393#define I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT (1<<15)
394#define I915_GMCH_THERMAL_SENSOR_EVENT_INTERRUPT (1<<14)
395#define I915_HWB_OOM_INTERRUPT (1<<13) /* binner out of memory */
396#define I915_SYNC_STATUS_INTERRUPT (1<<12)
397#define I915_DISPLAY_PLANE_A_FLIP_PENDING_INTERRUPT (1<<11)
398#define I915_DISPLAY_PLANE_B_FLIP_PENDING_INTERRUPT (1<<10)
399#define I915_OVERLAY_PLANE_FLIP_PENDING_INTERRUPT (1<<9)
400#define I915_DISPLAY_PLANE_C_FLIP_PENDING_INTERRUPT (1<<8)
401#define I915_DISPLAY_PIPE_A_VBLANK_INTERRUPT (1<<7)
402#define I915_DISPLAY_PIPE_A_EVENT_INTERRUPT (1<<6)
403#define I915_DISPLAY_PIPE_B_VBLANK_INTERRUPT (1<<5)
404#define I915_DISPLAY_PIPE_B_EVENT_INTERRUPT (1<<4)
405#define I915_DEBUG_INTERRUPT (1<<2)
406#define I915_USER_INTERRUPT (1<<1)
407
408
409#define I915REG_HWSTAM 0x02098
410#define I915REG_INT_IDENTITY_R 0x020a4
411#define I915REG_INT_MASK_R 0x020a8
412#define I915REG_INT_ENABLE_R 0x020a0
413#define I915REG_INSTPM 0x020c0
414
415#define PIPEADSL 0x70000
416#define PIPEBDSL 0x71000
417
418#define I915REG_PIPEASTAT 0x70024
419#define I915REG_PIPEBSTAT 0x71024
420/*
421 * The two pipe frame counter registers are not synchronized, so
422 * reading a stable value is somewhat tricky. The following code
423 * should work:
424 *
425 * do {
426 * high1 = ((INREG(PIPEAFRAMEHIGH) & PIPE_FRAME_HIGH_MASK) >>
427 * PIPE_FRAME_HIGH_SHIFT;
428 * low1 = ((INREG(PIPEAFRAMEPIXEL) & PIPE_FRAME_LOW_MASK) >>
429 * PIPE_FRAME_LOW_SHIFT);
430 * high2 = ((INREG(PIPEAFRAMEHIGH) & PIPE_FRAME_HIGH_MASK) >>
431 * PIPE_FRAME_HIGH_SHIFT);
432 * } while (high1 != high2);
433 * frame = (high1 << 8) | low1;
434 */
435#define PIPEAFRAMEHIGH 0x70040
436#define PIPEBFRAMEHIGH 0x71040
437#define PIPE_FRAME_HIGH_MASK 0x0000ffff
438#define PIPE_FRAME_HIGH_SHIFT 0
439#define PIPEAFRAMEPIXEL 0x70044
440#define PIPEBFRAMEPIXEL 0x71044
441
442#define PIPE_FRAME_LOW_MASK 0xff000000
443#define PIPE_FRAME_LOW_SHIFT 24
444/*
445 * Pixel within the current frame is counted in the PIPEAFRAMEPIXEL register
446 * and is 24 bits wide.
447 */
448#define PIPE_PIXEL_MASK 0x00ffffff
449#define PIPE_PIXEL_SHIFT 0
450
451#define I915_FIFO_UNDERRUN_STATUS (1UL<<31)
452#define I915_CRC_ERROR_ENABLE (1UL<<29)
453#define I915_CRC_DONE_ENABLE (1UL<<28)
454#define I915_GMBUS_EVENT_ENABLE (1UL<<27)
455#define I915_VSYNC_INTERRUPT_ENABLE (1UL<<25)
456#define I915_DISPLAY_LINE_COMPARE_ENABLE (1UL<<24)
457#define I915_DPST_EVENT_ENABLE (1UL<<23)
458#define I915_LEGACY_BLC_EVENT_ENABLE (1UL<<22)
459#define I915_ODD_FIELD_INTERRUPT_ENABLE (1UL<<21)
460#define I915_EVEN_FIELD_INTERRUPT_ENABLE (1UL<<20)
461#define I915_START_VBLANK_INTERRUPT_ENABLE (1UL<<18) /* 965 or later */
462#define I915_VBLANK_INTERRUPT_ENABLE (1UL<<17)
463#define I915_OVERLAY_UPDATED_ENABLE (1UL<<16)
464#define I915_CRC_ERROR_INTERRUPT_STATUS (1UL<<13)
465#define I915_CRC_DONE_INTERRUPT_STATUS (1UL<<12)
466#define I915_GMBUS_INTERRUPT_STATUS (1UL<<11)
467#define I915_VSYNC_INTERRUPT_STATUS (1UL<<9)
468#define I915_DISPLAY_LINE_COMPARE_STATUS (1UL<<8)
469#define I915_DPST_EVENT_STATUS (1UL<<7)
470#define I915_LEGACY_BLC_EVENT_STATUS (1UL<<6)
471#define I915_ODD_FIELD_INTERRUPT_STATUS (1UL<<5)
472#define I915_EVEN_FIELD_INTERRUPT_STATUS (1UL<<4)
473#define I915_START_VBLANK_INTERRUPT_STATUS (1UL<<2) /* 965 or later */
474#define I915_VBLANK_INTERRUPT_STATUS (1UL<<1)
475#define I915_OVERLAY_UPDATED_STATUS (1UL<<0)
476
477#define SRX_INDEX 0x3c4
478#define SRX_DATA 0x3c5
479#define SR01 1
480#define SR01_SCREEN_OFF (1<<5)
481
482#define PPCR 0x61204
483#define PPCR_ON (1<<0)
484
485#define DVOB 0x61140
486#define DVOB_ON (1<<31)
487#define DVOC 0x61160
488#define DVOC_ON (1<<31)
489#define LVDS 0x61180
490#define LVDS_ON (1<<31)
491
492#define ADPA 0x61100
493#define ADPA_DPMS_MASK (~(3<<10))
494#define ADPA_DPMS_ON (0<<10)
495#define ADPA_DPMS_SUSPEND (1<<10)
496#define ADPA_DPMS_STANDBY (2<<10)
497#define ADPA_DPMS_OFF (3<<10)
498
499#define NOPID 0x2094
500#define LP_RING 0x2030
501#define HP_RING 0x2040
502/* The binner has its own ring buffer:
503 */
504#define HWB_RING 0x2400
505
506#define RING_TAIL 0x00
507#define TAIL_ADDR 0x001FFFF8
508#define RING_HEAD 0x04
509#define HEAD_WRAP_COUNT 0xFFE00000
510#define HEAD_WRAP_ONE 0x00200000
511#define HEAD_ADDR 0x001FFFFC
512#define RING_START 0x08
513#define START_ADDR 0x0xFFFFF000
514#define RING_LEN 0x0C
515#define RING_NR_PAGES 0x001FF000
516#define RING_REPORT_MASK 0x00000006
517#define RING_REPORT_64K 0x00000002
518#define RING_REPORT_128K 0x00000004
519#define RING_NO_REPORT 0x00000000
520#define RING_VALID_MASK 0x00000001
521#define RING_VALID 0x00000001
522#define RING_INVALID 0x00000000
523
524/* Instruction parser error reg:
525 */
526#define IPEIR 0x2088
527
528/* Scratch pad debug 0 reg:
529 */
530#define SCPD0 0x209c
531
532/* Error status reg:
533 */
534#define ESR 0x20b8
535
536/* Secondary DMA fetch address debug reg:
537 */
538#define DMA_FADD_S 0x20d4
539
540/* Memory Interface Arbitration State
541 */
542#define MI_ARB_STATE 0x20e4
543
544/* Cache mode 0 reg.
545 * - Manipulating render cache behaviour is central
546 * to the concept of zone rendering, tuning this reg can help avoid
547 * unnecessary render cache reads and even writes (for z/stencil)
548 * at beginning and end of scene.
549 *
550 * - To change a bit, write to this reg with a mask bit set and the
551 * bit of interest either set or cleared. EG: (BIT<<16) | BIT to set.
552 */
553#define Cache_Mode_0 0x2120
554#define CACHE_MODE_0 0x2120
555#define CM0_MASK_SHIFT 16
556#define CM0_IZ_OPT_DISABLE (1<<6)
557#define CM0_ZR_OPT_DISABLE (1<<5)
558#define CM0_DEPTH_EVICT_DISABLE (1<<4)
559#define CM0_COLOR_EVICT_DISABLE (1<<3)
560#define CM0_DEPTH_WRITE_DISABLE (1<<1)
561#define CM0_RC_OP_FLUSH_DISABLE (1<<0)
562
563
564/* Graphics flush control. A CPU write flushes the GWB of all writes.
565 * The data is discarded.
566 */
567#define GFX_FLSH_CNTL 0x2170
568
569/* Binner control. Defines the location of the bin pointer list:
570 */
571#define BINCTL 0x2420
572#define BC_MASK (1 << 9)
573
574/* Binned scene info.
575 */
576#define BINSCENE 0x2428
577#define BS_OP_LOAD (1 << 8)
578#define BS_MASK (1 << 22)
579
580/* Bin command parser debug reg:
581 */
582#define BCPD 0x2480
583
584/* Bin memory control debug reg:
585 */
586#define BMCD 0x2484
587
588/* Bin data cache debug reg:
589 */
590#define BDCD 0x2488
591
592/* Binner pointer cache debug reg:
593 */
594#define BPCD 0x248c
595
596/* Binner scratch pad debug reg:
597 */
598#define BINSKPD 0x24f0
599
600/* HWB scratch pad debug reg:
601 */
602#define HWBSKPD 0x24f4
603
604/* Binner memory pool reg:
605 */
606#define BMP_BUFFER 0x2430
607#define BMP_PAGE_SIZE_4K (0 << 10)
608#define BMP_BUFFER_SIZE_SHIFT 1
609#define BMP_ENABLE (1 << 0)
610
611/* Get/put memory from the binner memory pool:
612 */
613#define BMP_GET 0x2438
614#define BMP_PUT 0x2440
615#define BMP_OFFSET_SHIFT 5
616
617/* 3D state packets:
618 */
619#define GFX_OP_RASTER_RULES ((0x3<<29)|(0x7<<24))
620
621#define GFX_OP_SCISSOR ((0x3<<29)|(0x1c<<24)|(0x10<<19))
622#define SC_UPDATE_SCISSOR (0x1<<1)
623#define SC_ENABLE_MASK (0x1<<0)
624#define SC_ENABLE (0x1<<0)
625
626#define GFX_OP_LOAD_INDIRECT ((0x3<<29)|(0x1d<<24)|(0x7<<16))
627
628#define GFX_OP_SCISSOR_INFO ((0x3<<29)|(0x1d<<24)|(0x81<<16)|(0x1))
629#define SCI_YMIN_MASK (0xffff<<16)
630#define SCI_XMIN_MASK (0xffff<<0)
631#define SCI_YMAX_MASK (0xffff<<16)
632#define SCI_XMAX_MASK (0xffff<<0)
633
634#define GFX_OP_SCISSOR_ENABLE ((0x3<<29)|(0x1c<<24)|(0x10<<19))
635#define GFX_OP_SCISSOR_RECT ((0x3<<29)|(0x1d<<24)|(0x81<<16)|1)
636#define GFX_OP_COLOR_FACTOR ((0x3<<29)|(0x1d<<24)|(0x1<<16)|0x0)
637#define GFX_OP_STIPPLE ((0x3<<29)|(0x1d<<24)|(0x83<<16))
638#define GFX_OP_MAP_INFO ((0x3<<29)|(0x1d<<24)|0x4)
639#define GFX_OP_DESTBUFFER_VARS ((0x3<<29)|(0x1d<<24)|(0x85<<16)|0x0)
640#define GFX_OP_DRAWRECT_INFO ((0x3<<29)|(0x1d<<24)|(0x80<<16)|(0x3))
641
642#define GFX_OP_DRAWRECT_INFO_I965 ((0x7900<<16)|0x2)
643
644#define SRC_COPY_BLT_CMD ((2<<29)|(0x43<<22)|4)
645#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6)
646#define XY_SRC_COPY_BLT_WRITE_ALPHA (1<<21)
647#define XY_SRC_COPY_BLT_WRITE_RGB (1<<20)
648#define XY_SRC_COPY_BLT_SRC_TILED (1<<15)
649#define XY_SRC_COPY_BLT_DST_TILED (1<<11)
650
651#define MI_BATCH_BUFFER ((0x30<<23)|1)
652#define MI_BATCH_BUFFER_START (0x31<<23)
653#define MI_BATCH_BUFFER_END (0xA<<23)
654#define MI_BATCH_NON_SECURE (1)
655#define MI_BATCH_NON_SECURE_I965 (1<<8)
656
657#define MI_WAIT_FOR_EVENT ((0x3<<23))
658#define MI_WAIT_FOR_PLANE_B_FLIP (1<<6)
659#define MI_WAIT_FOR_PLANE_A_FLIP (1<<2)
660#define MI_WAIT_FOR_PLANE_A_SCANLINES (1<<1)
661
662#define MI_LOAD_SCAN_LINES_INCL ((0x12<<23))
663
664#define CMD_OP_DISPLAYBUFFER_INFO ((0x0<<29)|(0x14<<23)|2)
665#define ASYNC_FLIP (1<<22)
666#define DISPLAY_PLANE_A (0<<20)
667#define DISPLAY_PLANE_B (1<<20)
668
669/* Display regs */
670#define DSPACNTR 0x70180
671#define DSPBCNTR 0x71180
672#define DISPPLANE_SEL_PIPE_MASK (1<<24)
673
674/* Define the region of interest for the binner:
675 */
676#define CMD_OP_BIN_CONTROL ((0x3<<29)|(0x1d<<24)|(0x84<<16)|4)
677
678#define CMD_OP_DESTBUFFER_INFO ((0x3<<29)|(0x1d<<24)|(0x8e<<16)|1)
679
680#define CMD_MI_FLUSH (0x04 << 23)
681#define MI_NO_WRITE_FLUSH (1 << 2)
682#define MI_READ_FLUSH (1 << 0)
683#define MI_EXE_FLUSH (1 << 1)
684#define MI_END_SCENE (1 << 4) /* flush binner and incr scene count */
685#define MI_SCENE_COUNT (1 << 3) /* just increment scene count */
686
687#define BREADCRUMB_BITS 31
688#define BREADCRUMB_MASK ((1U << BREADCRUMB_BITS) - 1)
689
690#define READ_BREADCRUMB(dev_priv) (((volatile u32*)(dev_priv->hw_status_page))[5])
691#define READ_HWSP(dev_priv, reg) (((volatile u32*)(dev_priv->hw_status_page))[reg])
692
693#define BLC_PWM_CTL 0x61254
694#define BACKLIGHT_MODULATION_FREQ_SHIFT (17)
695
696#define BLC_PWM_CTL2 0x61250
697/**
698 * This is the most significant 15 bits of the number of backlight cycles in a
699 * complete cycle of the modulated backlight control.
700 *
701 * The actual value is this field multiplied by two.
702 */
703#define BACKLIGHT_MODULATION_FREQ_MASK (0x7fff << 17)
704#define BLM_LEGACY_MODE (1 << 16)
705/**
706 * This is the number of cycles out of the backlight modulation cycle for which
707 * the backlight is on.
708 *
709 * This field must be no greater than the number of cycles in the complete
710 * backlight modulation cycle.
711 */
712#define BACKLIGHT_DUTY_CYCLE_SHIFT (0)
713#define BACKLIGHT_DUTY_CYCLE_MASK (0xffff)
714
715#define I915_GCFGC 0xf0
716#define I915_LOW_FREQUENCY_ENABLE (1 << 7)
717#define I915_DISPLAY_CLOCK_190_200_MHZ (0 << 4)
718#define I915_DISPLAY_CLOCK_333_MHZ (4 << 4)
719#define I915_DISPLAY_CLOCK_MASK (7 << 4)
720
721#define I855_HPLLCC 0xc0
722#define I855_CLOCK_CONTROL_MASK (3 << 0)
723#define I855_CLOCK_133_200 (0 << 0)
724#define I855_CLOCK_100_200 (1 << 0)
725#define I855_CLOCK_100_133 (2 << 0)
726#define I855_CLOCK_166_250 (3 << 0)
727
728/* p317, 319
729 */
730#define VCLK2_VCO_M 0x6008 /* treat as 16 bit? (includes msbs) */
731#define VCLK2_VCO_N 0x600a
732#define VCLK2_VCO_DIV_SEL 0x6012
733
734#define VCLK_DIVISOR_VGA0 0x6000
735#define VCLK_DIVISOR_VGA1 0x6004
736#define VCLK_POST_DIV 0x6010
737/** Selects a post divisor of 4 instead of 2. */
738# define VGA1_PD_P2_DIV_4 (1 << 15)
739/** Overrides the p2 post divisor field */
740# define VGA1_PD_P1_DIV_2 (1 << 13)
741# define VGA1_PD_P1_SHIFT 8
742/** P1 value is 2 greater than this field */
743# define VGA1_PD_P1_MASK (0x1f << 8)
744/** Selects a post divisor of 4 instead of 2. */
745# define VGA0_PD_P2_DIV_4 (1 << 7)
746/** Overrides the p2 post divisor field */
747# define VGA0_PD_P1_DIV_2 (1 << 5)
748# define VGA0_PD_P1_SHIFT 0
749/** P1 value is 2 greater than this field */
750# define VGA0_PD_P1_MASK (0x1f << 0)
751
752#define DSPCLK_GATE_D 0x6200
753
754/* I830 CRTC registers */
755#define HTOTAL_A 0x60000
756#define HBLANK_A 0x60004
757#define HSYNC_A 0x60008
758#define VTOTAL_A 0x6000c
759#define VBLANK_A 0x60010
760#define VSYNC_A 0x60014
761#define PIPEASRC 0x6001c
762#define BCLRPAT_A 0x60020
763#define VSYNCSHIFT_A 0x60028
764
765#define HTOTAL_B 0x61000
766#define HBLANK_B 0x61004
767#define HSYNC_B 0x61008
768#define VTOTAL_B 0x6100c
769#define VBLANK_B 0x61010
770#define VSYNC_B 0x61014
771#define PIPEBSRC 0x6101c
772#define BCLRPAT_B 0x61020
773#define VSYNCSHIFT_B 0x61028
774
775#define PP_STATUS 0x61200
776# define PP_ON (1 << 31)
777/**
778 * Indicates that all dependencies of the panel are on:
779 *
780 * - PLL enabled
781 * - pipe enabled
782 * - LVDS/DVOB/DVOC on
783 */
784# define PP_READY (1 << 30)
785# define PP_SEQUENCE_NONE (0 << 28)
786# define PP_SEQUENCE_ON (1 << 28)
787# define PP_SEQUENCE_OFF (2 << 28)
788# define PP_SEQUENCE_MASK 0x30000000
789#define PP_CONTROL 0x61204
790# define POWER_TARGET_ON (1 << 0)
791
792#define LVDSPP_ON 0x61208
793#define LVDSPP_OFF 0x6120c
794#define PP_CYCLE 0x61210
795
796#define PFIT_CONTROL 0x61230
797# define PFIT_ENABLE (1 << 31)
798# define PFIT_PIPE_MASK (3 << 29)
799# define PFIT_PIPE_SHIFT 29
800# define VERT_INTERP_DISABLE (0 << 10)
801# define VERT_INTERP_BILINEAR (1 << 10)
802# define VERT_INTERP_MASK (3 << 10)
803# define VERT_AUTO_SCALE (1 << 9)
804# define HORIZ_INTERP_DISABLE (0 << 6)
805# define HORIZ_INTERP_BILINEAR (1 << 6)
806# define HORIZ_INTERP_MASK (3 << 6)
807# define HORIZ_AUTO_SCALE (1 << 5)
808# define PANEL_8TO6_DITHER_ENABLE (1 << 3)
809
810#define PFIT_PGM_RATIOS 0x61234
811# define PFIT_VERT_SCALE_MASK 0xfff00000
812# define PFIT_HORIZ_SCALE_MASK 0x0000fff0
813
814#define PFIT_AUTO_RATIOS 0x61238
815
816
817#define DPLL_A 0x06014
818#define DPLL_B 0x06018
819# define DPLL_VCO_ENABLE (1 << 31)
820# define DPLL_DVO_HIGH_SPEED (1 << 30)
821# define DPLL_SYNCLOCK_ENABLE (1 << 29)
822# define DPLL_VGA_MODE_DIS (1 << 28)
823# define DPLLB_MODE_DAC_SERIAL (1 << 26) /* i915 */
824# define DPLLB_MODE_LVDS (2 << 26) /* i915 */
825# define DPLL_MODE_MASK (3 << 26)
826# define DPLL_DAC_SERIAL_P2_CLOCK_DIV_10 (0 << 24) /* i915 */
827# define DPLL_DAC_SERIAL_P2_CLOCK_DIV_5 (1 << 24) /* i915 */
828# define DPLLB_LVDS_P2_CLOCK_DIV_14 (0 << 24) /* i915 */
829# define DPLLB_LVDS_P2_CLOCK_DIV_7 (1 << 24) /* i915 */
830# define DPLL_P2_CLOCK_DIV_MASK 0x03000000 /* i915 */
831# define DPLL_FPA01_P1_POST_DIV_MASK 0x00ff0000 /* i915 */
832/**
833 * The i830 generation, in DAC/serial mode, defines p1 as two plus this
834 * bitfield, or just 2 if PLL_P1_DIVIDE_BY_TWO is set.
835 */
836# define DPLL_FPA01_P1_POST_DIV_MASK_I830 0x001f0000
837/**
838 * The i830 generation, in LVDS mode, defines P1 as the bit number set within
839 * this field (only one bit may be set).
840 */
841# define DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS 0x003f0000
842# define DPLL_FPA01_P1_POST_DIV_SHIFT 16
843# define PLL_P2_DIVIDE_BY_4 (1 << 23) /* i830, required in DVO non-gang */
844# define PLL_P1_DIVIDE_BY_TWO (1 << 21) /* i830 */
845# define PLL_REF_INPUT_DREFCLK (0 << 13)
846# define PLL_REF_INPUT_TVCLKINA (1 << 13) /* i830 */
847# define PLL_REF_INPUT_TVCLKINBC (2 << 13) /* SDVO TVCLKIN */
848# define PLLB_REF_INPUT_SPREADSPECTRUMIN (3 << 13)
849# define PLL_REF_INPUT_MASK (3 << 13)
850# define PLL_LOAD_PULSE_PHASE_SHIFT 9
851/*
852 * Parallel to Serial Load Pulse phase selection.
853 * Selects the phase for the 10X DPLL clock for the PCIe
854 * digital display port. The range is 4 to 13; 10 or more
855 * is just a flip delay. The default is 6
856 */
857# define PLL_LOAD_PULSE_PHASE_MASK (0xf << PLL_LOAD_PULSE_PHASE_SHIFT)
858# define DISPLAY_RATE_SELECT_FPA1 (1 << 8)
859
860/**
861 * SDVO multiplier for 945G/GM. Not used on 965.
862 *
863 * \sa DPLL_MD_UDI_MULTIPLIER_MASK
864 */
865# define SDVO_MULTIPLIER_MASK 0x000000ff
866# define SDVO_MULTIPLIER_SHIFT_HIRES 4
867# define SDVO_MULTIPLIER_SHIFT_VGA 0
868
869/** @defgroup DPLL_MD
870 * @{
871 */
872/** Pipe A SDVO/UDI clock multiplier/divider register for G965. */
873#define DPLL_A_MD 0x0601c
874/** Pipe B SDVO/UDI clock multiplier/divider register for G965. */
875#define DPLL_B_MD 0x06020
876/**
877 * UDI pixel divider, controlling how many pixels are stuffed into a packet.
878 *
879 * Value is pixels minus 1. Must be set to 1 pixel for SDVO.
880 */
881# define DPLL_MD_UDI_DIVIDER_MASK 0x3f000000
882# define DPLL_MD_UDI_DIVIDER_SHIFT 24
883/** UDI pixel divider for VGA, same as DPLL_MD_UDI_DIVIDER_MASK. */
884# define DPLL_MD_VGA_UDI_DIVIDER_MASK 0x003f0000
885# define DPLL_MD_VGA_UDI_DIVIDER_SHIFT 16
886/**
887 * SDVO/UDI pixel multiplier.
888 *
889 * SDVO requires that the bus clock rate be between 1 and 2 Ghz, and the bus
890 * clock rate is 10 times the DPLL clock. At low resolution/refresh rate
891 * modes, the bus rate would be below the limits, so SDVO allows for stuffing
892 * dummy bytes in the datastream at an increased clock rate, with both sides of
893 * the link knowing how many bytes are fill.
894 *
895 * So, for a mode with a dotclock of 65Mhz, we would want to double the clock
896 * rate to 130Mhz to get a bus rate of 1.30Ghz. The DPLL clock rate would be
897 * set to 130Mhz, and the SDVO multiplier set to 2x in this register and
898 * through an SDVO command.
899 *
900 * This register field has values of multiplication factor minus 1, with
901 * a maximum multiplier of 5 for SDVO.
902 */
903# define DPLL_MD_UDI_MULTIPLIER_MASK 0x00003f00
904# define DPLL_MD_UDI_MULTIPLIER_SHIFT 8
905/** SDVO/UDI pixel multiplier for VGA, same as DPLL_MD_UDI_MULTIPLIER_MASK.
906 * This best be set to the default value (3) or the CRT won't work. No,
907 * I don't entirely understand what this does...
908 */
909# define DPLL_MD_VGA_UDI_MULTIPLIER_MASK 0x0000003f
910# define DPLL_MD_VGA_UDI_MULTIPLIER_SHIFT 0
911/** @} */
912
913#define DPLL_TEST 0x606c
914# define DPLLB_TEST_SDVO_DIV_1 (0 << 22)
915# define DPLLB_TEST_SDVO_DIV_2 (1 << 22)
916# define DPLLB_TEST_SDVO_DIV_4 (2 << 22)
917# define DPLLB_TEST_SDVO_DIV_MASK (3 << 22)
918# define DPLLB_TEST_N_BYPASS (1 << 19)
919# define DPLLB_TEST_M_BYPASS (1 << 18)
920# define DPLLB_INPUT_BUFFER_ENABLE (1 << 16)
921# define DPLLA_TEST_N_BYPASS (1 << 3)
922# define DPLLA_TEST_M_BYPASS (1 << 2)
923# define DPLLA_INPUT_BUFFER_ENABLE (1 << 0)
924
925#define ADPA 0x61100
926#define ADPA_DAC_ENABLE (1<<31)
927#define ADPA_DAC_DISABLE 0
928#define ADPA_PIPE_SELECT_MASK (1<<30)
929#define ADPA_PIPE_A_SELECT 0
930#define ADPA_PIPE_B_SELECT (1<<30)
931#define ADPA_USE_VGA_HVPOLARITY (1<<15)
932#define ADPA_SETS_HVPOLARITY 0
933#define ADPA_VSYNC_CNTL_DISABLE (1<<11)
934#define ADPA_VSYNC_CNTL_ENABLE 0
935#define ADPA_HSYNC_CNTL_DISABLE (1<<10)
936#define ADPA_HSYNC_CNTL_ENABLE 0
937#define ADPA_VSYNC_ACTIVE_HIGH (1<<4)
938#define ADPA_VSYNC_ACTIVE_LOW 0
939#define ADPA_HSYNC_ACTIVE_HIGH (1<<3)
940#define ADPA_HSYNC_ACTIVE_LOW 0
941
942#define FPA0 0x06040
943#define FPA1 0x06044
944#define FPB0 0x06048
945#define FPB1 0x0604c
946# define FP_N_DIV_MASK 0x003f0000
947# define FP_N_DIV_SHIFT 16
948# define FP_M1_DIV_MASK 0x00003f00
949# define FP_M1_DIV_SHIFT 8
950# define FP_M2_DIV_MASK 0x0000003f
951# define FP_M2_DIV_SHIFT 0
952
953
954#define PORT_HOTPLUG_EN 0x61110
955# define SDVOB_HOTPLUG_INT_EN (1 << 26)
956# define SDVOC_HOTPLUG_INT_EN (1 << 25)
957# define TV_HOTPLUG_INT_EN (1 << 18)
958# define CRT_HOTPLUG_INT_EN (1 << 9)
959# define CRT_HOTPLUG_FORCE_DETECT (1 << 3)
960
961#define PORT_HOTPLUG_STAT 0x61114
962# define CRT_HOTPLUG_INT_STATUS (1 << 11)
963# define TV_HOTPLUG_INT_STATUS (1 << 10)
964# define CRT_HOTPLUG_MONITOR_MASK (3 << 8)
965# define CRT_HOTPLUG_MONITOR_COLOR (3 << 8)
966# define CRT_HOTPLUG_MONITOR_MONO (2 << 8)
967# define CRT_HOTPLUG_MONITOR_NONE (0 << 8)
968# define SDVOC_HOTPLUG_INT_STATUS (1 << 7)
969# define SDVOB_HOTPLUG_INT_STATUS (1 << 6)
970
971#define SDVOB 0x61140
972#define SDVOC 0x61160
973#define SDVO_ENABLE (1 << 31)
974#define SDVO_PIPE_B_SELECT (1 << 30)
975#define SDVO_STALL_SELECT (1 << 29)
976#define SDVO_INTERRUPT_ENABLE (1 << 26)
977/**
978 * 915G/GM SDVO pixel multiplier.
979 *
980 * Programmed value is multiplier - 1, up to 5x.
981 *
982 * \sa DPLL_MD_UDI_MULTIPLIER_MASK
983 */
984#define SDVO_PORT_MULTIPLY_MASK (7 << 23)
985#define SDVO_PORT_MULTIPLY_SHIFT 23
986#define SDVO_PHASE_SELECT_MASK (15 << 19)
987#define SDVO_PHASE_SELECT_DEFAULT (6 << 19)
988#define SDVO_CLOCK_OUTPUT_INVERT (1 << 18)
989#define SDVOC_GANG_MODE (1 << 16)
990#define SDVO_BORDER_ENABLE (1 << 7)
991#define SDVOB_PCIE_CONCURRENCY (1 << 3)
992#define SDVO_DETECTED (1 << 2)
993/* Bits to be preserved when writing */
994#define SDVOB_PRESERVE_MASK ((1 << 17) | (1 << 16) | (1 << 14))
995#define SDVOC_PRESERVE_MASK (1 << 17)
996
997/** @defgroup LVDS
998 * @{
999 */
1000/**
1001 * This register controls the LVDS output enable, pipe selection, and data
1002 * format selection.
1003 *
1004 * All of the clock/data pairs are force powered down by power sequencing.
1005 */
1006#define LVDS 0x61180
1007/**
1008 * Enables the LVDS port. This bit must be set before DPLLs are enabled, as
1009 * the DPLL semantics change when the LVDS is assigned to that pipe.
1010 */
1011# define LVDS_PORT_EN (1 << 31)
1012/** Selects pipe B for LVDS data. Must be set on pre-965. */
1013# define LVDS_PIPEB_SELECT (1 << 30)
1014
1015/**
1016 * Enables the A0-A2 data pairs and CLKA, containing 18 bits of color data per
1017 * pixel.
1018 */
1019# define LVDS_A0A2_CLKA_POWER_MASK (3 << 8)
1020# define LVDS_A0A2_CLKA_POWER_DOWN (0 << 8)
1021# define LVDS_A0A2_CLKA_POWER_UP (3 << 8)
1022/**
1023 * Controls the A3 data pair, which contains the additional LSBs for 24 bit
1024 * mode. Only enabled if LVDS_A0A2_CLKA_POWER_UP also indicates it should be
1025 * on.
1026 */
1027# define LVDS_A3_POWER_MASK (3 << 6)
1028# define LVDS_A3_POWER_DOWN (0 << 6)
1029# define LVDS_A3_POWER_UP (3 << 6)
1030/**
1031 * Controls the CLKB pair. This should only be set when LVDS_B0B3_POWER_UP
1032 * is set.
1033 */
1034# define LVDS_CLKB_POWER_MASK (3 << 4)
1035# define LVDS_CLKB_POWER_DOWN (0 << 4)
1036# define LVDS_CLKB_POWER_UP (3 << 4)
1037
1038/**
1039 * Controls the B0-B3 data pairs. This must be set to match the DPLL p2
1040 * setting for whether we are in dual-channel mode. The B3 pair will
1041 * additionally only be powered up when LVDS_A3_POWER_UP is set.
1042 */
1043# define LVDS_B0B3_POWER_MASK (3 << 2)
1044# define LVDS_B0B3_POWER_DOWN (0 << 2)
1045# define LVDS_B0B3_POWER_UP (3 << 2)
1046
1047#define PIPEACONF 0x70008
1048#define PIPEACONF_ENABLE (1<<31)
1049#define PIPEACONF_DISABLE 0
1050#define PIPEACONF_DOUBLE_WIDE (1<<30)
1051#define I965_PIPECONF_ACTIVE (1<<30)
1052#define PIPEACONF_SINGLE_WIDE 0
1053#define PIPEACONF_PIPE_UNLOCKED 0
1054#define PIPEACONF_PIPE_LOCKED (1<<25)
1055#define PIPEACONF_PALETTE 0
1056#define PIPEACONF_GAMMA (1<<24)
1057#define PIPECONF_FORCE_BORDER (1<<25)
1058#define PIPECONF_PROGRESSIVE (0 << 21)
1059#define PIPECONF_INTERLACE_W_FIELD_INDICATION (6 << 21)
1060#define PIPECONF_INTERLACE_FIELD_0_ONLY (7 << 21)
1061
1062#define PIPEBCONF 0x71008
1063#define PIPEBCONF_ENABLE (1<<31)
1064#define PIPEBCONF_DISABLE 0
1065#define PIPEBCONF_DOUBLE_WIDE (1<<30)
1066#define PIPEBCONF_DISABLE 0
1067#define PIPEBCONF_GAMMA (1<<24)
1068#define PIPEBCONF_PALETTE 0
1069
1070#define PIPEBGCMAXRED 0x71010
1071#define PIPEBGCMAXGREEN 0x71014
1072#define PIPEBGCMAXBLUE 0x71018
1073#define PIPEBSTAT 0x71024
1074#define PIPEBFRAMEHIGH 0x71040
1075#define PIPEBFRAMEPIXEL 0x71044
1076
1077#define DSPACNTR 0x70180
1078#define DSPBCNTR 0x71180
1079#define DISPLAY_PLANE_ENABLE (1<<31)
1080#define DISPLAY_PLANE_DISABLE 0
1081#define DISPPLANE_GAMMA_ENABLE (1<<30)
1082#define DISPPLANE_GAMMA_DISABLE 0
1083#define DISPPLANE_PIXFORMAT_MASK (0xf<<26)
1084#define DISPPLANE_8BPP (0x2<<26)
1085#define DISPPLANE_15_16BPP (0x4<<26)
1086#define DISPPLANE_16BPP (0x5<<26)
1087#define DISPPLANE_32BPP_NO_ALPHA (0x6<<26)
1088#define DISPPLANE_32BPP (0x7<<26)
1089#define DISPPLANE_STEREO_ENABLE (1<<25)
1090#define DISPPLANE_STEREO_DISABLE 0
1091#define DISPPLANE_SEL_PIPE_MASK (1<<24)
1092#define DISPPLANE_SEL_PIPE_A 0
1093#define DISPPLANE_SEL_PIPE_B (1<<24)
1094#define DISPPLANE_SRC_KEY_ENABLE (1<<22)
1095#define DISPPLANE_SRC_KEY_DISABLE 0
1096#define DISPPLANE_LINE_DOUBLE (1<<20)
1097#define DISPPLANE_NO_LINE_DOUBLE 0
1098#define DISPPLANE_STEREO_POLARITY_FIRST 0
1099#define DISPPLANE_STEREO_POLARITY_SECOND (1<<18)
1100/* plane B only */
1101#define DISPPLANE_ALPHA_TRANS_ENABLE (1<<15)
1102#define DISPPLANE_ALPHA_TRANS_DISABLE 0
1103#define DISPPLANE_SPRITE_ABOVE_DISPLAYA 0
1104#define DISPPLANE_SPRITE_ABOVE_OVERLAY (1)
1105
1106#define DSPABASE 0x70184
1107#define DSPASTRIDE 0x70188
1108
1109#define DSPBBASE 0x71184
1110#define DSPBADDR DSPBBASE
1111#define DSPBSTRIDE 0x71188
1112
1113#define DSPAKEYVAL 0x70194
1114#define DSPAKEYMASK 0x70198
1115
1116#define DSPAPOS 0x7018C /* reserved */
1117#define DSPASIZE 0x70190
1118#define DSPBPOS 0x7118C
1119#define DSPBSIZE 0x71190
1120
1121#define DSPASURF 0x7019C
1122#define DSPATILEOFF 0x701A4
1123
1124#define DSPBSURF 0x7119C
1125#define DSPBTILEOFF 0x711A4
1126
1127#define VGACNTRL 0x71400
1128# define VGA_DISP_DISABLE (1 << 31)
1129# define VGA_2X_MODE (1 << 30)
1130# define VGA_PIPE_B_SELECT (1 << 29)
1131
1132/*
1133 * Some BIOS scratch area registers. The 845 (and 830?) store the amount
1134 * of video memory available to the BIOS in SWF1.
1135 */
1136
1137#define SWF0 0x71410
1138
1139/*
1140 * 855 scratch registers.
1141 */
1142#define SWF10 0x70410
1143
1144#define SWF30 0x72414
1145
1146/*
1147 * Overlay registers. These are overlay registers accessed via MMIO.
1148 * Those loaded via the overlay register page are defined in i830_video.c.
1149 */
1150#define OVADD 0x30000
1151
1152#define DOVSTA 0x30008
1153#define OC_BUF (0x3<<20)
1154
1155#define OGAMC5 0x30010
1156#define OGAMC4 0x30014
1157#define OGAMC3 0x30018
1158#define OGAMC2 0x3001c
1159#define OGAMC1 0x30020
1160#define OGAMC0 0x30024
1161/*
1162 * Palette registers
1163 */
1164#define PALETTE_A 0x0a000
1165#define PALETTE_B 0x0a800
1166
1167#define IS_I830(dev) ((dev)->pci_device == 0x3577)
1168#define IS_845G(dev) ((dev)->pci_device == 0x2562)
1169#define IS_I85X(dev) ((dev)->pci_device == 0x3582)
1170#define IS_I855(dev) ((dev)->pci_device == 0x3582)
1171#define IS_I865G(dev) ((dev)->pci_device == 0x2572)
1172
1173#define IS_I915G(dev) ((dev)->pci_device == 0x2582 || (dev)->pci_device == 0x258a)
1174#define IS_I915GM(dev) ((dev)->pci_device == 0x2592)
1175#define IS_I945G(dev) ((dev)->pci_device == 0x2772)
1176#define IS_I945GM(dev) ((dev)->pci_device == 0x27A2 ||\
1177 (dev)->pci_device == 0x27AE)
1178#define IS_I965G(dev) ((dev)->pci_device == 0x2972 || \
1179 (dev)->pci_device == 0x2982 || \
1180 (dev)->pci_device == 0x2992 || \
1181 (dev)->pci_device == 0x29A2 || \
1182 (dev)->pci_device == 0x2A02 || \
1183 (dev)->pci_device == 0x2A12 || \
1184 (dev)->pci_device == 0x2A42)
1185
1186#define IS_I965GM(dev) ((dev)->pci_device == 0x2A02)
1187
1188#define IS_IGD_GM(dev) ((dev)->pci_device == 0x2A42)
1189
1190#define IS_G33(dev) ((dev)->pci_device == 0x29C2 || \
1191 (dev)->pci_device == 0x29B2 || \
1192 (dev)->pci_device == 0x29D2)
1193
1194#define IS_I9XX(dev) (IS_I915G(dev) || IS_I915GM(dev) || IS_I945G(dev) || \
1195 IS_I945GM(dev) || IS_I965G(dev) || IS_G33(dev))
1196
1197#define IS_MOBILE(dev) (IS_I830(dev) || IS_I85X(dev) || IS_I915GM(dev) || \
1198 IS_I945GM(dev) || IS_I965GM(dev) || IS_IGD_GM(dev))
1199
1200#define I915_NEED_GFX_HWS(dev) (IS_G33(dev) || IS_IGD_GM(dev))
1201
1202#define PRIMARY_RINGBUFFER_SIZE (128*1024)
1203
1204#endif
diff --git a/drivers/char/drm/i915_ioc32.c b/drivers/char/drm/i915_ioc32.c
deleted file mode 100644
index 1fe68a251b75..000000000000
--- a/drivers/char/drm/i915_ioc32.c
+++ /dev/null
@@ -1,222 +0,0 @@
1/**
2 * \file i915_ioc32.c
3 *
4 * 32-bit ioctl compatibility routines for the i915 DRM.
5 *
6 * \author Alan Hourihane <alanh@fairlite.demon.co.uk>
7 *
8 *
9 * Copyright (C) Paul Mackerras 2005
10 * Copyright (C) Alan Hourihane 2005
11 * All Rights Reserved.
12 *
13 * Permission is hereby granted, free of charge, to any person obtaining a
14 * copy of this software and associated documentation files (the "Software"),
15 * to deal in the Software without restriction, including without limitation
16 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
17 * and/or sell copies of the Software, and to permit persons to whom the
18 * Software is furnished to do so, subject to the following conditions:
19 *
20 * The above copyright notice and this permission notice (including the next
21 * paragraph) shall be included in all copies or substantial portions of the
22 * Software.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
27 * THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
28 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
30 * IN THE SOFTWARE.
31 */
32#include <linux/compat.h>
33
34#include "drmP.h"
35#include "drm.h"
36#include "i915_drm.h"
37
38typedef struct _drm_i915_batchbuffer32 {
39 int start; /* agp offset */
40 int used; /* nr bytes in use */
41 int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */
42 int DR4; /* window origin for GFX_OP_DRAWRECT_INFO */
43 int num_cliprects; /* mulitpass with multiple cliprects? */
44 u32 cliprects; /* pointer to userspace cliprects */
45} drm_i915_batchbuffer32_t;
46
47static int compat_i915_batchbuffer(struct file *file, unsigned int cmd,
48 unsigned long arg)
49{
50 drm_i915_batchbuffer32_t batchbuffer32;
51 drm_i915_batchbuffer_t __user *batchbuffer;
52
53 if (copy_from_user
54 (&batchbuffer32, (void __user *)arg, sizeof(batchbuffer32)))
55 return -EFAULT;
56
57 batchbuffer = compat_alloc_user_space(sizeof(*batchbuffer));
58 if (!access_ok(VERIFY_WRITE, batchbuffer, sizeof(*batchbuffer))
59 || __put_user(batchbuffer32.start, &batchbuffer->start)
60 || __put_user(batchbuffer32.used, &batchbuffer->used)
61 || __put_user(batchbuffer32.DR1, &batchbuffer->DR1)
62 || __put_user(batchbuffer32.DR4, &batchbuffer->DR4)
63 || __put_user(batchbuffer32.num_cliprects,
64 &batchbuffer->num_cliprects)
65 || __put_user((int __user *)(unsigned long)batchbuffer32.cliprects,
66 &batchbuffer->cliprects))
67 return -EFAULT;
68
69 return drm_ioctl(file->f_path.dentry->d_inode, file,
70 DRM_IOCTL_I915_BATCHBUFFER,
71 (unsigned long)batchbuffer);
72}
73
74typedef struct _drm_i915_cmdbuffer32 {
75 u32 buf; /* pointer to userspace command buffer */
76 int sz; /* nr bytes in buf */
77 int DR1; /* hw flags for GFX_OP_DRAWRECT_INFO */
78 int DR4; /* window origin for GFX_OP_DRAWRECT_INFO */
79 int num_cliprects; /* mulitpass with multiple cliprects? */
80 u32 cliprects; /* pointer to userspace cliprects */
81} drm_i915_cmdbuffer32_t;
82
83static int compat_i915_cmdbuffer(struct file *file, unsigned int cmd,
84 unsigned long arg)
85{
86 drm_i915_cmdbuffer32_t cmdbuffer32;
87 drm_i915_cmdbuffer_t __user *cmdbuffer;
88
89 if (copy_from_user
90 (&cmdbuffer32, (void __user *)arg, sizeof(cmdbuffer32)))
91 return -EFAULT;
92
93 cmdbuffer = compat_alloc_user_space(sizeof(*cmdbuffer));
94 if (!access_ok(VERIFY_WRITE, cmdbuffer, sizeof(*cmdbuffer))
95 || __put_user((int __user *)(unsigned long)cmdbuffer32.buf,
96 &cmdbuffer->buf)
97 || __put_user(cmdbuffer32.sz, &cmdbuffer->sz)
98 || __put_user(cmdbuffer32.DR1, &cmdbuffer->DR1)
99 || __put_user(cmdbuffer32.DR4, &cmdbuffer->DR4)
100 || __put_user(cmdbuffer32.num_cliprects, &cmdbuffer->num_cliprects)
101 || __put_user((int __user *)(unsigned long)cmdbuffer32.cliprects,
102 &cmdbuffer->cliprects))
103 return -EFAULT;
104
105 return drm_ioctl(file->f_path.dentry->d_inode, file,
106 DRM_IOCTL_I915_CMDBUFFER, (unsigned long)cmdbuffer);
107}
108
109typedef struct drm_i915_irq_emit32 {
110 u32 irq_seq;
111} drm_i915_irq_emit32_t;
112
113static int compat_i915_irq_emit(struct file *file, unsigned int cmd,
114 unsigned long arg)
115{
116 drm_i915_irq_emit32_t req32;
117 drm_i915_irq_emit_t __user *request;
118
119 if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
120 return -EFAULT;
121
122 request = compat_alloc_user_space(sizeof(*request));
123 if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
124 || __put_user((int __user *)(unsigned long)req32.irq_seq,
125 &request->irq_seq))
126 return -EFAULT;
127
128 return drm_ioctl(file->f_path.dentry->d_inode, file,
129 DRM_IOCTL_I915_IRQ_EMIT, (unsigned long)request);
130}
131typedef struct drm_i915_getparam32 {
132 int param;
133 u32 value;
134} drm_i915_getparam32_t;
135
136static int compat_i915_getparam(struct file *file, unsigned int cmd,
137 unsigned long arg)
138{
139 drm_i915_getparam32_t req32;
140 drm_i915_getparam_t __user *request;
141
142 if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
143 return -EFAULT;
144
145 request = compat_alloc_user_space(sizeof(*request));
146 if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
147 || __put_user(req32.param, &request->param)
148 || __put_user((void __user *)(unsigned long)req32.value,
149 &request->value))
150 return -EFAULT;
151
152 return drm_ioctl(file->f_path.dentry->d_inode, file,
153 DRM_IOCTL_I915_GETPARAM, (unsigned long)request);
154}
155
156typedef struct drm_i915_mem_alloc32 {
157 int region;
158 int alignment;
159 int size;
160 u32 region_offset; /* offset from start of fb or agp */
161} drm_i915_mem_alloc32_t;
162
163static int compat_i915_alloc(struct file *file, unsigned int cmd,
164 unsigned long arg)
165{
166 drm_i915_mem_alloc32_t req32;
167 drm_i915_mem_alloc_t __user *request;
168
169 if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
170 return -EFAULT;
171
172 request = compat_alloc_user_space(sizeof(*request));
173 if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
174 || __put_user(req32.region, &request->region)
175 || __put_user(req32.alignment, &request->alignment)
176 || __put_user(req32.size, &request->size)
177 || __put_user((void __user *)(unsigned long)req32.region_offset,
178 &request->region_offset))
179 return -EFAULT;
180
181 return drm_ioctl(file->f_path.dentry->d_inode, file,
182 DRM_IOCTL_I915_ALLOC, (unsigned long)request);
183}
184
185drm_ioctl_compat_t *i915_compat_ioctls[] = {
186 [DRM_I915_BATCHBUFFER] = compat_i915_batchbuffer,
187 [DRM_I915_CMDBUFFER] = compat_i915_cmdbuffer,
188 [DRM_I915_GETPARAM] = compat_i915_getparam,
189 [DRM_I915_IRQ_EMIT] = compat_i915_irq_emit,
190 [DRM_I915_ALLOC] = compat_i915_alloc
191};
192
193/**
194 * Called whenever a 32-bit process running under a 64-bit kernel
195 * performs an ioctl on /dev/dri/card<n>.
196 *
197 * \param filp file pointer.
198 * \param cmd command.
199 * \param arg user argument.
200 * \return zero on success or negative number on failure.
201 */
202long i915_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
203{
204 unsigned int nr = DRM_IOCTL_NR(cmd);
205 drm_ioctl_compat_t *fn = NULL;
206 int ret;
207
208 if (nr < DRM_COMMAND_BASE)
209 return drm_compat_ioctl(filp, cmd, arg);
210
211 if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(i915_compat_ioctls))
212 fn = i915_compat_ioctls[nr - DRM_COMMAND_BASE];
213
214 lock_kernel(); /* XXX for now */
215 if (fn != NULL)
216 ret = (*fn) (filp, cmd, arg);
217 else
218 ret = drm_ioctl(filp->f_path.dentry->d_inode, filp, cmd, arg);
219 unlock_kernel();
220
221 return ret;
222}
diff --git a/drivers/char/drm/i915_irq.c b/drivers/char/drm/i915_irq.c
deleted file mode 100644
index 023ce66ef3ab..000000000000
--- a/drivers/char/drm/i915_irq.c
+++ /dev/null
@@ -1,916 +0,0 @@
1/* i915_irq.c -- IRQ support for the I915 -*- linux-c -*-
2 */
3/*
4 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
5 * All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the
9 * "Software"), to deal in the Software without restriction, including
10 * without limitation the rights to use, copy, modify, merge, publish,
11 * distribute, sub license, and/or sell copies of the Software, and to
12 * permit persons to whom the Software is furnished to do so, subject to
13 * the following conditions:
14 *
15 * The above copyright notice and this permission notice (including the
16 * next paragraph) shall be included in all copies or substantial portions
17 * of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
23 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 *
27 */
28
29#include "drmP.h"
30#include "drm.h"
31#include "i915_drm.h"
32#include "i915_drv.h"
33
34#define USER_INT_FLAG (1<<1)
35#define VSYNC_PIPEB_FLAG (1<<5)
36#define VSYNC_PIPEA_FLAG (1<<7)
37
38#define MAX_NOPID ((u32)~0)
39
40/**
41 * i915_get_pipe - return the the pipe associated with a given plane
42 * @dev: DRM device
43 * @plane: plane to look for
44 *
45 * The Intel Mesa & 2D drivers call the vblank routines with a plane number
46 * rather than a pipe number, since they may not always be equal. This routine
47 * maps the given @plane back to a pipe number.
48 */
49static int
50i915_get_pipe(struct drm_device *dev, int plane)
51{
52 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
53 u32 dspcntr;
54
55 dspcntr = plane ? I915_READ(DSPBCNTR) : I915_READ(DSPACNTR);
56
57 return dspcntr & DISPPLANE_SEL_PIPE_MASK ? 1 : 0;
58}
59
60/**
61 * i915_get_plane - return the the plane associated with a given pipe
62 * @dev: DRM device
63 * @pipe: pipe to look for
64 *
65 * The Intel Mesa & 2D drivers call the vblank routines with a plane number
66 * rather than a plane number, since they may not always be equal. This routine
67 * maps the given @pipe back to a plane number.
68 */
69static int
70i915_get_plane(struct drm_device *dev, int pipe)
71{
72 if (i915_get_pipe(dev, 0) == pipe)
73 return 0;
74 return 1;
75}
76
77/**
78 * i915_pipe_enabled - check if a pipe is enabled
79 * @dev: DRM device
80 * @pipe: pipe to check
81 *
82 * Reading certain registers when the pipe is disabled can hang the chip.
83 * Use this routine to make sure the PLL is running and the pipe is active
84 * before reading such registers if unsure.
85 */
86static int
87i915_pipe_enabled(struct drm_device *dev, int pipe)
88{
89 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
90 unsigned long pipeconf = pipe ? PIPEBCONF : PIPEACONF;
91
92 if (I915_READ(pipeconf) & PIPEACONF_ENABLE)
93 return 1;
94
95 return 0;
96}
97
98/**
99 * Emit a synchronous flip.
100 *
101 * This function must be called with the drawable spinlock held.
102 */
103static void
104i915_dispatch_vsync_flip(struct drm_device *dev, struct drm_drawable_info *drw,
105 int plane)
106{
107 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
108 drm_i915_sarea_t *sarea_priv = dev_priv->sarea_priv;
109 u16 x1, y1, x2, y2;
110 int pf_planes = 1 << plane;
111
112 /* If the window is visible on the other plane, we have to flip on that
113 * plane as well.
114 */
115 if (plane == 1) {
116 x1 = sarea_priv->planeA_x;
117 y1 = sarea_priv->planeA_y;
118 x2 = x1 + sarea_priv->planeA_w;
119 y2 = y1 + sarea_priv->planeA_h;
120 } else {
121 x1 = sarea_priv->planeB_x;
122 y1 = sarea_priv->planeB_y;
123 x2 = x1 + sarea_priv->planeB_w;
124 y2 = y1 + sarea_priv->planeB_h;
125 }
126
127 if (x2 > 0 && y2 > 0) {
128 int i, num_rects = drw->num_rects;
129 struct drm_clip_rect *rect = drw->rects;
130
131 for (i = 0; i < num_rects; i++)
132 if (!(rect[i].x1 >= x2 || rect[i].y1 >= y2 ||
133 rect[i].x2 <= x1 || rect[i].y2 <= y1)) {
134 pf_planes = 0x3;
135
136 break;
137 }
138 }
139
140 i915_dispatch_flip(dev, pf_planes, 1);
141}
142
143/**
144 * Emit blits for scheduled buffer swaps.
145 *
146 * This function will be called with the HW lock held.
147 */
148static void i915_vblank_tasklet(struct drm_device *dev)
149{
150 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
151 struct list_head *list, *tmp, hits, *hit;
152 int nhits, nrects, slice[2], upper[2], lower[2], i, num_pages;
153 unsigned counter[2];
154 struct drm_drawable_info *drw;
155 drm_i915_sarea_t *sarea_priv = dev_priv->sarea_priv;
156 u32 cpp = dev_priv->cpp, offsets[3];
157 u32 cmd = (cpp == 4) ? (XY_SRC_COPY_BLT_CMD |
158 XY_SRC_COPY_BLT_WRITE_ALPHA |
159 XY_SRC_COPY_BLT_WRITE_RGB)
160 : XY_SRC_COPY_BLT_CMD;
161 u32 src_pitch = sarea_priv->pitch * cpp;
162 u32 dst_pitch = sarea_priv->pitch * cpp;
163 /* COPY rop (0xcc), map cpp to magic color depth constants */
164 u32 ropcpp = (0xcc << 16) | ((cpp - 1) << 24);
165 RING_LOCALS;
166
167 if (sarea_priv->front_tiled) {
168 cmd |= XY_SRC_COPY_BLT_DST_TILED;
169 dst_pitch >>= 2;
170 }
171 if (sarea_priv->back_tiled) {
172 cmd |= XY_SRC_COPY_BLT_SRC_TILED;
173 src_pitch >>= 2;
174 }
175
176 counter[0] = drm_vblank_count(dev, 0);
177 counter[1] = drm_vblank_count(dev, 1);
178
179 DRM_DEBUG("\n");
180
181 INIT_LIST_HEAD(&hits);
182
183 nhits = nrects = 0;
184
185 /* No irqsave/restore necessary. This tasklet may be run in an
186 * interrupt context or normal context, but we don't have to worry
187 * about getting interrupted by something acquiring the lock, because
188 * we are the interrupt context thing that acquires the lock.
189 */
190 spin_lock(&dev_priv->swaps_lock);
191
192 /* Find buffer swaps scheduled for this vertical blank */
193 list_for_each_safe(list, tmp, &dev_priv->vbl_swaps.head) {
194 drm_i915_vbl_swap_t *vbl_swap =
195 list_entry(list, drm_i915_vbl_swap_t, head);
196 int pipe = i915_get_pipe(dev, vbl_swap->plane);
197
198 if ((counter[pipe] - vbl_swap->sequence) > (1<<23))
199 continue;
200
201 list_del(list);
202 dev_priv->swaps_pending--;
203 drm_vblank_put(dev, pipe);
204
205 spin_unlock(&dev_priv->swaps_lock);
206 spin_lock(&dev->drw_lock);
207
208 drw = drm_get_drawable_info(dev, vbl_swap->drw_id);
209
210 if (!drw) {
211 spin_unlock(&dev->drw_lock);
212 drm_free(vbl_swap, sizeof(*vbl_swap), DRM_MEM_DRIVER);
213 spin_lock(&dev_priv->swaps_lock);
214 continue;
215 }
216
217 list_for_each(hit, &hits) {
218 drm_i915_vbl_swap_t *swap_cmp =
219 list_entry(hit, drm_i915_vbl_swap_t, head);
220 struct drm_drawable_info *drw_cmp =
221 drm_get_drawable_info(dev, swap_cmp->drw_id);
222
223 if (drw_cmp &&
224 drw_cmp->rects[0].y1 > drw->rects[0].y1) {
225 list_add_tail(list, hit);
226 break;
227 }
228 }
229
230 spin_unlock(&dev->drw_lock);
231
232 /* List of hits was empty, or we reached the end of it */
233 if (hit == &hits)
234 list_add_tail(list, hits.prev);
235
236 nhits++;
237
238 spin_lock(&dev_priv->swaps_lock);
239 }
240
241 spin_unlock(&dev_priv->swaps_lock);
242
243 if (nhits == 0)
244 return;
245
246 i915_kernel_lost_context(dev);
247
248 upper[0] = upper[1] = 0;
249 slice[0] = max(sarea_priv->planeA_h / nhits, 1);
250 slice[1] = max(sarea_priv->planeB_h / nhits, 1);
251 lower[0] = sarea_priv->planeA_y + slice[0];
252 lower[1] = sarea_priv->planeB_y + slice[0];
253
254 offsets[0] = sarea_priv->front_offset;
255 offsets[1] = sarea_priv->back_offset;
256 offsets[2] = sarea_priv->third_offset;
257 num_pages = sarea_priv->third_handle ? 3 : 2;
258
259 spin_lock(&dev->drw_lock);
260
261 /* Emit blits for buffer swaps, partitioning both outputs into as many
262 * slices as there are buffer swaps scheduled in order to avoid tearing
263 * (based on the assumption that a single buffer swap would always
264 * complete before scanout starts).
265 */
266 for (i = 0; i++ < nhits;
267 upper[0] = lower[0], lower[0] += slice[0],
268 upper[1] = lower[1], lower[1] += slice[1]) {
269 int init_drawrect = 1;
270
271 if (i == nhits)
272 lower[0] = lower[1] = sarea_priv->height;
273
274 list_for_each(hit, &hits) {
275 drm_i915_vbl_swap_t *swap_hit =
276 list_entry(hit, drm_i915_vbl_swap_t, head);
277 struct drm_clip_rect *rect;
278 int num_rects, plane, front, back;
279 unsigned short top, bottom;
280
281 drw = drm_get_drawable_info(dev, swap_hit->drw_id);
282
283 if (!drw)
284 continue;
285
286 plane = swap_hit->plane;
287
288 if (swap_hit->flip) {
289 i915_dispatch_vsync_flip(dev, drw, plane);
290 continue;
291 }
292
293 if (init_drawrect) {
294 int width = sarea_priv->width;
295 int height = sarea_priv->height;
296 if (IS_I965G(dev)) {
297 BEGIN_LP_RING(4);
298
299 OUT_RING(GFX_OP_DRAWRECT_INFO_I965);
300 OUT_RING(0);
301 OUT_RING(((width - 1) & 0xffff) | ((height - 1) << 16));
302 OUT_RING(0);
303
304 ADVANCE_LP_RING();
305 } else {
306 BEGIN_LP_RING(6);
307
308 OUT_RING(GFX_OP_DRAWRECT_INFO);
309 OUT_RING(0);
310 OUT_RING(0);
311 OUT_RING(((width - 1) & 0xffff) | ((height - 1) << 16));
312 OUT_RING(0);
313 OUT_RING(0);
314
315 ADVANCE_LP_RING();
316 }
317
318 sarea_priv->ctxOwner = DRM_KERNEL_CONTEXT;
319
320 init_drawrect = 0;
321 }
322
323 rect = drw->rects;
324 top = upper[plane];
325 bottom = lower[plane];
326
327 front = (dev_priv->sarea_priv->pf_current_page >>
328 (2 * plane)) & 0x3;
329 back = (front + 1) % num_pages;
330
331 for (num_rects = drw->num_rects; num_rects--; rect++) {
332 int y1 = max(rect->y1, top);
333 int y2 = min(rect->y2, bottom);
334
335 if (y1 >= y2)
336 continue;
337
338 BEGIN_LP_RING(8);
339
340 OUT_RING(cmd);
341 OUT_RING(ropcpp | dst_pitch);
342 OUT_RING((y1 << 16) | rect->x1);
343 OUT_RING((y2 << 16) | rect->x2);
344 OUT_RING(offsets[front]);
345 OUT_RING((y1 << 16) | rect->x1);
346 OUT_RING(src_pitch);
347 OUT_RING(offsets[back]);
348
349 ADVANCE_LP_RING();
350 }
351 }
352 }
353
354 spin_unlock(&dev->drw_lock);
355
356 list_for_each_safe(hit, tmp, &hits) {
357 drm_i915_vbl_swap_t *swap_hit =
358 list_entry(hit, drm_i915_vbl_swap_t, head);
359
360 list_del(hit);
361
362 drm_free(swap_hit, sizeof(*swap_hit), DRM_MEM_DRIVER);
363 }
364}
365
366u32 i915_get_vblank_counter(struct drm_device *dev, int plane)
367{
368 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
369 unsigned long high_frame;
370 unsigned long low_frame;
371 u32 high1, high2, low, count;
372 int pipe;
373
374 pipe = i915_get_pipe(dev, plane);
375 high_frame = pipe ? PIPEBFRAMEHIGH : PIPEAFRAMEHIGH;
376 low_frame = pipe ? PIPEBFRAMEPIXEL : PIPEAFRAMEPIXEL;
377
378 if (!i915_pipe_enabled(dev, pipe)) {
379 printk(KERN_ERR "trying to get vblank count for disabled "
380 "pipe %d\n", pipe);
381 return 0;
382 }
383
384 /*
385 * High & low register fields aren't synchronized, so make sure
386 * we get a low value that's stable across two reads of the high
387 * register.
388 */
389 do {
390 high1 = ((I915_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >>
391 PIPE_FRAME_HIGH_SHIFT);
392 low = ((I915_READ(low_frame) & PIPE_FRAME_LOW_MASK) >>
393 PIPE_FRAME_LOW_SHIFT);
394 high2 = ((I915_READ(high_frame) & PIPE_FRAME_HIGH_MASK) >>
395 PIPE_FRAME_HIGH_SHIFT);
396 } while (high1 != high2);
397
398 count = (high1 << 8) | low;
399
400 /* count may be reset by other driver(e.g. 2D driver),
401 we have no way to know if it is wrapped or resetted
402 when count is zero. do a rough guess.
403 */
404 if (count == 0 && dev->last_vblank[pipe] < dev->max_vblank_count/2)
405 dev->last_vblank[pipe] = 0;
406
407 return count;
408}
409
410irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
411{
412 struct drm_device *dev = (struct drm_device *) arg;
413 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
414 u32 iir;
415 u32 pipea_stats, pipeb_stats;
416 int vblank = 0;
417
418 iir = I915_READ(I915REG_INT_IDENTITY_R);
419 if (iir == 0) {
420 DRM_DEBUG ("iir 0x%08x im 0x%08x ie 0x%08x pipea 0x%08x pipeb 0x%08x\n",
421 iir,
422 I915_READ(I915REG_INT_MASK_R),
423 I915_READ(I915REG_INT_ENABLE_R),
424 I915_READ(I915REG_PIPEASTAT),
425 I915_READ(I915REG_PIPEBSTAT));
426 return IRQ_NONE;
427 }
428
429 /*
430 * Clear the PIPE(A|B)STAT regs before the IIR otherwise
431 * we may get extra interrupts.
432 */
433 if (iir & I915_DISPLAY_PIPE_A_EVENT_INTERRUPT) {
434 pipea_stats = I915_READ(I915REG_PIPEASTAT);
435 if (pipea_stats & (I915_START_VBLANK_INTERRUPT_STATUS|
436 I915_VBLANK_INTERRUPT_STATUS))
437 {
438 vblank++;
439 drm_handle_vblank(dev, i915_get_plane(dev, 0));
440 }
441 I915_WRITE(I915REG_PIPEASTAT, pipea_stats);
442 }
443 if (iir & I915_DISPLAY_PIPE_B_EVENT_INTERRUPT) {
444 pipeb_stats = I915_READ(I915REG_PIPEBSTAT);
445 if (pipeb_stats & (I915_START_VBLANK_INTERRUPT_STATUS|
446 I915_VBLANK_INTERRUPT_STATUS))
447 {
448 vblank++;
449 drm_handle_vblank(dev, i915_get_plane(dev, 1));
450 }
451 I915_WRITE(I915REG_PIPEBSTAT, pipeb_stats);
452 }
453
454 if (dev_priv->sarea_priv)
455 dev_priv->sarea_priv->last_dispatch = READ_BREADCRUMB(dev_priv);
456
457 I915_WRITE(I915REG_INT_IDENTITY_R, iir);
458 (void) I915_READ(I915REG_INT_IDENTITY_R); /* Flush posted write */
459
460 if (iir & I915_USER_INTERRUPT) {
461 DRM_WAKEUP(&dev_priv->irq_queue);
462 }
463 if (vblank) {
464 if (dev_priv->swaps_pending > 0)
465 drm_locked_tasklet(dev, i915_vblank_tasklet);
466 }
467
468 return IRQ_HANDLED;
469}
470
471static int i915_emit_irq(struct drm_device *dev)
472{
473 drm_i915_private_t *dev_priv = dev->dev_private;
474 RING_LOCALS;
475
476 i915_kernel_lost_context(dev);
477
478 DRM_DEBUG("\n");
479
480 dev_priv->sarea_priv->last_enqueue = ++dev_priv->counter;
481
482 if (dev_priv->counter > 0x7FFFFFFFUL)
483 dev_priv->sarea_priv->last_enqueue = dev_priv->counter = 1;
484
485 BEGIN_LP_RING(6);
486 OUT_RING(CMD_STORE_DWORD_IDX);
487 OUT_RING(20);
488 OUT_RING(dev_priv->counter);
489 OUT_RING(0);
490 OUT_RING(0);
491 OUT_RING(GFX_OP_USER_INTERRUPT);
492 ADVANCE_LP_RING();
493
494 return dev_priv->counter;
495}
496
497static int i915_wait_irq(struct drm_device * dev, int irq_nr)
498{
499 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
500 int ret = 0;
501
502 DRM_DEBUG("irq_nr=%d breadcrumb=%d\n", irq_nr,
503 READ_BREADCRUMB(dev_priv));
504
505 if (READ_BREADCRUMB(dev_priv) >= irq_nr)
506 return 0;
507
508 dev_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT;
509
510 DRM_WAIT_ON(ret, dev_priv->irq_queue, 3 * DRM_HZ,
511 READ_BREADCRUMB(dev_priv) >= irq_nr);
512
513 if (ret == -EBUSY) {
514 DRM_ERROR("EBUSY -- rec: %d emitted: %d\n",
515 READ_BREADCRUMB(dev_priv), (int)dev_priv->counter);
516 }
517
518 if (dev_priv->sarea_priv)
519 dev_priv->sarea_priv->last_dispatch =
520 READ_BREADCRUMB(dev_priv);
521 return ret;
522}
523
524/* Needs the lock as it touches the ring.
525 */
526int i915_irq_emit(struct drm_device *dev, void *data,
527 struct drm_file *file_priv)
528{
529 drm_i915_private_t *dev_priv = dev->dev_private;
530 drm_i915_irq_emit_t *emit = data;
531 int result;
532
533 LOCK_TEST_WITH_RETURN(dev, file_priv);
534
535 if (!dev_priv) {
536 DRM_ERROR("called with no initialization\n");
537 return -EINVAL;
538 }
539
540 result = i915_emit_irq(dev);
541
542 if (DRM_COPY_TO_USER(emit->irq_seq, &result, sizeof(int))) {
543 DRM_ERROR("copy_to_user\n");
544 return -EFAULT;
545 }
546
547 return 0;
548}
549
550/* Doesn't need the hardware lock.
551 */
552int i915_irq_wait(struct drm_device *dev, void *data,
553 struct drm_file *file_priv)
554{
555 drm_i915_private_t *dev_priv = dev->dev_private;
556 drm_i915_irq_wait_t *irqwait = data;
557
558 if (!dev_priv) {
559 DRM_ERROR("called with no initialization\n");
560 return -EINVAL;
561 }
562
563 return i915_wait_irq(dev, irqwait->irq_seq);
564}
565
566int i915_enable_vblank(struct drm_device *dev, int plane)
567{
568 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
569 int pipe = i915_get_pipe(dev, plane);
570 u32 pipestat_reg = 0;
571 u32 pipestat;
572
573 switch (pipe) {
574 case 0:
575 pipestat_reg = I915REG_PIPEASTAT;
576 dev_priv->irq_enable_reg |= I915_DISPLAY_PIPE_A_EVENT_INTERRUPT;
577 break;
578 case 1:
579 pipestat_reg = I915REG_PIPEBSTAT;
580 dev_priv->irq_enable_reg |= I915_DISPLAY_PIPE_B_EVENT_INTERRUPT;
581 break;
582 default:
583 DRM_ERROR("tried to enable vblank on non-existent pipe %d\n",
584 pipe);
585 break;
586 }
587
588 if (pipestat_reg)
589 {
590 pipestat = I915_READ (pipestat_reg);
591 /*
592 * Older chips didn't have the start vblank interrupt,
593 * but
594 */
595 if (IS_I965G (dev))
596 pipestat |= I915_START_VBLANK_INTERRUPT_ENABLE;
597 else
598 pipestat |= I915_VBLANK_INTERRUPT_ENABLE;
599 /*
600 * Clear any pending status
601 */
602 pipestat |= (I915_START_VBLANK_INTERRUPT_STATUS |
603 I915_VBLANK_INTERRUPT_STATUS);
604 I915_WRITE(pipestat_reg, pipestat);
605 }
606 I915_WRITE(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg);
607
608 return 0;
609}
610
611void i915_disable_vblank(struct drm_device *dev, int plane)
612{
613 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
614 int pipe = i915_get_pipe(dev, plane);
615 u32 pipestat_reg = 0;
616 u32 pipestat;
617
618 switch (pipe) {
619 case 0:
620 pipestat_reg = I915REG_PIPEASTAT;
621 dev_priv->irq_enable_reg &= ~I915_DISPLAY_PIPE_A_EVENT_INTERRUPT;
622 break;
623 case 1:
624 pipestat_reg = I915REG_PIPEBSTAT;
625 dev_priv->irq_enable_reg &= ~I915_DISPLAY_PIPE_B_EVENT_INTERRUPT;
626 break;
627 default:
628 DRM_ERROR("tried to disable vblank on non-existent pipe %d\n",
629 pipe);
630 break;
631 }
632
633 I915_WRITE(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg);
634 if (pipestat_reg)
635 {
636 pipestat = I915_READ (pipestat_reg);
637 pipestat &= ~(I915_START_VBLANK_INTERRUPT_ENABLE |
638 I915_VBLANK_INTERRUPT_ENABLE);
639 /*
640 * Clear any pending status
641 */
642 pipestat |= (I915_START_VBLANK_INTERRUPT_STATUS |
643 I915_VBLANK_INTERRUPT_STATUS);
644 I915_WRITE(pipestat_reg, pipestat);
645 }
646}
647
648static void i915_enable_interrupt (struct drm_device *dev)
649{
650 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
651
652 dev_priv->irq_enable_reg |= I915_USER_INTERRUPT;
653
654 I915_WRITE(I915REG_INT_ENABLE_R, dev_priv->irq_enable_reg);
655 dev_priv->irq_enabled = 1;
656}
657
658/* Set the vblank monitor pipe
659 */
660int i915_vblank_pipe_set(struct drm_device *dev, void *data,
661 struct drm_file *file_priv)
662{
663 drm_i915_private_t *dev_priv = dev->dev_private;
664 drm_i915_vblank_pipe_t *pipe = data;
665
666 if (!dev_priv) {
667 DRM_ERROR("called with no initialization\n");
668 return -EINVAL;
669 }
670
671 if (pipe->pipe & ~(DRM_I915_VBLANK_PIPE_A|DRM_I915_VBLANK_PIPE_B)) {
672 DRM_ERROR("called with invalid pipe 0x%x\n", pipe->pipe);
673 return -EINVAL;
674 }
675
676 dev_priv->vblank_pipe = pipe->pipe;
677
678 return 0;
679}
680
681int i915_vblank_pipe_get(struct drm_device *dev, void *data,
682 struct drm_file *file_priv)
683{
684 drm_i915_private_t *dev_priv = dev->dev_private;
685 drm_i915_vblank_pipe_t *pipe = data;
686 u16 flag;
687
688 if (!dev_priv) {
689 DRM_ERROR("called with no initialization\n");
690 return -EINVAL;
691 }
692
693 flag = I915_READ(I915REG_INT_ENABLE_R);
694 pipe->pipe = 0;
695 if (flag & I915_DISPLAY_PIPE_A_EVENT_INTERRUPT)
696 pipe->pipe |= DRM_I915_VBLANK_PIPE_A;
697 if (flag & I915_DISPLAY_PIPE_B_EVENT_INTERRUPT)
698 pipe->pipe |= DRM_I915_VBLANK_PIPE_B;
699
700 return 0;
701}
702
703/**
704 * Schedule buffer swap at given vertical blank.
705 */
706int i915_vblank_swap(struct drm_device *dev, void *data,
707 struct drm_file *file_priv)
708{
709 drm_i915_private_t *dev_priv = dev->dev_private;
710 drm_i915_vblank_swap_t *swap = data;
711 drm_i915_vbl_swap_t *vbl_swap;
712 unsigned int pipe, seqtype, curseq, plane;
713 unsigned long irqflags;
714 struct list_head *list;
715 int ret;
716
717 if (!dev_priv) {
718 DRM_ERROR("%s called with no initialization\n", __func__);
719 return -EINVAL;
720 }
721
722 if (!dev_priv->sarea_priv || dev_priv->sarea_priv->rotation) {
723 DRM_DEBUG("Rotation not supported\n");
724 return -EINVAL;
725 }
726
727 if (swap->seqtype & ~(_DRM_VBLANK_RELATIVE | _DRM_VBLANK_ABSOLUTE |
728 _DRM_VBLANK_SECONDARY | _DRM_VBLANK_NEXTONMISS |
729 _DRM_VBLANK_FLIP)) {
730 DRM_ERROR("Invalid sequence type 0x%x\n", swap->seqtype);
731 return -EINVAL;
732 }
733
734 plane = (swap->seqtype & _DRM_VBLANK_SECONDARY) ? 1 : 0;
735 pipe = i915_get_pipe(dev, plane);
736
737 seqtype = swap->seqtype & (_DRM_VBLANK_RELATIVE | _DRM_VBLANK_ABSOLUTE);
738
739 if (!(dev_priv->vblank_pipe & (1 << pipe))) {
740 DRM_ERROR("Invalid pipe %d\n", pipe);
741 return -EINVAL;
742 }
743
744 spin_lock_irqsave(&dev->drw_lock, irqflags);
745
746 /* It makes no sense to schedule a swap for a drawable that doesn't have
747 * valid information at this point. E.g. this could mean that the X
748 * server is too old to push drawable information to the DRM, in which
749 * case all such swaps would become ineffective.
750 */
751 if (!drm_get_drawable_info(dev, swap->drawable)) {
752 spin_unlock_irqrestore(&dev->drw_lock, irqflags);
753 DRM_DEBUG("Invalid drawable ID %d\n", swap->drawable);
754 return -EINVAL;
755 }
756
757 spin_unlock_irqrestore(&dev->drw_lock, irqflags);
758
759 drm_update_vblank_count(dev, pipe);
760 curseq = drm_vblank_count(dev, pipe);
761
762 if (seqtype == _DRM_VBLANK_RELATIVE)
763 swap->sequence += curseq;
764
765 if ((curseq - swap->sequence) <= (1<<23)) {
766 if (swap->seqtype & _DRM_VBLANK_NEXTONMISS) {
767 swap->sequence = curseq + 1;
768 } else {
769 DRM_DEBUG("Missed target sequence\n");
770 return -EINVAL;
771 }
772 }
773
774 if (swap->seqtype & _DRM_VBLANK_FLIP) {
775 swap->sequence--;
776
777 if ((curseq - swap->sequence) <= (1<<23)) {
778 struct drm_drawable_info *drw;
779
780 LOCK_TEST_WITH_RETURN(dev, file_priv);
781
782 spin_lock_irqsave(&dev->drw_lock, irqflags);
783
784 drw = drm_get_drawable_info(dev, swap->drawable);
785
786 if (!drw) {
787 spin_unlock_irqrestore(&dev->drw_lock,
788 irqflags);
789 DRM_DEBUG("Invalid drawable ID %d\n",
790 swap->drawable);
791 return -EINVAL;
792 }
793
794 i915_dispatch_vsync_flip(dev, drw, plane);
795
796 spin_unlock_irqrestore(&dev->drw_lock, irqflags);
797
798 return 0;
799 }
800 }
801
802 spin_lock_irqsave(&dev_priv->swaps_lock, irqflags);
803
804 list_for_each(list, &dev_priv->vbl_swaps.head) {
805 vbl_swap = list_entry(list, drm_i915_vbl_swap_t, head);
806
807 if (vbl_swap->drw_id == swap->drawable &&
808 vbl_swap->plane == plane &&
809 vbl_swap->sequence == swap->sequence) {
810 vbl_swap->flip = (swap->seqtype & _DRM_VBLANK_FLIP);
811 spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags);
812 DRM_DEBUG("Already scheduled\n");
813 return 0;
814 }
815 }
816
817 spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags);
818
819 if (dev_priv->swaps_pending >= 100) {
820 DRM_DEBUG("Too many swaps queued\n");
821 return -EBUSY;
822 }
823
824 vbl_swap = drm_calloc(1, sizeof(*vbl_swap), DRM_MEM_DRIVER);
825
826 if (!vbl_swap) {
827 DRM_ERROR("Failed to allocate memory to queue swap\n");
828 return -ENOMEM;
829 }
830
831 DRM_DEBUG("\n");
832
833 ret = drm_vblank_get(dev, pipe);
834 if (ret) {
835 drm_free(vbl_swap, sizeof(*vbl_swap), DRM_MEM_DRIVER);
836 return ret;
837 }
838
839 vbl_swap->drw_id = swap->drawable;
840 vbl_swap->plane = plane;
841 vbl_swap->sequence = swap->sequence;
842 vbl_swap->flip = (swap->seqtype & _DRM_VBLANK_FLIP);
843
844 if (vbl_swap->flip)
845 swap->sequence++;
846
847 spin_lock_irqsave(&dev_priv->swaps_lock, irqflags);
848
849 list_add_tail(&vbl_swap->head, &dev_priv->vbl_swaps.head);
850 dev_priv->swaps_pending++;
851
852 spin_unlock_irqrestore(&dev_priv->swaps_lock, irqflags);
853
854 return 0;
855}
856
857/* drm_dma.h hooks
858*/
859void i915_driver_irq_preinstall(struct drm_device * dev)
860{
861 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
862
863 I915_WRITE16(I915REG_HWSTAM, 0xeffe);
864 I915_WRITE16(I915REG_INT_MASK_R, 0x0);
865 I915_WRITE16(I915REG_INT_ENABLE_R, 0x0);
866}
867
868int i915_driver_irq_postinstall(struct drm_device * dev)
869{
870 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
871 int ret, num_pipes = 2;
872
873 spin_lock_init(&dev_priv->swaps_lock);
874 INIT_LIST_HEAD(&dev_priv->vbl_swaps.head);
875 dev_priv->swaps_pending = 0;
876
877 dev_priv->user_irq_refcount = 0;
878 dev_priv->irq_enable_reg = 0;
879
880 ret = drm_vblank_init(dev, num_pipes);
881 if (ret)
882 return ret;
883
884 dev->max_vblank_count = 0xffffff; /* only 24 bits of frame count */
885
886 i915_enable_interrupt(dev);
887 DRM_INIT_WAITQUEUE(&dev_priv->irq_queue);
888
889 /*
890 * Initialize the hardware status page IRQ location.
891 */
892
893 I915_WRITE(I915REG_INSTPM, (1 << 5) | (1 << 21));
894 return 0;
895}
896
897void i915_driver_irq_uninstall(struct drm_device * dev)
898{
899 drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
900 u32 temp;
901
902 if (!dev_priv)
903 return;
904
905 dev_priv->irq_enabled = 0;
906 I915_WRITE(I915REG_HWSTAM, 0xffffffff);
907 I915_WRITE(I915REG_INT_MASK_R, 0xffffffff);
908 I915_WRITE(I915REG_INT_ENABLE_R, 0x0);
909
910 temp = I915_READ(I915REG_PIPEASTAT);
911 I915_WRITE(I915REG_PIPEASTAT, temp);
912 temp = I915_READ(I915REG_PIPEBSTAT);
913 I915_WRITE(I915REG_PIPEBSTAT, temp);
914 temp = I915_READ(I915REG_INT_IDENTITY_R);
915 I915_WRITE(I915REG_INT_IDENTITY_R, temp);
916}
diff --git a/drivers/char/drm/i915_mem.c b/drivers/char/drm/i915_mem.c
deleted file mode 100644
index 6126a60dc9cb..000000000000
--- a/drivers/char/drm/i915_mem.c
+++ /dev/null
@@ -1,386 +0,0 @@
1/* i915_mem.c -- Simple agp/fb memory manager for i915 -*- linux-c -*-
2 */
3/*
4 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
5 * All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the
9 * "Software"), to deal in the Software without restriction, including
10 * without limitation the rights to use, copy, modify, merge, publish,
11 * distribute, sub license, and/or sell copies of the Software, and to
12 * permit persons to whom the Software is furnished to do so, subject to
13 * the following conditions:
14 *
15 * The above copyright notice and this permission notice (including the
16 * next paragraph) shall be included in all copies or substantial portions
17 * of the Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
23 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 *
27 */
28
29#include "drmP.h"
30#include "drm.h"
31#include "i915_drm.h"
32#include "i915_drv.h"
33
34/* This memory manager is integrated into the global/local lru
35 * mechanisms used by the clients. Specifically, it operates by
36 * setting the 'in_use' fields of the global LRU to indicate whether
37 * this region is privately allocated to a client.
38 *
39 * This does require the client to actually respect that field.
40 *
41 * Currently no effort is made to allocate 'private' memory in any
42 * clever way - the LRU information isn't used to determine which
43 * block to allocate, and the ring is drained prior to allocations --
44 * in other words allocation is expensive.
45 */
46static void mark_block(struct drm_device * dev, struct mem_block *p, int in_use)
47{
48 drm_i915_private_t *dev_priv = dev->dev_private;
49 drm_i915_sarea_t *sarea_priv = dev_priv->sarea_priv;
50 struct drm_tex_region *list;
51 unsigned shift, nr;
52 unsigned start;
53 unsigned end;
54 unsigned i;
55 int age;
56
57 shift = dev_priv->tex_lru_log_granularity;
58 nr = I915_NR_TEX_REGIONS;
59
60 start = p->start >> shift;
61 end = (p->start + p->size - 1) >> shift;
62
63 age = ++sarea_priv->texAge;
64 list = sarea_priv->texList;
65
66 /* Mark the regions with the new flag and update their age. Move
67 * them to head of list to preserve LRU semantics.
68 */
69 for (i = start; i <= end; i++) {
70 list[i].in_use = in_use;
71 list[i].age = age;
72
73 /* remove_from_list(i)
74 */
75 list[(unsigned)list[i].next].prev = list[i].prev;
76 list[(unsigned)list[i].prev].next = list[i].next;
77
78 /* insert_at_head(list, i)
79 */
80 list[i].prev = nr;
81 list[i].next = list[nr].next;
82 list[(unsigned)list[nr].next].prev = i;
83 list[nr].next = i;
84 }
85}
86
87/* Very simple allocator for agp memory, working on a static range
88 * already mapped into each client's address space.
89 */
90
91static struct mem_block *split_block(struct mem_block *p, int start, int size,
92 struct drm_file *file_priv)
93{
94 /* Maybe cut off the start of an existing block */
95 if (start > p->start) {
96 struct mem_block *newblock =
97 drm_alloc(sizeof(*newblock), DRM_MEM_BUFLISTS);
98 if (!newblock)
99 goto out;
100 newblock->start = start;
101 newblock->size = p->size - (start - p->start);
102 newblock->file_priv = NULL;
103 newblock->next = p->next;
104 newblock->prev = p;
105 p->next->prev = newblock;
106 p->next = newblock;
107 p->size -= newblock->size;
108 p = newblock;
109 }
110
111 /* Maybe cut off the end of an existing block */
112 if (size < p->size) {
113 struct mem_block *newblock =
114 drm_alloc(sizeof(*newblock), DRM_MEM_BUFLISTS);
115 if (!newblock)
116 goto out;
117 newblock->start = start + size;
118 newblock->size = p->size - size;
119 newblock->file_priv = NULL;
120 newblock->next = p->next;
121 newblock->prev = p;
122 p->next->prev = newblock;
123 p->next = newblock;
124 p->size = size;
125 }
126
127 out:
128 /* Our block is in the middle */
129 p->file_priv = file_priv;
130 return p;
131}
132
133static struct mem_block *alloc_block(struct mem_block *heap, int size,
134 int align2, struct drm_file *file_priv)
135{
136 struct mem_block *p;
137 int mask = (1 << align2) - 1;
138
139 for (p = heap->next; p != heap; p = p->next) {
140 int start = (p->start + mask) & ~mask;
141 if (p->file_priv == NULL && start + size <= p->start + p->size)
142 return split_block(p, start, size, file_priv);
143 }
144
145 return NULL;
146}
147
148static struct mem_block *find_block(struct mem_block *heap, int start)
149{
150 struct mem_block *p;
151
152 for (p = heap->next; p != heap; p = p->next)
153 if (p->start == start)
154 return p;
155
156 return NULL;
157}
158
159static void free_block(struct mem_block *p)
160{
161 p->file_priv = NULL;
162
163 /* Assumes a single contiguous range. Needs a special file_priv in
164 * 'heap' to stop it being subsumed.
165 */
166 if (p->next->file_priv == NULL) {
167 struct mem_block *q = p->next;
168 p->size += q->size;
169 p->next = q->next;
170 p->next->prev = p;
171 drm_free(q, sizeof(*q), DRM_MEM_BUFLISTS);
172 }
173
174 if (p->prev->file_priv == NULL) {
175 struct mem_block *q = p->prev;
176 q->size += p->size;
177 q->next = p->next;
178 q->next->prev = q;
179 drm_free(p, sizeof(*q), DRM_MEM_BUFLISTS);
180 }
181}
182
183/* Initialize. How to check for an uninitialized heap?
184 */
185static int init_heap(struct mem_block **heap, int start, int size)
186{
187 struct mem_block *blocks = drm_alloc(sizeof(*blocks), DRM_MEM_BUFLISTS);
188
189 if (!blocks)
190 return -ENOMEM;
191
192 *heap = drm_alloc(sizeof(**heap), DRM_MEM_BUFLISTS);
193 if (!*heap) {
194 drm_free(blocks, sizeof(*blocks), DRM_MEM_BUFLISTS);
195 return -ENOMEM;
196 }
197
198 blocks->start = start;
199 blocks->size = size;
200 blocks->file_priv = NULL;
201 blocks->next = blocks->prev = *heap;
202
203 memset(*heap, 0, sizeof(**heap));
204 (*heap)->file_priv = (struct drm_file *) - 1;
205 (*heap)->next = (*heap)->prev = blocks;
206 return 0;
207}
208
209/* Free all blocks associated with the releasing file.
210 */
211void i915_mem_release(struct drm_device * dev, struct drm_file *file_priv,
212 struct mem_block *heap)
213{
214 struct mem_block *p;
215
216 if (!heap || !heap->next)
217 return;
218
219 for (p = heap->next; p != heap; p = p->next) {
220 if (p->file_priv == file_priv) {
221 p->file_priv = NULL;
222 mark_block(dev, p, 0);
223 }
224 }
225
226 /* Assumes a single contiguous range. Needs a special file_priv in
227 * 'heap' to stop it being subsumed.
228 */
229 for (p = heap->next; p != heap; p = p->next) {
230 while (p->file_priv == NULL && p->next->file_priv == NULL) {
231 struct mem_block *q = p->next;
232 p->size += q->size;
233 p->next = q->next;
234 p->next->prev = p;
235 drm_free(q, sizeof(*q), DRM_MEM_BUFLISTS);
236 }
237 }
238}
239
240/* Shutdown.
241 */
242void i915_mem_takedown(struct mem_block **heap)
243{
244 struct mem_block *p;
245
246 if (!*heap)
247 return;
248
249 for (p = (*heap)->next; p != *heap;) {
250 struct mem_block *q = p;
251 p = p->next;
252 drm_free(q, sizeof(*q), DRM_MEM_BUFLISTS);
253 }
254
255 drm_free(*heap, sizeof(**heap), DRM_MEM_BUFLISTS);
256 *heap = NULL;
257}
258
259static struct mem_block **get_heap(drm_i915_private_t * dev_priv, int region)
260{
261 switch (region) {
262 case I915_MEM_REGION_AGP:
263 return &dev_priv->agp_heap;
264 default:
265 return NULL;
266 }
267}
268
269/* IOCTL HANDLERS */
270
271int i915_mem_alloc(struct drm_device *dev, void *data,
272 struct drm_file *file_priv)
273{
274 drm_i915_private_t *dev_priv = dev->dev_private;
275 drm_i915_mem_alloc_t *alloc = data;
276 struct mem_block *block, **heap;
277
278 if (!dev_priv) {
279 DRM_ERROR("called with no initialization\n");
280 return -EINVAL;
281 }
282
283 heap = get_heap(dev_priv, alloc->region);
284 if (!heap || !*heap)
285 return -EFAULT;
286
287 /* Make things easier on ourselves: all allocations at least
288 * 4k aligned.
289 */
290 if (alloc->alignment < 12)
291 alloc->alignment = 12;
292
293 block = alloc_block(*heap, alloc->size, alloc->alignment, file_priv);
294
295 if (!block)
296 return -ENOMEM;
297
298 mark_block(dev, block, 1);
299
300 if (DRM_COPY_TO_USER(alloc->region_offset, &block->start,
301 sizeof(int))) {
302 DRM_ERROR("copy_to_user\n");
303 return -EFAULT;
304 }
305
306 return 0;
307}
308
309int i915_mem_free(struct drm_device *dev, void *data,
310 struct drm_file *file_priv)
311{
312 drm_i915_private_t *dev_priv = dev->dev_private;
313 drm_i915_mem_free_t *memfree = data;
314 struct mem_block *block, **heap;
315
316 if (!dev_priv) {
317 DRM_ERROR("called with no initialization\n");
318 return -EINVAL;
319 }
320
321 heap = get_heap(dev_priv, memfree->region);
322 if (!heap || !*heap)
323 return -EFAULT;
324
325 block = find_block(*heap, memfree->region_offset);
326 if (!block)
327 return -EFAULT;
328
329 if (block->file_priv != file_priv)
330 return -EPERM;
331
332 mark_block(dev, block, 0);
333 free_block(block);
334 return 0;
335}
336
337int i915_mem_init_heap(struct drm_device *dev, void *data,
338 struct drm_file *file_priv)
339{
340 drm_i915_private_t *dev_priv = dev->dev_private;
341 drm_i915_mem_init_heap_t *initheap = data;
342 struct mem_block **heap;
343
344 if (!dev_priv) {
345 DRM_ERROR("called with no initialization\n");
346 return -EINVAL;
347 }
348
349 heap = get_heap(dev_priv, initheap->region);
350 if (!heap)
351 return -EFAULT;
352
353 if (*heap) {
354 DRM_ERROR("heap already initialized?");
355 return -EFAULT;
356 }
357
358 return init_heap(heap, initheap->start, initheap->size);
359}
360
361int i915_mem_destroy_heap( struct drm_device *dev, void *data,
362 struct drm_file *file_priv )
363{
364 drm_i915_private_t *dev_priv = dev->dev_private;
365 drm_i915_mem_destroy_heap_t *destroyheap = data;
366 struct mem_block **heap;
367
368 if ( !dev_priv ) {
369 DRM_ERROR( "called with no initialization\n" );
370 return -EINVAL;
371 }
372
373 heap = get_heap( dev_priv, destroyheap->region );
374 if (!heap) {
375 DRM_ERROR("get_heap failed");
376 return -EFAULT;
377 }
378
379 if (!*heap) {
380 DRM_ERROR("heap not initialized?");
381 return -EFAULT;
382 }
383
384 i915_mem_takedown( heap );
385 return 0;
386}
diff --git a/drivers/char/drm/mga_dma.c b/drivers/char/drm/mga_dma.c
deleted file mode 100644
index c1d12dbfa8d8..000000000000
--- a/drivers/char/drm/mga_dma.c
+++ /dev/null
@@ -1,1162 +0,0 @@
1/* mga_dma.c -- DMA support for mga g200/g400 -*- linux-c -*-
2 * Created: Mon Dec 13 01:50:01 1999 by jhartmann@precisioninsight.com
3 *
4 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
5 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
6 * All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice (including the next
16 * paragraph) shall be included in all copies or substantial portions of the
17 * Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
23 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 * DEALINGS IN THE SOFTWARE.
26 */
27
28/**
29 * \file mga_dma.c
30 * DMA support for MGA G200 / G400.
31 *
32 * \author Rickard E. (Rik) Faith <faith@valinux.com>
33 * \author Jeff Hartmann <jhartmann@valinux.com>
34 * \author Keith Whitwell <keith@tungstengraphics.com>
35 * \author Gareth Hughes <gareth@valinux.com>
36 */
37
38#include "drmP.h"
39#include "drm.h"
40#include "drm_sarea.h"
41#include "mga_drm.h"
42#include "mga_drv.h"
43
44#define MGA_DEFAULT_USEC_TIMEOUT 10000
45#define MGA_FREELIST_DEBUG 0
46
47#define MINIMAL_CLEANUP 0
48#define FULL_CLEANUP 1
49static int mga_do_cleanup_dma(struct drm_device *dev, int full_cleanup);
50
51/* ================================================================
52 * Engine control
53 */
54
55int mga_do_wait_for_idle(drm_mga_private_t * dev_priv)
56{
57 u32 status = 0;
58 int i;
59 DRM_DEBUG("\n");
60
61 for (i = 0; i < dev_priv->usec_timeout; i++) {
62 status = MGA_READ(MGA_STATUS) & MGA_ENGINE_IDLE_MASK;
63 if (status == MGA_ENDPRDMASTS) {
64 MGA_WRITE8(MGA_CRTC_INDEX, 0);
65 return 0;
66 }
67 DRM_UDELAY(1);
68 }
69
70#if MGA_DMA_DEBUG
71 DRM_ERROR("failed!\n");
72 DRM_INFO(" status=0x%08x\n", status);
73#endif
74 return -EBUSY;
75}
76
77static int mga_do_dma_reset(drm_mga_private_t * dev_priv)
78{
79 drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
80 drm_mga_primary_buffer_t *primary = &dev_priv->prim;
81
82 DRM_DEBUG("\n");
83
84 /* The primary DMA stream should look like new right about now.
85 */
86 primary->tail = 0;
87 primary->space = primary->size;
88 primary->last_flush = 0;
89
90 sarea_priv->last_wrap = 0;
91
92 /* FIXME: Reset counters, buffer ages etc...
93 */
94
95 /* FIXME: What else do we need to reinitialize? WARP stuff?
96 */
97
98 return 0;
99}
100
101/* ================================================================
102 * Primary DMA stream
103 */
104
105void mga_do_dma_flush(drm_mga_private_t * dev_priv)
106{
107 drm_mga_primary_buffer_t *primary = &dev_priv->prim;
108 u32 head, tail;
109 u32 status = 0;
110 int i;
111 DMA_LOCALS;
112 DRM_DEBUG("\n");
113
114 /* We need to wait so that we can do an safe flush */
115 for (i = 0; i < dev_priv->usec_timeout; i++) {
116 status = MGA_READ(MGA_STATUS) & MGA_ENGINE_IDLE_MASK;
117 if (status == MGA_ENDPRDMASTS)
118 break;
119 DRM_UDELAY(1);
120 }
121
122 if (primary->tail == primary->last_flush) {
123 DRM_DEBUG(" bailing out...\n");
124 return;
125 }
126
127 tail = primary->tail + dev_priv->primary->offset;
128
129 /* We need to pad the stream between flushes, as the card
130 * actually (partially?) reads the first of these commands.
131 * See page 4-16 in the G400 manual, middle of the page or so.
132 */
133 BEGIN_DMA(1);
134
135 DMA_BLOCK(MGA_DMAPAD, 0x00000000,
136 MGA_DMAPAD, 0x00000000,
137 MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000);
138
139 ADVANCE_DMA();
140
141 primary->last_flush = primary->tail;
142
143 head = MGA_READ(MGA_PRIMADDRESS);
144
145 if (head <= tail) {
146 primary->space = primary->size - primary->tail;
147 } else {
148 primary->space = head - tail;
149 }
150
151 DRM_DEBUG(" head = 0x%06lx\n", head - dev_priv->primary->offset);
152 DRM_DEBUG(" tail = 0x%06lx\n", tail - dev_priv->primary->offset);
153 DRM_DEBUG(" space = 0x%06x\n", primary->space);
154
155 mga_flush_write_combine();
156 MGA_WRITE(MGA_PRIMEND, tail | dev_priv->dma_access);
157
158 DRM_DEBUG("done.\n");
159}
160
161void mga_do_dma_wrap_start(drm_mga_private_t * dev_priv)
162{
163 drm_mga_primary_buffer_t *primary = &dev_priv->prim;
164 u32 head, tail;
165 DMA_LOCALS;
166 DRM_DEBUG("\n");
167
168 BEGIN_DMA_WRAP();
169
170 DMA_BLOCK(MGA_DMAPAD, 0x00000000,
171 MGA_DMAPAD, 0x00000000,
172 MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000);
173
174 ADVANCE_DMA();
175
176 tail = primary->tail + dev_priv->primary->offset;
177
178 primary->tail = 0;
179 primary->last_flush = 0;
180 primary->last_wrap++;
181
182 head = MGA_READ(MGA_PRIMADDRESS);
183
184 if (head == dev_priv->primary->offset) {
185 primary->space = primary->size;
186 } else {
187 primary->space = head - dev_priv->primary->offset;
188 }
189
190 DRM_DEBUG(" head = 0x%06lx\n", head - dev_priv->primary->offset);
191 DRM_DEBUG(" tail = 0x%06x\n", primary->tail);
192 DRM_DEBUG(" wrap = %d\n", primary->last_wrap);
193 DRM_DEBUG(" space = 0x%06x\n", primary->space);
194
195 mga_flush_write_combine();
196 MGA_WRITE(MGA_PRIMEND, tail | dev_priv->dma_access);
197
198 set_bit(0, &primary->wrapped);
199 DRM_DEBUG("done.\n");
200}
201
202void mga_do_dma_wrap_end(drm_mga_private_t * dev_priv)
203{
204 drm_mga_primary_buffer_t *primary = &dev_priv->prim;
205 drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
206 u32 head = dev_priv->primary->offset;
207 DRM_DEBUG("\n");
208
209 sarea_priv->last_wrap++;
210 DRM_DEBUG(" wrap = %d\n", sarea_priv->last_wrap);
211
212 mga_flush_write_combine();
213 MGA_WRITE(MGA_PRIMADDRESS, head | MGA_DMA_GENERAL);
214
215 clear_bit(0, &primary->wrapped);
216 DRM_DEBUG("done.\n");
217}
218
219/* ================================================================
220 * Freelist management
221 */
222
223#define MGA_BUFFER_USED ~0
224#define MGA_BUFFER_FREE 0
225
226#if MGA_FREELIST_DEBUG
227static void mga_freelist_print(struct drm_device * dev)
228{
229 drm_mga_private_t *dev_priv = dev->dev_private;
230 drm_mga_freelist_t *entry;
231
232 DRM_INFO("\n");
233 DRM_INFO("current dispatch: last=0x%x done=0x%x\n",
234 dev_priv->sarea_priv->last_dispatch,
235 (unsigned int)(MGA_READ(MGA_PRIMADDRESS) -
236 dev_priv->primary->offset));
237 DRM_INFO("current freelist:\n");
238
239 for (entry = dev_priv->head->next; entry; entry = entry->next) {
240 DRM_INFO(" %p idx=%2d age=0x%x 0x%06lx\n",
241 entry, entry->buf->idx, entry->age.head,
242 entry->age.head - dev_priv->primary->offset);
243 }
244 DRM_INFO("\n");
245}
246#endif
247
248static int mga_freelist_init(struct drm_device * dev, drm_mga_private_t * dev_priv)
249{
250 struct drm_device_dma *dma = dev->dma;
251 struct drm_buf *buf;
252 drm_mga_buf_priv_t *buf_priv;
253 drm_mga_freelist_t *entry;
254 int i;
255 DRM_DEBUG("count=%d\n", dma->buf_count);
256
257 dev_priv->head = drm_alloc(sizeof(drm_mga_freelist_t), DRM_MEM_DRIVER);
258 if (dev_priv->head == NULL)
259 return -ENOMEM;
260
261 memset(dev_priv->head, 0, sizeof(drm_mga_freelist_t));
262 SET_AGE(&dev_priv->head->age, MGA_BUFFER_USED, 0);
263
264 for (i = 0; i < dma->buf_count; i++) {
265 buf = dma->buflist[i];
266 buf_priv = buf->dev_private;
267
268 entry = drm_alloc(sizeof(drm_mga_freelist_t), DRM_MEM_DRIVER);
269 if (entry == NULL)
270 return -ENOMEM;
271
272 memset(entry, 0, sizeof(drm_mga_freelist_t));
273
274 entry->next = dev_priv->head->next;
275 entry->prev = dev_priv->head;
276 SET_AGE(&entry->age, MGA_BUFFER_FREE, 0);
277 entry->buf = buf;
278
279 if (dev_priv->head->next != NULL)
280 dev_priv->head->next->prev = entry;
281 if (entry->next == NULL)
282 dev_priv->tail = entry;
283
284 buf_priv->list_entry = entry;
285 buf_priv->discard = 0;
286 buf_priv->dispatched = 0;
287
288 dev_priv->head->next = entry;
289 }
290
291 return 0;
292}
293
294static void mga_freelist_cleanup(struct drm_device * dev)
295{
296 drm_mga_private_t *dev_priv = dev->dev_private;
297 drm_mga_freelist_t *entry;
298 drm_mga_freelist_t *next;
299 DRM_DEBUG("\n");
300
301 entry = dev_priv->head;
302 while (entry) {
303 next = entry->next;
304 drm_free(entry, sizeof(drm_mga_freelist_t), DRM_MEM_DRIVER);
305 entry = next;
306 }
307
308 dev_priv->head = dev_priv->tail = NULL;
309}
310
311#if 0
312/* FIXME: Still needed?
313 */
314static void mga_freelist_reset(struct drm_device * dev)
315{
316 struct drm_device_dma *dma = dev->dma;
317 struct drm_buf *buf;
318 drm_mga_buf_priv_t *buf_priv;
319 int i;
320
321 for (i = 0; i < dma->buf_count; i++) {
322 buf = dma->buflist[i];
323 buf_priv = buf->dev_private;
324 SET_AGE(&buf_priv->list_entry->age, MGA_BUFFER_FREE, 0);
325 }
326}
327#endif
328
329static struct drm_buf *mga_freelist_get(struct drm_device * dev)
330{
331 drm_mga_private_t *dev_priv = dev->dev_private;
332 drm_mga_freelist_t *next;
333 drm_mga_freelist_t *prev;
334 drm_mga_freelist_t *tail = dev_priv->tail;
335 u32 head, wrap;
336 DRM_DEBUG("\n");
337
338 head = MGA_READ(MGA_PRIMADDRESS);
339 wrap = dev_priv->sarea_priv->last_wrap;
340
341 DRM_DEBUG(" tail=0x%06lx %d\n",
342 tail->age.head ?
343 tail->age.head - dev_priv->primary->offset : 0,
344 tail->age.wrap);
345 DRM_DEBUG(" head=0x%06lx %d\n",
346 head - dev_priv->primary->offset, wrap);
347
348 if (TEST_AGE(&tail->age, head, wrap)) {
349 prev = dev_priv->tail->prev;
350 next = dev_priv->tail;
351 prev->next = NULL;
352 next->prev = next->next = NULL;
353 dev_priv->tail = prev;
354 SET_AGE(&next->age, MGA_BUFFER_USED, 0);
355 return next->buf;
356 }
357
358 DRM_DEBUG("returning NULL!\n");
359 return NULL;
360}
361
362int mga_freelist_put(struct drm_device * dev, struct drm_buf * buf)
363{
364 drm_mga_private_t *dev_priv = dev->dev_private;
365 drm_mga_buf_priv_t *buf_priv = buf->dev_private;
366 drm_mga_freelist_t *head, *entry, *prev;
367
368 DRM_DEBUG("age=0x%06lx wrap=%d\n",
369 buf_priv->list_entry->age.head -
370 dev_priv->primary->offset, buf_priv->list_entry->age.wrap);
371
372 entry = buf_priv->list_entry;
373 head = dev_priv->head;
374
375 if (buf_priv->list_entry->age.head == MGA_BUFFER_USED) {
376 SET_AGE(&entry->age, MGA_BUFFER_FREE, 0);
377 prev = dev_priv->tail;
378 prev->next = entry;
379 entry->prev = prev;
380 entry->next = NULL;
381 } else {
382 prev = head->next;
383 head->next = entry;
384 prev->prev = entry;
385 entry->prev = head;
386 entry->next = prev;
387 }
388
389 return 0;
390}
391
392/* ================================================================
393 * DMA initialization, cleanup
394 */
395
396int mga_driver_load(struct drm_device * dev, unsigned long flags)
397{
398 drm_mga_private_t *dev_priv;
399
400 dev_priv = drm_alloc(sizeof(drm_mga_private_t), DRM_MEM_DRIVER);
401 if (!dev_priv)
402 return -ENOMEM;
403
404 dev->dev_private = (void *)dev_priv;
405 memset(dev_priv, 0, sizeof(drm_mga_private_t));
406
407 dev_priv->usec_timeout = MGA_DEFAULT_USEC_TIMEOUT;
408 dev_priv->chipset = flags;
409
410 dev_priv->mmio_base = drm_get_resource_start(dev, 1);
411 dev_priv->mmio_size = drm_get_resource_len(dev, 1);
412
413 dev->counters += 3;
414 dev->types[6] = _DRM_STAT_IRQ;
415 dev->types[7] = _DRM_STAT_PRIMARY;
416 dev->types[8] = _DRM_STAT_SECONDARY;
417
418 return 0;
419}
420
421#if __OS_HAS_AGP
422/**
423 * Bootstrap the driver for AGP DMA.
424 *
425 * \todo
426 * Investigate whether there is any benifit to storing the WARP microcode in
427 * AGP memory. If not, the microcode may as well always be put in PCI
428 * memory.
429 *
430 * \todo
431 * This routine needs to set dma_bs->agp_mode to the mode actually configured
432 * in the hardware. Looking just at the Linux AGP driver code, I don't see
433 * an easy way to determine this.
434 *
435 * \sa mga_do_dma_bootstrap, mga_do_pci_dma_bootstrap
436 */
437static int mga_do_agp_dma_bootstrap(struct drm_device * dev,
438 drm_mga_dma_bootstrap_t * dma_bs)
439{
440 drm_mga_private_t *const dev_priv =
441 (drm_mga_private_t *) dev->dev_private;
442 unsigned int warp_size = mga_warp_microcode_size(dev_priv);
443 int err;
444 unsigned offset;
445 const unsigned secondary_size = dma_bs->secondary_bin_count
446 * dma_bs->secondary_bin_size;
447 const unsigned agp_size = (dma_bs->agp_size << 20);
448 struct drm_buf_desc req;
449 struct drm_agp_mode mode;
450 struct drm_agp_info info;
451 struct drm_agp_buffer agp_req;
452 struct drm_agp_binding bind_req;
453
454 /* Acquire AGP. */
455 err = drm_agp_acquire(dev);
456 if (err) {
457 DRM_ERROR("Unable to acquire AGP: %d\n", err);
458 return err;
459 }
460
461 err = drm_agp_info(dev, &info);
462 if (err) {
463 DRM_ERROR("Unable to get AGP info: %d\n", err);
464 return err;
465 }
466
467 mode.mode = (info.mode & ~0x07) | dma_bs->agp_mode;
468 err = drm_agp_enable(dev, mode);
469 if (err) {
470 DRM_ERROR("Unable to enable AGP (mode = 0x%lx)\n", mode.mode);
471 return err;
472 }
473
474 /* In addition to the usual AGP mode configuration, the G200 AGP cards
475 * need to have the AGP mode "manually" set.
476 */
477
478 if (dev_priv->chipset == MGA_CARD_TYPE_G200) {
479 if (mode.mode & 0x02) {
480 MGA_WRITE(MGA_AGP_PLL, MGA_AGP2XPLL_ENABLE);
481 } else {
482 MGA_WRITE(MGA_AGP_PLL, MGA_AGP2XPLL_DISABLE);
483 }
484 }
485
486 /* Allocate and bind AGP memory. */
487 agp_req.size = agp_size;
488 agp_req.type = 0;
489 err = drm_agp_alloc(dev, &agp_req);
490 if (err) {
491 dev_priv->agp_size = 0;
492 DRM_ERROR("Unable to allocate %uMB AGP memory\n",
493 dma_bs->agp_size);
494 return err;
495 }
496
497 dev_priv->agp_size = agp_size;
498 dev_priv->agp_handle = agp_req.handle;
499
500 bind_req.handle = agp_req.handle;
501 bind_req.offset = 0;
502 err = drm_agp_bind(dev, &bind_req);
503 if (err) {
504 DRM_ERROR("Unable to bind AGP memory: %d\n", err);
505 return err;
506 }
507
508 /* Make drm_addbufs happy by not trying to create a mapping for less
509 * than a page.
510 */
511 if (warp_size < PAGE_SIZE)
512 warp_size = PAGE_SIZE;
513
514 offset = 0;
515 err = drm_addmap(dev, offset, warp_size,
516 _DRM_AGP, _DRM_READ_ONLY, &dev_priv->warp);
517 if (err) {
518 DRM_ERROR("Unable to map WARP microcode: %d\n", err);
519 return err;
520 }
521
522 offset += warp_size;
523 err = drm_addmap(dev, offset, dma_bs->primary_size,
524 _DRM_AGP, _DRM_READ_ONLY, &dev_priv->primary);
525 if (err) {
526 DRM_ERROR("Unable to map primary DMA region: %d\n", err);
527 return err;
528 }
529
530 offset += dma_bs->primary_size;
531 err = drm_addmap(dev, offset, secondary_size,
532 _DRM_AGP, 0, &dev->agp_buffer_map);
533 if (err) {
534 DRM_ERROR("Unable to map secondary DMA region: %d\n", err);
535 return err;
536 }
537
538 (void)memset(&req, 0, sizeof(req));
539 req.count = dma_bs->secondary_bin_count;
540 req.size = dma_bs->secondary_bin_size;
541 req.flags = _DRM_AGP_BUFFER;
542 req.agp_start = offset;
543
544 err = drm_addbufs_agp(dev, &req);
545 if (err) {
546 DRM_ERROR("Unable to add secondary DMA buffers: %d\n", err);
547 return err;
548 }
549
550 {
551 struct drm_map_list *_entry;
552 unsigned long agp_token = 0;
553
554 list_for_each_entry(_entry, &dev->maplist, head) {
555 if (_entry->map == dev->agp_buffer_map)
556 agp_token = _entry->user_token;
557 }
558 if (!agp_token)
559 return -EFAULT;
560
561 dev->agp_buffer_token = agp_token;
562 }
563
564 offset += secondary_size;
565 err = drm_addmap(dev, offset, agp_size - offset,
566 _DRM_AGP, 0, &dev_priv->agp_textures);
567 if (err) {
568 DRM_ERROR("Unable to map AGP texture region %d\n", err);
569 return err;
570 }
571
572 drm_core_ioremap(dev_priv->warp, dev);
573 drm_core_ioremap(dev_priv->primary, dev);
574 drm_core_ioremap(dev->agp_buffer_map, dev);
575
576 if (!dev_priv->warp->handle ||
577 !dev_priv->primary->handle || !dev->agp_buffer_map->handle) {
578 DRM_ERROR("failed to ioremap agp regions! (%p, %p, %p)\n",
579 dev_priv->warp->handle, dev_priv->primary->handle,
580 dev->agp_buffer_map->handle);
581 return -ENOMEM;
582 }
583
584 dev_priv->dma_access = MGA_PAGPXFER;
585 dev_priv->wagp_enable = MGA_WAGP_ENABLE;
586
587 DRM_INFO("Initialized card for AGP DMA.\n");
588 return 0;
589}
590#else
591static int mga_do_agp_dma_bootstrap(struct drm_device * dev,
592 drm_mga_dma_bootstrap_t * dma_bs)
593{
594 return -EINVAL;
595}
596#endif
597
598/**
599 * Bootstrap the driver for PCI DMA.
600 *
601 * \todo
602 * The algorithm for decreasing the size of the primary DMA buffer could be
603 * better. The size should be rounded up to the nearest page size, then
604 * decrease the request size by a single page each pass through the loop.
605 *
606 * \todo
607 * Determine whether the maximum address passed to drm_pci_alloc is correct.
608 * The same goes for drm_addbufs_pci.
609 *
610 * \sa mga_do_dma_bootstrap, mga_do_agp_dma_bootstrap
611 */
612static int mga_do_pci_dma_bootstrap(struct drm_device * dev,
613 drm_mga_dma_bootstrap_t * dma_bs)
614{
615 drm_mga_private_t *const dev_priv =
616 (drm_mga_private_t *) dev->dev_private;
617 unsigned int warp_size = mga_warp_microcode_size(dev_priv);
618 unsigned int primary_size;
619 unsigned int bin_count;
620 int err;
621 struct drm_buf_desc req;
622
623 if (dev->dma == NULL) {
624 DRM_ERROR("dev->dma is NULL\n");
625 return -EFAULT;
626 }
627
628 /* Make drm_addbufs happy by not trying to create a mapping for less
629 * than a page.
630 */
631 if (warp_size < PAGE_SIZE)
632 warp_size = PAGE_SIZE;
633
634 /* The proper alignment is 0x100 for this mapping */
635 err = drm_addmap(dev, 0, warp_size, _DRM_CONSISTENT,
636 _DRM_READ_ONLY, &dev_priv->warp);
637 if (err != 0) {
638 DRM_ERROR("Unable to create mapping for WARP microcode: %d\n",
639 err);
640 return err;
641 }
642
643 /* Other than the bottom two bits being used to encode other
644 * information, there don't appear to be any restrictions on the
645 * alignment of the primary or secondary DMA buffers.
646 */
647
648 for (primary_size = dma_bs->primary_size; primary_size != 0;
649 primary_size >>= 1) {
650 /* The proper alignment for this mapping is 0x04 */
651 err = drm_addmap(dev, 0, primary_size, _DRM_CONSISTENT,
652 _DRM_READ_ONLY, &dev_priv->primary);
653 if (!err)
654 break;
655 }
656
657 if (err != 0) {
658 DRM_ERROR("Unable to allocate primary DMA region: %d\n", err);
659 return -ENOMEM;
660 }
661
662 if (dev_priv->primary->size != dma_bs->primary_size) {
663 DRM_INFO("Primary DMA buffer size reduced from %u to %u.\n",
664 dma_bs->primary_size,
665 (unsigned)dev_priv->primary->size);
666 dma_bs->primary_size = dev_priv->primary->size;
667 }
668
669 for (bin_count = dma_bs->secondary_bin_count; bin_count > 0;
670 bin_count--) {
671 (void)memset(&req, 0, sizeof(req));
672 req.count = bin_count;
673 req.size = dma_bs->secondary_bin_size;
674
675 err = drm_addbufs_pci(dev, &req);
676 if (!err) {
677 break;
678 }
679 }
680
681 if (bin_count == 0) {
682 DRM_ERROR("Unable to add secondary DMA buffers: %d\n", err);
683 return err;
684 }
685
686 if (bin_count != dma_bs->secondary_bin_count) {
687 DRM_INFO("Secondary PCI DMA buffer bin count reduced from %u "
688 "to %u.\n", dma_bs->secondary_bin_count, bin_count);
689
690 dma_bs->secondary_bin_count = bin_count;
691 }
692
693 dev_priv->dma_access = 0;
694 dev_priv->wagp_enable = 0;
695
696 dma_bs->agp_mode = 0;
697
698 DRM_INFO("Initialized card for PCI DMA.\n");
699 return 0;
700}
701
702static int mga_do_dma_bootstrap(struct drm_device * dev,
703 drm_mga_dma_bootstrap_t * dma_bs)
704{
705 const int is_agp = (dma_bs->agp_mode != 0) && drm_device_is_agp(dev);
706 int err;
707 drm_mga_private_t *const dev_priv =
708 (drm_mga_private_t *) dev->dev_private;
709
710 dev_priv->used_new_dma_init = 1;
711
712 /* The first steps are the same for both PCI and AGP based DMA. Map
713 * the cards MMIO registers and map a status page.
714 */
715 err = drm_addmap(dev, dev_priv->mmio_base, dev_priv->mmio_size,
716 _DRM_REGISTERS, _DRM_READ_ONLY, &dev_priv->mmio);
717 if (err) {
718 DRM_ERROR("Unable to map MMIO region: %d\n", err);
719 return err;
720 }
721
722 err = drm_addmap(dev, 0, SAREA_MAX, _DRM_SHM,
723 _DRM_READ_ONLY | _DRM_LOCKED | _DRM_KERNEL,
724 &dev_priv->status);
725 if (err) {
726 DRM_ERROR("Unable to map status region: %d\n", err);
727 return err;
728 }
729
730 /* The DMA initialization procedure is slightly different for PCI and
731 * AGP cards. AGP cards just allocate a large block of AGP memory and
732 * carve off portions of it for internal uses. The remaining memory
733 * is returned to user-mode to be used for AGP textures.
734 */
735 if (is_agp) {
736 err = mga_do_agp_dma_bootstrap(dev, dma_bs);
737 }
738
739 /* If we attempted to initialize the card for AGP DMA but failed,
740 * clean-up any mess that may have been created.
741 */
742
743 if (err) {
744 mga_do_cleanup_dma(dev, MINIMAL_CLEANUP);
745 }
746
747 /* Not only do we want to try and initialized PCI cards for PCI DMA,
748 * but we also try to initialized AGP cards that could not be
749 * initialized for AGP DMA. This covers the case where we have an AGP
750 * card in a system with an unsupported AGP chipset. In that case the
751 * card will be detected as AGP, but we won't be able to allocate any
752 * AGP memory, etc.
753 */
754
755 if (!is_agp || err) {
756 err = mga_do_pci_dma_bootstrap(dev, dma_bs);
757 }
758
759 return err;
760}
761
762int mga_dma_bootstrap(struct drm_device *dev, void *data,
763 struct drm_file *file_priv)
764{
765 drm_mga_dma_bootstrap_t *bootstrap = data;
766 int err;
767 static const int modes[] = { 0, 1, 2, 2, 4, 4, 4, 4 };
768 const drm_mga_private_t *const dev_priv =
769 (drm_mga_private_t *) dev->dev_private;
770
771 err = mga_do_dma_bootstrap(dev, bootstrap);
772 if (err) {
773 mga_do_cleanup_dma(dev, FULL_CLEANUP);
774 return err;
775 }
776
777 if (dev_priv->agp_textures != NULL) {
778 bootstrap->texture_handle = dev_priv->agp_textures->offset;
779 bootstrap->texture_size = dev_priv->agp_textures->size;
780 } else {
781 bootstrap->texture_handle = 0;
782 bootstrap->texture_size = 0;
783 }
784
785 bootstrap->agp_mode = modes[bootstrap->agp_mode & 0x07];
786
787 return err;
788}
789
790static int mga_do_init_dma(struct drm_device * dev, drm_mga_init_t * init)
791{
792 drm_mga_private_t *dev_priv;
793 int ret;
794 DRM_DEBUG("\n");
795
796 dev_priv = dev->dev_private;
797
798 if (init->sgram) {
799 dev_priv->clear_cmd = MGA_DWGCTL_CLEAR | MGA_ATYPE_BLK;
800 } else {
801 dev_priv->clear_cmd = MGA_DWGCTL_CLEAR | MGA_ATYPE_RSTR;
802 }
803 dev_priv->maccess = init->maccess;
804
805 dev_priv->fb_cpp = init->fb_cpp;
806 dev_priv->front_offset = init->front_offset;
807 dev_priv->front_pitch = init->front_pitch;
808 dev_priv->back_offset = init->back_offset;
809 dev_priv->back_pitch = init->back_pitch;
810
811 dev_priv->depth_cpp = init->depth_cpp;
812 dev_priv->depth_offset = init->depth_offset;
813 dev_priv->depth_pitch = init->depth_pitch;
814
815 /* FIXME: Need to support AGP textures...
816 */
817 dev_priv->texture_offset = init->texture_offset[0];
818 dev_priv->texture_size = init->texture_size[0];
819
820 dev_priv->sarea = drm_getsarea(dev);
821 if (!dev_priv->sarea) {
822 DRM_ERROR("failed to find sarea!\n");
823 return -EINVAL;
824 }
825
826 if (!dev_priv->used_new_dma_init) {
827
828 dev_priv->dma_access = MGA_PAGPXFER;
829 dev_priv->wagp_enable = MGA_WAGP_ENABLE;
830
831 dev_priv->status = drm_core_findmap(dev, init->status_offset);
832 if (!dev_priv->status) {
833 DRM_ERROR("failed to find status page!\n");
834 return -EINVAL;
835 }
836 dev_priv->mmio = drm_core_findmap(dev, init->mmio_offset);
837 if (!dev_priv->mmio) {
838 DRM_ERROR("failed to find mmio region!\n");
839 return -EINVAL;
840 }
841 dev_priv->warp = drm_core_findmap(dev, init->warp_offset);
842 if (!dev_priv->warp) {
843 DRM_ERROR("failed to find warp microcode region!\n");
844 return -EINVAL;
845 }
846 dev_priv->primary = drm_core_findmap(dev, init->primary_offset);
847 if (!dev_priv->primary) {
848 DRM_ERROR("failed to find primary dma region!\n");
849 return -EINVAL;
850 }
851 dev->agp_buffer_token = init->buffers_offset;
852 dev->agp_buffer_map =
853 drm_core_findmap(dev, init->buffers_offset);
854 if (!dev->agp_buffer_map) {
855 DRM_ERROR("failed to find dma buffer region!\n");
856 return -EINVAL;
857 }
858
859 drm_core_ioremap(dev_priv->warp, dev);
860 drm_core_ioremap(dev_priv->primary, dev);
861 drm_core_ioremap(dev->agp_buffer_map, dev);
862 }
863
864 dev_priv->sarea_priv =
865 (drm_mga_sarea_t *) ((u8 *) dev_priv->sarea->handle +
866 init->sarea_priv_offset);
867
868 if (!dev_priv->warp->handle ||
869 !dev_priv->primary->handle ||
870 ((dev_priv->dma_access != 0) &&
871 ((dev->agp_buffer_map == NULL) ||
872 (dev->agp_buffer_map->handle == NULL)))) {
873 DRM_ERROR("failed to ioremap agp regions!\n");
874 return -ENOMEM;
875 }
876
877 ret = mga_warp_install_microcode(dev_priv);
878 if (ret < 0) {
879 DRM_ERROR("failed to install WARP ucode!: %d\n", ret);
880 return ret;
881 }
882
883 ret = mga_warp_init(dev_priv);
884 if (ret < 0) {
885 DRM_ERROR("failed to init WARP engine!: %d\n", ret);
886 return ret;
887 }
888
889 dev_priv->prim.status = (u32 *) dev_priv->status->handle;
890
891 mga_do_wait_for_idle(dev_priv);
892
893 /* Init the primary DMA registers.
894 */
895 MGA_WRITE(MGA_PRIMADDRESS, dev_priv->primary->offset | MGA_DMA_GENERAL);
896#if 0
897 MGA_WRITE(MGA_PRIMPTR, virt_to_bus((void *)dev_priv->prim.status) | MGA_PRIMPTREN0 | /* Soft trap, SECEND, SETUPEND */
898 MGA_PRIMPTREN1); /* DWGSYNC */
899#endif
900
901 dev_priv->prim.start = (u8 *) dev_priv->primary->handle;
902 dev_priv->prim.end = ((u8 *) dev_priv->primary->handle
903 + dev_priv->primary->size);
904 dev_priv->prim.size = dev_priv->primary->size;
905
906 dev_priv->prim.tail = 0;
907 dev_priv->prim.space = dev_priv->prim.size;
908 dev_priv->prim.wrapped = 0;
909
910 dev_priv->prim.last_flush = 0;
911 dev_priv->prim.last_wrap = 0;
912
913 dev_priv->prim.high_mark = 256 * DMA_BLOCK_SIZE;
914
915 dev_priv->prim.status[0] = dev_priv->primary->offset;
916 dev_priv->prim.status[1] = 0;
917
918 dev_priv->sarea_priv->last_wrap = 0;
919 dev_priv->sarea_priv->last_frame.head = 0;
920 dev_priv->sarea_priv->last_frame.wrap = 0;
921
922 if (mga_freelist_init(dev, dev_priv) < 0) {
923 DRM_ERROR("could not initialize freelist\n");
924 return -ENOMEM;
925 }
926
927 return 0;
928}
929
930static int mga_do_cleanup_dma(struct drm_device *dev, int full_cleanup)
931{
932 int err = 0;
933 DRM_DEBUG("\n");
934
935 /* Make sure interrupts are disabled here because the uninstall ioctl
936 * may not have been called from userspace and after dev_private
937 * is freed, it's too late.
938 */
939 if (dev->irq_enabled)
940 drm_irq_uninstall(dev);
941
942 if (dev->dev_private) {
943 drm_mga_private_t *dev_priv = dev->dev_private;
944
945 if ((dev_priv->warp != NULL)
946 && (dev_priv->warp->type != _DRM_CONSISTENT))
947 drm_core_ioremapfree(dev_priv->warp, dev);
948
949 if ((dev_priv->primary != NULL)
950 && (dev_priv->primary->type != _DRM_CONSISTENT))
951 drm_core_ioremapfree(dev_priv->primary, dev);
952
953 if (dev->agp_buffer_map != NULL)
954 drm_core_ioremapfree(dev->agp_buffer_map, dev);
955
956 if (dev_priv->used_new_dma_init) {
957#if __OS_HAS_AGP
958 if (dev_priv->agp_handle != 0) {
959 struct drm_agp_binding unbind_req;
960 struct drm_agp_buffer free_req;
961
962 unbind_req.handle = dev_priv->agp_handle;
963 drm_agp_unbind(dev, &unbind_req);
964
965 free_req.handle = dev_priv->agp_handle;
966 drm_agp_free(dev, &free_req);
967
968 dev_priv->agp_textures = NULL;
969 dev_priv->agp_size = 0;
970 dev_priv->agp_handle = 0;
971 }
972
973 if ((dev->agp != NULL) && dev->agp->acquired) {
974 err = drm_agp_release(dev);
975 }
976#endif
977 }
978
979 dev_priv->warp = NULL;
980 dev_priv->primary = NULL;
981 dev_priv->sarea = NULL;
982 dev_priv->sarea_priv = NULL;
983 dev->agp_buffer_map = NULL;
984
985 if (full_cleanup) {
986 dev_priv->mmio = NULL;
987 dev_priv->status = NULL;
988 dev_priv->used_new_dma_init = 0;
989 }
990
991 memset(&dev_priv->prim, 0, sizeof(dev_priv->prim));
992 dev_priv->warp_pipe = 0;
993 memset(dev_priv->warp_pipe_phys, 0,
994 sizeof(dev_priv->warp_pipe_phys));
995
996 if (dev_priv->head != NULL) {
997 mga_freelist_cleanup(dev);
998 }
999 }
1000
1001 return err;
1002}
1003
1004int mga_dma_init(struct drm_device *dev, void *data,
1005 struct drm_file *file_priv)
1006{
1007 drm_mga_init_t *init = data;
1008 int err;
1009
1010 LOCK_TEST_WITH_RETURN(dev, file_priv);
1011
1012 switch (init->func) {
1013 case MGA_INIT_DMA:
1014 err = mga_do_init_dma(dev, init);
1015 if (err) {
1016 (void)mga_do_cleanup_dma(dev, FULL_CLEANUP);
1017 }
1018 return err;
1019 case MGA_CLEANUP_DMA:
1020 return mga_do_cleanup_dma(dev, FULL_CLEANUP);
1021 }
1022
1023 return -EINVAL;
1024}
1025
1026/* ================================================================
1027 * Primary DMA stream management
1028 */
1029
1030int mga_dma_flush(struct drm_device *dev, void *data,
1031 struct drm_file *file_priv)
1032{
1033 drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
1034 struct drm_lock *lock = data;
1035
1036 LOCK_TEST_WITH_RETURN(dev, file_priv);
1037
1038 DRM_DEBUG("%s%s%s\n",
1039 (lock->flags & _DRM_LOCK_FLUSH) ? "flush, " : "",
1040 (lock->flags & _DRM_LOCK_FLUSH_ALL) ? "flush all, " : "",
1041 (lock->flags & _DRM_LOCK_QUIESCENT) ? "idle, " : "");
1042
1043 WRAP_WAIT_WITH_RETURN(dev_priv);
1044
1045 if (lock->flags & (_DRM_LOCK_FLUSH | _DRM_LOCK_FLUSH_ALL)) {
1046 mga_do_dma_flush(dev_priv);
1047 }
1048
1049 if (lock->flags & _DRM_LOCK_QUIESCENT) {
1050#if MGA_DMA_DEBUG
1051 int ret = mga_do_wait_for_idle(dev_priv);
1052 if (ret < 0)
1053 DRM_INFO("-EBUSY\n");
1054 return ret;
1055#else
1056 return mga_do_wait_for_idle(dev_priv);
1057#endif
1058 } else {
1059 return 0;
1060 }
1061}
1062
1063int mga_dma_reset(struct drm_device *dev, void *data,
1064 struct drm_file *file_priv)
1065{
1066 drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
1067
1068 LOCK_TEST_WITH_RETURN(dev, file_priv);
1069
1070 return mga_do_dma_reset(dev_priv);
1071}
1072
1073/* ================================================================
1074 * DMA buffer management
1075 */
1076
1077static int mga_dma_get_buffers(struct drm_device * dev,
1078 struct drm_file *file_priv, struct drm_dma * d)
1079{
1080 struct drm_buf *buf;
1081 int i;
1082
1083 for (i = d->granted_count; i < d->request_count; i++) {
1084 buf = mga_freelist_get(dev);
1085 if (!buf)
1086 return -EAGAIN;
1087
1088 buf->file_priv = file_priv;
1089
1090 if (DRM_COPY_TO_USER(&d->request_indices[i],
1091 &buf->idx, sizeof(buf->idx)))
1092 return -EFAULT;
1093 if (DRM_COPY_TO_USER(&d->request_sizes[i],
1094 &buf->total, sizeof(buf->total)))
1095 return -EFAULT;
1096
1097 d->granted_count++;
1098 }
1099 return 0;
1100}
1101
1102int mga_dma_buffers(struct drm_device *dev, void *data,
1103 struct drm_file *file_priv)
1104{
1105 struct drm_device_dma *dma = dev->dma;
1106 drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
1107 struct drm_dma *d = data;
1108 int ret = 0;
1109
1110 LOCK_TEST_WITH_RETURN(dev, file_priv);
1111
1112 /* Please don't send us buffers.
1113 */
1114 if (d->send_count != 0) {
1115 DRM_ERROR("Process %d trying to send %d buffers via drmDMA\n",
1116 DRM_CURRENTPID, d->send_count);
1117 return -EINVAL;
1118 }
1119
1120 /* We'll send you buffers.
1121 */
1122 if (d->request_count < 0 || d->request_count > dma->buf_count) {
1123 DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n",
1124 DRM_CURRENTPID, d->request_count, dma->buf_count);
1125 return -EINVAL;
1126 }
1127
1128 WRAP_TEST_WITH_RETURN(dev_priv);
1129
1130 d->granted_count = 0;
1131
1132 if (d->request_count) {
1133 ret = mga_dma_get_buffers(dev, file_priv, d);
1134 }
1135
1136 return ret;
1137}
1138
1139/**
1140 * Called just before the module is unloaded.
1141 */
1142int mga_driver_unload(struct drm_device * dev)
1143{
1144 drm_free(dev->dev_private, sizeof(drm_mga_private_t), DRM_MEM_DRIVER);
1145 dev->dev_private = NULL;
1146
1147 return 0;
1148}
1149
1150/**
1151 * Called when the last opener of the device is closed.
1152 */
1153void mga_driver_lastclose(struct drm_device * dev)
1154{
1155 mga_do_cleanup_dma(dev, FULL_CLEANUP);
1156}
1157
1158int mga_driver_dma_quiescent(struct drm_device * dev)
1159{
1160 drm_mga_private_t *dev_priv = dev->dev_private;
1161 return mga_do_wait_for_idle(dev_priv);
1162}
diff --git a/drivers/char/drm/mga_drm.h b/drivers/char/drm/mga_drm.h
deleted file mode 100644
index 944b50a5ff24..000000000000
--- a/drivers/char/drm/mga_drm.h
+++ /dev/null
@@ -1,417 +0,0 @@
1/* mga_drm.h -- Public header for the Matrox g200/g400 driver -*- linux-c -*-
2 * Created: Tue Jan 25 01:50:01 1999 by jhartmann@precisioninsight.com
3 *
4 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
5 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
6 * All rights reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice (including the next
16 * paragraph) shall be included in all copies or substantial portions of the
17 * Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
23 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25 * OTHER DEALINGS IN THE SOFTWARE.
26 *
27 * Authors:
28 * Jeff Hartmann <jhartmann@valinux.com>
29 * Keith Whitwell <keith@tungstengraphics.com>
30 *
31 * Rewritten by:
32 * Gareth Hughes <gareth@valinux.com>
33 */
34
35#ifndef __MGA_DRM_H__
36#define __MGA_DRM_H__
37
38/* WARNING: If you change any of these defines, make sure to change the
39 * defines in the Xserver file (mga_sarea.h)
40 */
41
42#ifndef __MGA_SAREA_DEFINES__
43#define __MGA_SAREA_DEFINES__
44
45/* WARP pipe flags
46 */
47#define MGA_F 0x1 /* fog */
48#define MGA_A 0x2 /* alpha */
49#define MGA_S 0x4 /* specular */
50#define MGA_T2 0x8 /* multitexture */
51
52#define MGA_WARP_TGZ 0
53#define MGA_WARP_TGZF (MGA_F)
54#define MGA_WARP_TGZA (MGA_A)
55#define MGA_WARP_TGZAF (MGA_F|MGA_A)
56#define MGA_WARP_TGZS (MGA_S)
57#define MGA_WARP_TGZSF (MGA_S|MGA_F)
58#define MGA_WARP_TGZSA (MGA_S|MGA_A)
59#define MGA_WARP_TGZSAF (MGA_S|MGA_F|MGA_A)
60#define MGA_WARP_T2GZ (MGA_T2)
61#define MGA_WARP_T2GZF (MGA_T2|MGA_F)
62#define MGA_WARP_T2GZA (MGA_T2|MGA_A)
63#define MGA_WARP_T2GZAF (MGA_T2|MGA_A|MGA_F)
64#define MGA_WARP_T2GZS (MGA_T2|MGA_S)
65#define MGA_WARP_T2GZSF (MGA_T2|MGA_S|MGA_F)
66#define MGA_WARP_T2GZSA (MGA_T2|MGA_S|MGA_A)
67#define MGA_WARP_T2GZSAF (MGA_T2|MGA_S|MGA_F|MGA_A)
68
69#define MGA_MAX_G200_PIPES 8 /* no multitex */
70#define MGA_MAX_G400_PIPES 16
71#define MGA_MAX_WARP_PIPES MGA_MAX_G400_PIPES
72#define MGA_WARP_UCODE_SIZE 32768 /* in bytes */
73
74#define MGA_CARD_TYPE_G200 1
75#define MGA_CARD_TYPE_G400 2
76#define MGA_CARD_TYPE_G450 3 /* not currently used */
77#define MGA_CARD_TYPE_G550 4
78
79#define MGA_FRONT 0x1
80#define MGA_BACK 0x2
81#define MGA_DEPTH 0x4
82
83/* What needs to be changed for the current vertex dma buffer?
84 */
85#define MGA_UPLOAD_CONTEXT 0x1
86#define MGA_UPLOAD_TEX0 0x2
87#define MGA_UPLOAD_TEX1 0x4
88#define MGA_UPLOAD_PIPE 0x8
89#define MGA_UPLOAD_TEX0IMAGE 0x10 /* handled client-side */
90#define MGA_UPLOAD_TEX1IMAGE 0x20 /* handled client-side */
91#define MGA_UPLOAD_2D 0x40
92#define MGA_WAIT_AGE 0x80 /* handled client-side */
93#define MGA_UPLOAD_CLIPRECTS 0x100 /* handled client-side */
94#if 0
95#define MGA_DMA_FLUSH 0x200 /* set when someone gets the lock
96 quiescent */
97#endif
98
99/* 32 buffers of 64k each, total 2 meg.
100 */
101#define MGA_BUFFER_SIZE (1 << 16)
102#define MGA_NUM_BUFFERS 128
103
104/* Keep these small for testing.
105 */
106#define MGA_NR_SAREA_CLIPRECTS 8
107
108/* 2 heaps (1 for card, 1 for agp), each divided into upto 128
109 * regions, subject to a minimum region size of (1<<16) == 64k.
110 *
111 * Clients may subdivide regions internally, but when sharing between
112 * clients, the region size is the minimum granularity.
113 */
114
115#define MGA_CARD_HEAP 0
116#define MGA_AGP_HEAP 1
117#define MGA_NR_TEX_HEAPS 2
118#define MGA_NR_TEX_REGIONS 16
119#define MGA_LOG_MIN_TEX_REGION_SIZE 16
120
121#define DRM_MGA_IDLE_RETRY 2048
122
123#endif /* __MGA_SAREA_DEFINES__ */
124
125/* Setup registers for 3D context
126 */
127typedef struct {
128 unsigned int dstorg;
129 unsigned int maccess;
130 unsigned int plnwt;
131 unsigned int dwgctl;
132 unsigned int alphactrl;
133 unsigned int fogcolor;
134 unsigned int wflag;
135 unsigned int tdualstage0;
136 unsigned int tdualstage1;
137 unsigned int fcol;
138 unsigned int stencil;
139 unsigned int stencilctl;
140} drm_mga_context_regs_t;
141
142/* Setup registers for 2D, X server
143 */
144typedef struct {
145 unsigned int pitch;
146} drm_mga_server_regs_t;
147
148/* Setup registers for each texture unit
149 */
150typedef struct {
151 unsigned int texctl;
152 unsigned int texctl2;
153 unsigned int texfilter;
154 unsigned int texbordercol;
155 unsigned int texorg;
156 unsigned int texwidth;
157 unsigned int texheight;
158 unsigned int texorg1;
159 unsigned int texorg2;
160 unsigned int texorg3;
161 unsigned int texorg4;
162} drm_mga_texture_regs_t;
163
164/* General aging mechanism
165 */
166typedef struct {
167 unsigned int head; /* Position of head pointer */
168 unsigned int wrap; /* Primary DMA wrap count */
169} drm_mga_age_t;
170
171typedef struct _drm_mga_sarea {
172 /* The channel for communication of state information to the kernel
173 * on firing a vertex dma buffer.
174 */
175 drm_mga_context_regs_t context_state;
176 drm_mga_server_regs_t server_state;
177 drm_mga_texture_regs_t tex_state[2];
178 unsigned int warp_pipe;
179 unsigned int dirty;
180 unsigned int vertsize;
181
182 /* The current cliprects, or a subset thereof.
183 */
184 struct drm_clip_rect boxes[MGA_NR_SAREA_CLIPRECTS];
185 unsigned int nbox;
186
187 /* Information about the most recently used 3d drawable. The
188 * client fills in the req_* fields, the server fills in the
189 * exported_ fields and puts the cliprects into boxes, above.
190 *
191 * The client clears the exported_drawable field before
192 * clobbering the boxes data.
193 */
194 unsigned int req_drawable; /* the X drawable id */
195 unsigned int req_draw_buffer; /* MGA_FRONT or MGA_BACK */
196
197 unsigned int exported_drawable;
198 unsigned int exported_index;
199 unsigned int exported_stamp;
200 unsigned int exported_buffers;
201 unsigned int exported_nfront;
202 unsigned int exported_nback;
203 int exported_back_x, exported_front_x, exported_w;
204 int exported_back_y, exported_front_y, exported_h;
205 struct drm_clip_rect exported_boxes[MGA_NR_SAREA_CLIPRECTS];
206
207 /* Counters for aging textures and for client-side throttling.
208 */
209 unsigned int status[4];
210 unsigned int last_wrap;
211
212 drm_mga_age_t last_frame;
213 unsigned int last_enqueue; /* last time a buffer was enqueued */
214 unsigned int last_dispatch; /* age of the most recently dispatched buffer */
215 unsigned int last_quiescent; /* */
216
217 /* LRU lists for texture memory in agp space and on the card.
218 */
219 struct drm_tex_region texList[MGA_NR_TEX_HEAPS][MGA_NR_TEX_REGIONS + 1];
220 unsigned int texAge[MGA_NR_TEX_HEAPS];
221
222 /* Mechanism to validate card state.
223 */
224 int ctxOwner;
225} drm_mga_sarea_t;
226
227/* MGA specific ioctls
228 * The device specific ioctl range is 0x40 to 0x79.
229 */
230#define DRM_MGA_INIT 0x00
231#define DRM_MGA_FLUSH 0x01
232#define DRM_MGA_RESET 0x02
233#define DRM_MGA_SWAP 0x03
234#define DRM_MGA_CLEAR 0x04
235#define DRM_MGA_VERTEX 0x05
236#define DRM_MGA_INDICES 0x06
237#define DRM_MGA_ILOAD 0x07
238#define DRM_MGA_BLIT 0x08
239#define DRM_MGA_GETPARAM 0x09
240
241/* 3.2:
242 * ioctls for operating on fences.
243 */
244#define DRM_MGA_SET_FENCE 0x0a
245#define DRM_MGA_WAIT_FENCE 0x0b
246#define DRM_MGA_DMA_BOOTSTRAP 0x0c
247
248#define DRM_IOCTL_MGA_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_INIT, drm_mga_init_t)
249#define DRM_IOCTL_MGA_FLUSH DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_FLUSH, drm_lock_t)
250#define DRM_IOCTL_MGA_RESET DRM_IO( DRM_COMMAND_BASE + DRM_MGA_RESET)
251#define DRM_IOCTL_MGA_SWAP DRM_IO( DRM_COMMAND_BASE + DRM_MGA_SWAP)
252#define DRM_IOCTL_MGA_CLEAR DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_CLEAR, drm_mga_clear_t)
253#define DRM_IOCTL_MGA_VERTEX DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_VERTEX, drm_mga_vertex_t)
254#define DRM_IOCTL_MGA_INDICES DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_INDICES, drm_mga_indices_t)
255#define DRM_IOCTL_MGA_ILOAD DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_ILOAD, drm_mga_iload_t)
256#define DRM_IOCTL_MGA_BLIT DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_BLIT, drm_mga_blit_t)
257#define DRM_IOCTL_MGA_GETPARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_MGA_GETPARAM, drm_mga_getparam_t)
258#define DRM_IOCTL_MGA_SET_FENCE DRM_IOW( DRM_COMMAND_BASE + DRM_MGA_SET_FENCE, uint32_t)
259#define DRM_IOCTL_MGA_WAIT_FENCE DRM_IOWR(DRM_COMMAND_BASE + DRM_MGA_WAIT_FENCE, uint32_t)
260#define DRM_IOCTL_MGA_DMA_BOOTSTRAP DRM_IOWR(DRM_COMMAND_BASE + DRM_MGA_DMA_BOOTSTRAP, drm_mga_dma_bootstrap_t)
261
262typedef struct _drm_mga_warp_index {
263 int installed;
264 unsigned long phys_addr;
265 int size;
266} drm_mga_warp_index_t;
267
268typedef struct drm_mga_init {
269 enum {
270 MGA_INIT_DMA = 0x01,
271 MGA_CLEANUP_DMA = 0x02
272 } func;
273
274 unsigned long sarea_priv_offset;
275
276 int chipset;
277 int sgram;
278
279 unsigned int maccess;
280
281 unsigned int fb_cpp;
282 unsigned int front_offset, front_pitch;
283 unsigned int back_offset, back_pitch;
284
285 unsigned int depth_cpp;
286 unsigned int depth_offset, depth_pitch;
287
288 unsigned int texture_offset[MGA_NR_TEX_HEAPS];
289 unsigned int texture_size[MGA_NR_TEX_HEAPS];
290
291 unsigned long fb_offset;
292 unsigned long mmio_offset;
293 unsigned long status_offset;
294 unsigned long warp_offset;
295 unsigned long primary_offset;
296 unsigned long buffers_offset;
297} drm_mga_init_t;
298
299typedef struct drm_mga_dma_bootstrap {
300 /**
301 * \name AGP texture region
302 *
303 * On return from the DRM_MGA_DMA_BOOTSTRAP ioctl, these fields will
304 * be filled in with the actual AGP texture settings.
305 *
306 * \warning
307 * If these fields are non-zero, but dma_mga_dma_bootstrap::agp_mode
308 * is zero, it means that PCI memory (most likely through the use of
309 * an IOMMU) is being used for "AGP" textures.
310 */
311 /*@{ */
312 unsigned long texture_handle; /**< Handle used to map AGP textures. */
313 uint32_t texture_size; /**< Size of the AGP texture region. */
314 /*@} */
315
316 /**
317 * Requested size of the primary DMA region.
318 *
319 * On return from the DRM_MGA_DMA_BOOTSTRAP ioctl, this field will be
320 * filled in with the actual AGP mode. If AGP was not available
321 */
322 uint32_t primary_size;
323
324 /**
325 * Requested number of secondary DMA buffers.
326 *
327 * On return from the DRM_MGA_DMA_BOOTSTRAP ioctl, this field will be
328 * filled in with the actual number of secondary DMA buffers
329 * allocated. Particularly when PCI DMA is used, this may be
330 * (subtantially) less than the number requested.
331 */
332 uint32_t secondary_bin_count;
333
334 /**
335 * Requested size of each secondary DMA buffer.
336 *
337 * While the kernel \b is free to reduce
338 * dma_mga_dma_bootstrap::secondary_bin_count, it is \b not allowed
339 * to reduce dma_mga_dma_bootstrap::secondary_bin_size.
340 */
341 uint32_t secondary_bin_size;
342
343 /**
344 * Bit-wise mask of AGPSTAT2_* values. Currently only \c AGPSTAT2_1X,
345 * \c AGPSTAT2_2X, and \c AGPSTAT2_4X are supported. If this value is
346 * zero, it means that PCI DMA should be used, even if AGP is
347 * possible.
348 *
349 * On return from the DRM_MGA_DMA_BOOTSTRAP ioctl, this field will be
350 * filled in with the actual AGP mode. If AGP was not available
351 * (i.e., PCI DMA was used), this value will be zero.
352 */
353 uint32_t agp_mode;
354
355 /**
356 * Desired AGP GART size, measured in megabytes.
357 */
358 uint8_t agp_size;
359} drm_mga_dma_bootstrap_t;
360
361typedef struct drm_mga_clear {
362 unsigned int flags;
363 unsigned int clear_color;
364 unsigned int clear_depth;
365 unsigned int color_mask;
366 unsigned int depth_mask;
367} drm_mga_clear_t;
368
369typedef struct drm_mga_vertex {
370 int idx; /* buffer to queue */
371 int used; /* bytes in use */
372 int discard; /* client finished with buffer? */
373} drm_mga_vertex_t;
374
375typedef struct drm_mga_indices {
376 int idx; /* buffer to queue */
377 unsigned int start;
378 unsigned int end;
379 int discard; /* client finished with buffer? */
380} drm_mga_indices_t;
381
382typedef struct drm_mga_iload {
383 int idx;
384 unsigned int dstorg;
385 unsigned int length;
386} drm_mga_iload_t;
387
388typedef struct _drm_mga_blit {
389 unsigned int planemask;
390 unsigned int srcorg;
391 unsigned int dstorg;
392 int src_pitch, dst_pitch;
393 int delta_sx, delta_sy;
394 int delta_dx, delta_dy;
395 int height, ydir; /* flip image vertically */
396 int source_pitch, dest_pitch;
397} drm_mga_blit_t;
398
399/* 3.1: An ioctl to get parameters that aren't available to the 3d
400 * client any other way.
401 */
402#define MGA_PARAM_IRQ_NR 1
403
404/* 3.2: Query the actual card type. The DDX only distinguishes between
405 * G200 chips and non-G200 chips, which it calls G400. It turns out that
406 * there are some very sublte differences between the G4x0 chips and the G550
407 * chips. Using this parameter query, a client-side driver can detect the
408 * difference between a G4x0 and a G550.
409 */
410#define MGA_PARAM_CARD_TYPE 2
411
412typedef struct drm_mga_getparam {
413 int param;
414 void __user *value;
415} drm_mga_getparam_t;
416
417#endif
diff --git a/drivers/char/drm/mga_drv.c b/drivers/char/drm/mga_drv.c
deleted file mode 100644
index 6b3790939e76..000000000000
--- a/drivers/char/drm/mga_drv.c
+++ /dev/null
@@ -1,142 +0,0 @@
1/* mga_drv.c -- Matrox G200/G400 driver -*- linux-c -*-
2 * Created: Mon Dec 13 01:56:22 1999 by jhartmann@precisioninsight.com
3 *
4 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
5 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
6 * All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice (including the next
16 * paragraph) shall be included in all copies or substantial portions of the
17 * Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
23 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25 * OTHER DEALINGS IN THE SOFTWARE.
26 *
27 * Authors:
28 * Rickard E. (Rik) Faith <faith@valinux.com>
29 * Gareth Hughes <gareth@valinux.com>
30 */
31
32#include "drmP.h"
33#include "drm.h"
34#include "mga_drm.h"
35#include "mga_drv.h"
36
37#include "drm_pciids.h"
38
39static int mga_driver_device_is_agp(struct drm_device * dev);
40
41static struct pci_device_id pciidlist[] = {
42 mga_PCI_IDS
43};
44
45static struct drm_driver driver = {
46 .driver_features =
47 DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA |
48 DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED,
49 .dev_priv_size = sizeof(drm_mga_buf_priv_t),
50 .load = mga_driver_load,
51 .unload = mga_driver_unload,
52 .lastclose = mga_driver_lastclose,
53 .dma_quiescent = mga_driver_dma_quiescent,
54 .device_is_agp = mga_driver_device_is_agp,
55 .get_vblank_counter = mga_get_vblank_counter,
56 .enable_vblank = mga_enable_vblank,
57 .disable_vblank = mga_disable_vblank,
58 .irq_preinstall = mga_driver_irq_preinstall,
59 .irq_postinstall = mga_driver_irq_postinstall,
60 .irq_uninstall = mga_driver_irq_uninstall,
61 .irq_handler = mga_driver_irq_handler,
62 .reclaim_buffers = drm_core_reclaim_buffers,
63 .get_map_ofs = drm_core_get_map_ofs,
64 .get_reg_ofs = drm_core_get_reg_ofs,
65 .ioctls = mga_ioctls,
66 .dma_ioctl = mga_dma_buffers,
67 .fops = {
68 .owner = THIS_MODULE,
69 .open = drm_open,
70 .release = drm_release,
71 .ioctl = drm_ioctl,
72 .mmap = drm_mmap,
73 .poll = drm_poll,
74 .fasync = drm_fasync,
75#ifdef CONFIG_COMPAT
76 .compat_ioctl = mga_compat_ioctl,
77#endif
78 },
79 .pci_driver = {
80 .name = DRIVER_NAME,
81 .id_table = pciidlist,
82 },
83
84 .name = DRIVER_NAME,
85 .desc = DRIVER_DESC,
86 .date = DRIVER_DATE,
87 .major = DRIVER_MAJOR,
88 .minor = DRIVER_MINOR,
89 .patchlevel = DRIVER_PATCHLEVEL,
90};
91
92static int __init mga_init(void)
93{
94 driver.num_ioctls = mga_max_ioctl;
95 return drm_init(&driver);
96}
97
98static void __exit mga_exit(void)
99{
100 drm_exit(&driver);
101}
102
103module_init(mga_init);
104module_exit(mga_exit);
105
106MODULE_AUTHOR(DRIVER_AUTHOR);
107MODULE_DESCRIPTION(DRIVER_DESC);
108MODULE_LICENSE("GPL and additional rights");
109
110/**
111 * Determine if the device really is AGP or not.
112 *
113 * In addition to the usual tests performed by \c drm_device_is_agp, this
114 * function detects PCI G450 cards that appear to the system exactly like
115 * AGP G450 cards.
116 *
117 * \param dev The device to be tested.
118 *
119 * \returns
120 * If the device is a PCI G450, zero is returned. Otherwise 2 is returned.
121 */
122static int mga_driver_device_is_agp(struct drm_device * dev)
123{
124 const struct pci_dev *const pdev = dev->pdev;
125
126 /* There are PCI versions of the G450. These cards have the
127 * same PCI ID as the AGP G450, but have an additional PCI-to-PCI
128 * bridge chip. We detect these cards, which are not currently
129 * supported by this driver, by looking at the device ID of the
130 * bus the "card" is on. If vendor is 0x3388 (Hint Corp) and the
131 * device is 0x0021 (HB6 Universal PCI-PCI bridge), we reject the
132 * device.
133 */
134
135 if ((pdev->device == 0x0525) && pdev->bus->self
136 && (pdev->bus->self->vendor == 0x3388)
137 && (pdev->bus->self->device == 0x0021)) {
138 return 0;
139 }
140
141 return 2;
142}
diff --git a/drivers/char/drm/mga_drv.h b/drivers/char/drm/mga_drv.h
deleted file mode 100644
index 8f7291f36363..000000000000
--- a/drivers/char/drm/mga_drv.h
+++ /dev/null
@@ -1,691 +0,0 @@
1/* mga_drv.h -- Private header for the Matrox G200/G400 driver -*- linux-c -*-
2 * Created: Mon Dec 13 01:50:01 1999 by jhartmann@precisioninsight.com
3 *
4 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
5 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
6 * All rights reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice (including the next
16 * paragraph) shall be included in all copies or substantial portions of the
17 * Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
23 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25 * OTHER DEALINGS IN THE SOFTWARE.
26 *
27 * Authors:
28 * Gareth Hughes <gareth@valinux.com>
29 */
30
31#ifndef __MGA_DRV_H__
32#define __MGA_DRV_H__
33
34/* General customization:
35 */
36
37#define DRIVER_AUTHOR "Gareth Hughes, VA Linux Systems Inc."
38
39#define DRIVER_NAME "mga"
40#define DRIVER_DESC "Matrox G200/G400"
41#define DRIVER_DATE "20051102"
42
43#define DRIVER_MAJOR 3
44#define DRIVER_MINOR 2
45#define DRIVER_PATCHLEVEL 1
46
47typedef struct drm_mga_primary_buffer {
48 u8 *start;
49 u8 *end;
50 int size;
51
52 u32 tail;
53 int space;
54 volatile long wrapped;
55
56 volatile u32 *status;
57
58 u32 last_flush;
59 u32 last_wrap;
60
61 u32 high_mark;
62} drm_mga_primary_buffer_t;
63
64typedef struct drm_mga_freelist {
65 struct drm_mga_freelist *next;
66 struct drm_mga_freelist *prev;
67 drm_mga_age_t age;
68 struct drm_buf *buf;
69} drm_mga_freelist_t;
70
71typedef struct {
72 drm_mga_freelist_t *list_entry;
73 int discard;
74 int dispatched;
75} drm_mga_buf_priv_t;
76
77typedef struct drm_mga_private {
78 drm_mga_primary_buffer_t prim;
79 drm_mga_sarea_t *sarea_priv;
80
81 drm_mga_freelist_t *head;
82 drm_mga_freelist_t *tail;
83
84 unsigned int warp_pipe;
85 unsigned long warp_pipe_phys[MGA_MAX_WARP_PIPES];
86
87 int chipset;
88 int usec_timeout;
89
90 /**
91 * If set, the new DMA initialization sequence was used. This is
92 * primarilly used to select how the driver should uninitialized its
93 * internal DMA structures.
94 */
95 int used_new_dma_init;
96
97 /**
98 * If AGP memory is used for DMA buffers, this will be the value
99 * \c MGA_PAGPXFER. Otherwise, it will be zero (for a PCI transfer).
100 */
101 u32 dma_access;
102
103 /**
104 * If AGP memory is used for DMA buffers, this will be the value
105 * \c MGA_WAGP_ENABLE. Otherwise, it will be zero (for a PCI
106 * transfer).
107 */
108 u32 wagp_enable;
109
110 /**
111 * \name MMIO region parameters.
112 *
113 * \sa drm_mga_private_t::mmio
114 */
115 /*@{ */
116 u32 mmio_base; /**< Bus address of base of MMIO. */
117 u32 mmio_size; /**< Size of the MMIO region. */
118 /*@} */
119
120 u32 clear_cmd;
121 u32 maccess;
122
123 atomic_t vbl_received; /**< Number of vblanks received. */
124 wait_queue_head_t fence_queue;
125 atomic_t last_fence_retired;
126 u32 next_fence_to_post;
127
128 unsigned int fb_cpp;
129 unsigned int front_offset;
130 unsigned int front_pitch;
131 unsigned int back_offset;
132 unsigned int back_pitch;
133
134 unsigned int depth_cpp;
135 unsigned int depth_offset;
136 unsigned int depth_pitch;
137
138 unsigned int texture_offset;
139 unsigned int texture_size;
140
141 drm_local_map_t *sarea;
142 drm_local_map_t *mmio;
143 drm_local_map_t *status;
144 drm_local_map_t *warp;
145 drm_local_map_t *primary;
146 drm_local_map_t *agp_textures;
147
148 unsigned long agp_handle;
149 unsigned int agp_size;
150} drm_mga_private_t;
151
152extern struct drm_ioctl_desc mga_ioctls[];
153extern int mga_max_ioctl;
154
155 /* mga_dma.c */
156extern int mga_dma_bootstrap(struct drm_device *dev, void *data,
157 struct drm_file *file_priv);
158extern int mga_dma_init(struct drm_device *dev, void *data,
159 struct drm_file *file_priv);
160extern int mga_dma_flush(struct drm_device *dev, void *data,
161 struct drm_file *file_priv);
162extern int mga_dma_reset(struct drm_device *dev, void *data,
163 struct drm_file *file_priv);
164extern int mga_dma_buffers(struct drm_device *dev, void *data,
165 struct drm_file *file_priv);
166extern int mga_driver_load(struct drm_device *dev, unsigned long flags);
167extern int mga_driver_unload(struct drm_device * dev);
168extern void mga_driver_lastclose(struct drm_device * dev);
169extern int mga_driver_dma_quiescent(struct drm_device * dev);
170
171extern int mga_do_wait_for_idle(drm_mga_private_t * dev_priv);
172
173extern void mga_do_dma_flush(drm_mga_private_t * dev_priv);
174extern void mga_do_dma_wrap_start(drm_mga_private_t * dev_priv);
175extern void mga_do_dma_wrap_end(drm_mga_private_t * dev_priv);
176
177extern int mga_freelist_put(struct drm_device * dev, struct drm_buf * buf);
178
179 /* mga_warp.c */
180extern unsigned int mga_warp_microcode_size(const drm_mga_private_t * dev_priv);
181extern int mga_warp_install_microcode(drm_mga_private_t * dev_priv);
182extern int mga_warp_init(drm_mga_private_t * dev_priv);
183
184 /* mga_irq.c */
185extern int mga_enable_vblank(struct drm_device *dev, int crtc);
186extern void mga_disable_vblank(struct drm_device *dev, int crtc);
187extern u32 mga_get_vblank_counter(struct drm_device *dev, int crtc);
188extern int mga_driver_fence_wait(struct drm_device * dev, unsigned int *sequence);
189extern int mga_driver_vblank_wait(struct drm_device * dev, unsigned int *sequence);
190extern irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS);
191extern void mga_driver_irq_preinstall(struct drm_device * dev);
192extern int mga_driver_irq_postinstall(struct drm_device * dev);
193extern void mga_driver_irq_uninstall(struct drm_device * dev);
194extern long mga_compat_ioctl(struct file *filp, unsigned int cmd,
195 unsigned long arg);
196
197#define mga_flush_write_combine() DRM_WRITEMEMORYBARRIER()
198
199#if defined(__linux__) && defined(__alpha__)
200#define MGA_BASE( reg ) ((unsigned long)(dev_priv->mmio->handle))
201#define MGA_ADDR( reg ) (MGA_BASE(reg) + reg)
202
203#define MGA_DEREF( reg ) *(volatile u32 *)MGA_ADDR( reg )
204#define MGA_DEREF8( reg ) *(volatile u8 *)MGA_ADDR( reg )
205
206#define MGA_READ( reg ) (_MGA_READ((u32 *)MGA_ADDR(reg)))
207#define MGA_READ8( reg ) (_MGA_READ((u8 *)MGA_ADDR(reg)))
208#define MGA_WRITE( reg, val ) do { DRM_WRITEMEMORYBARRIER(); MGA_DEREF( reg ) = val; } while (0)
209#define MGA_WRITE8( reg, val ) do { DRM_WRITEMEMORYBARRIER(); MGA_DEREF8( reg ) = val; } while (0)
210
211static inline u32 _MGA_READ(u32 * addr)
212{
213 DRM_MEMORYBARRIER();
214 return *(volatile u32 *)addr;
215}
216#else
217#define MGA_READ8( reg ) DRM_READ8(dev_priv->mmio, (reg))
218#define MGA_READ( reg ) DRM_READ32(dev_priv->mmio, (reg))
219#define MGA_WRITE8( reg, val ) DRM_WRITE8(dev_priv->mmio, (reg), (val))
220#define MGA_WRITE( reg, val ) DRM_WRITE32(dev_priv->mmio, (reg), (val))
221#endif
222
223#define DWGREG0 0x1c00
224#define DWGREG0_END 0x1dff
225#define DWGREG1 0x2c00
226#define DWGREG1_END 0x2dff
227
228#define ISREG0(r) (r >= DWGREG0 && r <= DWGREG0_END)
229#define DMAREG0(r) (u8)((r - DWGREG0) >> 2)
230#define DMAREG1(r) (u8)(((r - DWGREG1) >> 2) | 0x80)
231#define DMAREG(r) (ISREG0(r) ? DMAREG0(r) : DMAREG1(r))
232
233/* ================================================================
234 * Helper macross...
235 */
236
237#define MGA_EMIT_STATE( dev_priv, dirty ) \
238do { \
239 if ( (dirty) & ~MGA_UPLOAD_CLIPRECTS ) { \
240 if ( dev_priv->chipset >= MGA_CARD_TYPE_G400 ) { \
241 mga_g400_emit_state( dev_priv ); \
242 } else { \
243 mga_g200_emit_state( dev_priv ); \
244 } \
245 } \
246} while (0)
247
248#define WRAP_TEST_WITH_RETURN( dev_priv ) \
249do { \
250 if ( test_bit( 0, &dev_priv->prim.wrapped ) ) { \
251 if ( mga_is_idle( dev_priv ) ) { \
252 mga_do_dma_wrap_end( dev_priv ); \
253 } else if ( dev_priv->prim.space < \
254 dev_priv->prim.high_mark ) { \
255 if ( MGA_DMA_DEBUG ) \
256 DRM_INFO( "wrap...\n"); \
257 return -EBUSY; \
258 } \
259 } \
260} while (0)
261
262#define WRAP_WAIT_WITH_RETURN( dev_priv ) \
263do { \
264 if ( test_bit( 0, &dev_priv->prim.wrapped ) ) { \
265 if ( mga_do_wait_for_idle( dev_priv ) < 0 ) { \
266 if ( MGA_DMA_DEBUG ) \
267 DRM_INFO( "wrap...\n"); \
268 return -EBUSY; \
269 } \
270 mga_do_dma_wrap_end( dev_priv ); \
271 } \
272} while (0)
273
274/* ================================================================
275 * Primary DMA command stream
276 */
277
278#define MGA_VERBOSE 0
279
280#define DMA_LOCALS unsigned int write; volatile u8 *prim;
281
282#define DMA_BLOCK_SIZE (5 * sizeof(u32))
283
284#define BEGIN_DMA( n ) \
285do { \
286 if ( MGA_VERBOSE ) { \
287 DRM_INFO( "BEGIN_DMA( %d )\n", (n) ); \
288 DRM_INFO( " space=0x%x req=0x%Zx\n", \
289 dev_priv->prim.space, (n) * DMA_BLOCK_SIZE ); \
290 } \
291 prim = dev_priv->prim.start; \
292 write = dev_priv->prim.tail; \
293} while (0)
294
295#define BEGIN_DMA_WRAP() \
296do { \
297 if ( MGA_VERBOSE ) { \
298 DRM_INFO( "BEGIN_DMA()\n" ); \
299 DRM_INFO( " space=0x%x\n", dev_priv->prim.space ); \
300 } \
301 prim = dev_priv->prim.start; \
302 write = dev_priv->prim.tail; \
303} while (0)
304
305#define ADVANCE_DMA() \
306do { \
307 dev_priv->prim.tail = write; \
308 if ( MGA_VERBOSE ) { \
309 DRM_INFO( "ADVANCE_DMA() tail=0x%05x sp=0x%x\n", \
310 write, dev_priv->prim.space ); \
311 } \
312} while (0)
313
314#define FLUSH_DMA() \
315do { \
316 if ( 0 ) { \
317 DRM_INFO( "\n" ); \
318 DRM_INFO( " tail=0x%06x head=0x%06lx\n", \
319 dev_priv->prim.tail, \
320 MGA_READ( MGA_PRIMADDRESS ) - \
321 dev_priv->primary->offset ); \
322 } \
323 if ( !test_bit( 0, &dev_priv->prim.wrapped ) ) { \
324 if ( dev_priv->prim.space < \
325 dev_priv->prim.high_mark ) { \
326 mga_do_dma_wrap_start( dev_priv ); \
327 } else { \
328 mga_do_dma_flush( dev_priv ); \
329 } \
330 } \
331} while (0)
332
333/* Never use this, always use DMA_BLOCK(...) for primary DMA output.
334 */
335#define DMA_WRITE( offset, val ) \
336do { \
337 if ( MGA_VERBOSE ) { \
338 DRM_INFO( " DMA_WRITE( 0x%08x ) at 0x%04Zx\n", \
339 (u32)(val), write + (offset) * sizeof(u32) ); \
340 } \
341 *(volatile u32 *)(prim + write + (offset) * sizeof(u32)) = val; \
342} while (0)
343
344#define DMA_BLOCK( reg0, val0, reg1, val1, reg2, val2, reg3, val3 ) \
345do { \
346 DMA_WRITE( 0, ((DMAREG( reg0 ) << 0) | \
347 (DMAREG( reg1 ) << 8) | \
348 (DMAREG( reg2 ) << 16) | \
349 (DMAREG( reg3 ) << 24)) ); \
350 DMA_WRITE( 1, val0 ); \
351 DMA_WRITE( 2, val1 ); \
352 DMA_WRITE( 3, val2 ); \
353 DMA_WRITE( 4, val3 ); \
354 write += DMA_BLOCK_SIZE; \
355} while (0)
356
357/* Buffer aging via primary DMA stream head pointer.
358 */
359
360#define SET_AGE( age, h, w ) \
361do { \
362 (age)->head = h; \
363 (age)->wrap = w; \
364} while (0)
365
366#define TEST_AGE( age, h, w ) ( (age)->wrap < w || \
367 ( (age)->wrap == w && \
368 (age)->head < h ) )
369
370#define AGE_BUFFER( buf_priv ) \
371do { \
372 drm_mga_freelist_t *entry = (buf_priv)->list_entry; \
373 if ( (buf_priv)->dispatched ) { \
374 entry->age.head = (dev_priv->prim.tail + \
375 dev_priv->primary->offset); \
376 entry->age.wrap = dev_priv->sarea_priv->last_wrap; \
377 } else { \
378 entry->age.head = 0; \
379 entry->age.wrap = 0; \
380 } \
381} while (0)
382
383#define MGA_ENGINE_IDLE_MASK (MGA_SOFTRAPEN | \
384 MGA_DWGENGSTS | \
385 MGA_ENDPRDMASTS)
386#define MGA_DMA_IDLE_MASK (MGA_SOFTRAPEN | \
387 MGA_ENDPRDMASTS)
388
389#define MGA_DMA_DEBUG 0
390
391/* A reduced set of the mga registers.
392 */
393#define MGA_CRTC_INDEX 0x1fd4
394#define MGA_CRTC_DATA 0x1fd5
395
396/* CRTC11 */
397#define MGA_VINTCLR (1 << 4)
398#define MGA_VINTEN (1 << 5)
399
400#define MGA_ALPHACTRL 0x2c7c
401#define MGA_AR0 0x1c60
402#define MGA_AR1 0x1c64
403#define MGA_AR2 0x1c68
404#define MGA_AR3 0x1c6c
405#define MGA_AR4 0x1c70
406#define MGA_AR5 0x1c74
407#define MGA_AR6 0x1c78
408
409#define MGA_CXBNDRY 0x1c80
410#define MGA_CXLEFT 0x1ca0
411#define MGA_CXRIGHT 0x1ca4
412
413#define MGA_DMAPAD 0x1c54
414#define MGA_DSTORG 0x2cb8
415#define MGA_DWGCTL 0x1c00
416# define MGA_OPCOD_MASK (15 << 0)
417# define MGA_OPCOD_TRAP (4 << 0)
418# define MGA_OPCOD_TEXTURE_TRAP (6 << 0)
419# define MGA_OPCOD_BITBLT (8 << 0)
420# define MGA_OPCOD_ILOAD (9 << 0)
421# define MGA_ATYPE_MASK (7 << 4)
422# define MGA_ATYPE_RPL (0 << 4)
423# define MGA_ATYPE_RSTR (1 << 4)
424# define MGA_ATYPE_ZI (3 << 4)
425# define MGA_ATYPE_BLK (4 << 4)
426# define MGA_ATYPE_I (7 << 4)
427# define MGA_LINEAR (1 << 7)
428# define MGA_ZMODE_MASK (7 << 8)
429# define MGA_ZMODE_NOZCMP (0 << 8)
430# define MGA_ZMODE_ZE (2 << 8)
431# define MGA_ZMODE_ZNE (3 << 8)
432# define MGA_ZMODE_ZLT (4 << 8)
433# define MGA_ZMODE_ZLTE (5 << 8)
434# define MGA_ZMODE_ZGT (6 << 8)
435# define MGA_ZMODE_ZGTE (7 << 8)
436# define MGA_SOLID (1 << 11)
437# define MGA_ARZERO (1 << 12)
438# define MGA_SGNZERO (1 << 13)
439# define MGA_SHIFTZERO (1 << 14)
440# define MGA_BOP_MASK (15 << 16)
441# define MGA_BOP_ZERO (0 << 16)
442# define MGA_BOP_DST (10 << 16)
443# define MGA_BOP_SRC (12 << 16)
444# define MGA_BOP_ONE (15 << 16)
445# define MGA_TRANS_SHIFT 20
446# define MGA_TRANS_MASK (15 << 20)
447# define MGA_BLTMOD_MASK (15 << 25)
448# define MGA_BLTMOD_BMONOLEF (0 << 25)
449# define MGA_BLTMOD_BMONOWF (4 << 25)
450# define MGA_BLTMOD_PLAN (1 << 25)
451# define MGA_BLTMOD_BFCOL (2 << 25)
452# define MGA_BLTMOD_BU32BGR (3 << 25)
453# define MGA_BLTMOD_BU32RGB (7 << 25)
454# define MGA_BLTMOD_BU24BGR (11 << 25)
455# define MGA_BLTMOD_BU24RGB (15 << 25)
456# define MGA_PATTERN (1 << 29)
457# define MGA_TRANSC (1 << 30)
458# define MGA_CLIPDIS (1 << 31)
459#define MGA_DWGSYNC 0x2c4c
460
461#define MGA_FCOL 0x1c24
462#define MGA_FIFOSTATUS 0x1e10
463#define MGA_FOGCOL 0x1cf4
464#define MGA_FXBNDRY 0x1c84
465#define MGA_FXLEFT 0x1ca8
466#define MGA_FXRIGHT 0x1cac
467
468#define MGA_ICLEAR 0x1e18
469# define MGA_SOFTRAPICLR (1 << 0)
470# define MGA_VLINEICLR (1 << 5)
471#define MGA_IEN 0x1e1c
472# define MGA_SOFTRAPIEN (1 << 0)
473# define MGA_VLINEIEN (1 << 5)
474
475#define MGA_LEN 0x1c5c
476
477#define MGA_MACCESS 0x1c04
478
479#define MGA_PITCH 0x1c8c
480#define MGA_PLNWT 0x1c1c
481#define MGA_PRIMADDRESS 0x1e58
482# define MGA_DMA_GENERAL (0 << 0)
483# define MGA_DMA_BLIT (1 << 0)
484# define MGA_DMA_VECTOR (2 << 0)
485# define MGA_DMA_VERTEX (3 << 0)
486#define MGA_PRIMEND 0x1e5c
487# define MGA_PRIMNOSTART (1 << 0)
488# define MGA_PAGPXFER (1 << 1)
489#define MGA_PRIMPTR 0x1e50
490# define MGA_PRIMPTREN0 (1 << 0)
491# define MGA_PRIMPTREN1 (1 << 1)
492
493#define MGA_RST 0x1e40
494# define MGA_SOFTRESET (1 << 0)
495# define MGA_SOFTEXTRST (1 << 1)
496
497#define MGA_SECADDRESS 0x2c40
498#define MGA_SECEND 0x2c44
499#define MGA_SETUPADDRESS 0x2cd0
500#define MGA_SETUPEND 0x2cd4
501#define MGA_SGN 0x1c58
502#define MGA_SOFTRAP 0x2c48
503#define MGA_SRCORG 0x2cb4
504# define MGA_SRMMAP_MASK (1 << 0)
505# define MGA_SRCMAP_FB (0 << 0)
506# define MGA_SRCMAP_SYSMEM (1 << 0)
507# define MGA_SRCACC_MASK (1 << 1)
508# define MGA_SRCACC_PCI (0 << 1)
509# define MGA_SRCACC_AGP (1 << 1)
510#define MGA_STATUS 0x1e14
511# define MGA_SOFTRAPEN (1 << 0)
512# define MGA_VSYNCPEN (1 << 4)
513# define MGA_VLINEPEN (1 << 5)
514# define MGA_DWGENGSTS (1 << 16)
515# define MGA_ENDPRDMASTS (1 << 17)
516#define MGA_STENCIL 0x2cc8
517#define MGA_STENCILCTL 0x2ccc
518
519#define MGA_TDUALSTAGE0 0x2cf8
520#define MGA_TDUALSTAGE1 0x2cfc
521#define MGA_TEXBORDERCOL 0x2c5c
522#define MGA_TEXCTL 0x2c30
523#define MGA_TEXCTL2 0x2c3c
524# define MGA_DUALTEX (1 << 7)
525# define MGA_G400_TC2_MAGIC (1 << 15)
526# define MGA_MAP1_ENABLE (1 << 31)
527#define MGA_TEXFILTER 0x2c58
528#define MGA_TEXHEIGHT 0x2c2c
529#define MGA_TEXORG 0x2c24
530# define MGA_TEXORGMAP_MASK (1 << 0)
531# define MGA_TEXORGMAP_FB (0 << 0)
532# define MGA_TEXORGMAP_SYSMEM (1 << 0)
533# define MGA_TEXORGACC_MASK (1 << 1)
534# define MGA_TEXORGACC_PCI (0 << 1)
535# define MGA_TEXORGACC_AGP (1 << 1)
536#define MGA_TEXORG1 0x2ca4
537#define MGA_TEXORG2 0x2ca8
538#define MGA_TEXORG3 0x2cac
539#define MGA_TEXORG4 0x2cb0
540#define MGA_TEXTRANS 0x2c34
541#define MGA_TEXTRANSHIGH 0x2c38
542#define MGA_TEXWIDTH 0x2c28
543
544#define MGA_WACCEPTSEQ 0x1dd4
545#define MGA_WCODEADDR 0x1e6c
546#define MGA_WFLAG 0x1dc4
547#define MGA_WFLAG1 0x1de0
548#define MGA_WFLAGNB 0x1e64
549#define MGA_WFLAGNB1 0x1e08
550#define MGA_WGETMSB 0x1dc8
551#define MGA_WIADDR 0x1dc0
552#define MGA_WIADDR2 0x1dd8
553# define MGA_WMODE_SUSPEND (0 << 0)
554# define MGA_WMODE_RESUME (1 << 0)
555# define MGA_WMODE_JUMP (2 << 0)
556# define MGA_WMODE_START (3 << 0)
557# define MGA_WAGP_ENABLE (1 << 2)
558#define MGA_WMISC 0x1e70
559# define MGA_WUCODECACHE_ENABLE (1 << 0)
560# define MGA_WMASTER_ENABLE (1 << 1)
561# define MGA_WCACHEFLUSH_ENABLE (1 << 3)
562#define MGA_WVRTXSZ 0x1dcc
563
564#define MGA_YBOT 0x1c9c
565#define MGA_YDST 0x1c90
566#define MGA_YDSTLEN 0x1c88
567#define MGA_YDSTORG 0x1c94
568#define MGA_YTOP 0x1c98
569
570#define MGA_ZORG 0x1c0c
571
572/* This finishes the current batch of commands
573 */
574#define MGA_EXEC 0x0100
575
576/* AGP PLL encoding (for G200 only).
577 */
578#define MGA_AGP_PLL 0x1e4c
579# define MGA_AGP2XPLL_DISABLE (0 << 0)
580# define MGA_AGP2XPLL_ENABLE (1 << 0)
581
582/* Warp registers
583 */
584#define MGA_WR0 0x2d00
585#define MGA_WR1 0x2d04
586#define MGA_WR2 0x2d08
587#define MGA_WR3 0x2d0c
588#define MGA_WR4 0x2d10
589#define MGA_WR5 0x2d14
590#define MGA_WR6 0x2d18
591#define MGA_WR7 0x2d1c
592#define MGA_WR8 0x2d20
593#define MGA_WR9 0x2d24
594#define MGA_WR10 0x2d28
595#define MGA_WR11 0x2d2c
596#define MGA_WR12 0x2d30
597#define MGA_WR13 0x2d34
598#define MGA_WR14 0x2d38
599#define MGA_WR15 0x2d3c
600#define MGA_WR16 0x2d40
601#define MGA_WR17 0x2d44
602#define MGA_WR18 0x2d48
603#define MGA_WR19 0x2d4c
604#define MGA_WR20 0x2d50
605#define MGA_WR21 0x2d54
606#define MGA_WR22 0x2d58
607#define MGA_WR23 0x2d5c
608#define MGA_WR24 0x2d60
609#define MGA_WR25 0x2d64
610#define MGA_WR26 0x2d68
611#define MGA_WR27 0x2d6c
612#define MGA_WR28 0x2d70
613#define MGA_WR29 0x2d74
614#define MGA_WR30 0x2d78
615#define MGA_WR31 0x2d7c
616#define MGA_WR32 0x2d80
617#define MGA_WR33 0x2d84
618#define MGA_WR34 0x2d88
619#define MGA_WR35 0x2d8c
620#define MGA_WR36 0x2d90
621#define MGA_WR37 0x2d94
622#define MGA_WR38 0x2d98
623#define MGA_WR39 0x2d9c
624#define MGA_WR40 0x2da0
625#define MGA_WR41 0x2da4
626#define MGA_WR42 0x2da8
627#define MGA_WR43 0x2dac
628#define MGA_WR44 0x2db0
629#define MGA_WR45 0x2db4
630#define MGA_WR46 0x2db8
631#define MGA_WR47 0x2dbc
632#define MGA_WR48 0x2dc0
633#define MGA_WR49 0x2dc4
634#define MGA_WR50 0x2dc8
635#define MGA_WR51 0x2dcc
636#define MGA_WR52 0x2dd0
637#define MGA_WR53 0x2dd4
638#define MGA_WR54 0x2dd8
639#define MGA_WR55 0x2ddc
640#define MGA_WR56 0x2de0
641#define MGA_WR57 0x2de4
642#define MGA_WR58 0x2de8
643#define MGA_WR59 0x2dec
644#define MGA_WR60 0x2df0
645#define MGA_WR61 0x2df4
646#define MGA_WR62 0x2df8
647#define MGA_WR63 0x2dfc
648# define MGA_G400_WR_MAGIC (1 << 6)
649# define MGA_G400_WR56_MAGIC 0x46480000 /* 12800.0f */
650
651#define MGA_ILOAD_ALIGN 64
652#define MGA_ILOAD_MASK (MGA_ILOAD_ALIGN - 1)
653
654#define MGA_DWGCTL_FLUSH (MGA_OPCOD_TEXTURE_TRAP | \
655 MGA_ATYPE_I | \
656 MGA_ZMODE_NOZCMP | \
657 MGA_ARZERO | \
658 MGA_SGNZERO | \
659 MGA_BOP_SRC | \
660 (15 << MGA_TRANS_SHIFT))
661
662#define MGA_DWGCTL_CLEAR (MGA_OPCOD_TRAP | \
663 MGA_ZMODE_NOZCMP | \
664 MGA_SOLID | \
665 MGA_ARZERO | \
666 MGA_SGNZERO | \
667 MGA_SHIFTZERO | \
668 MGA_BOP_SRC | \
669 (0 << MGA_TRANS_SHIFT) | \
670 MGA_BLTMOD_BMONOLEF | \
671 MGA_TRANSC | \
672 MGA_CLIPDIS)
673
674#define MGA_DWGCTL_COPY (MGA_OPCOD_BITBLT | \
675 MGA_ATYPE_RPL | \
676 MGA_SGNZERO | \
677 MGA_SHIFTZERO | \
678 MGA_BOP_SRC | \
679 (0 << MGA_TRANS_SHIFT) | \
680 MGA_BLTMOD_BFCOL | \
681 MGA_CLIPDIS)
682
683/* Simple idle test.
684 */
685static __inline__ int mga_is_idle(drm_mga_private_t * dev_priv)
686{
687 u32 status = MGA_READ(MGA_STATUS) & MGA_ENGINE_IDLE_MASK;
688 return (status == MGA_ENDPRDMASTS);
689}
690
691#endif
diff --git a/drivers/char/drm/mga_ioc32.c b/drivers/char/drm/mga_ioc32.c
deleted file mode 100644
index 30d00478ddee..000000000000
--- a/drivers/char/drm/mga_ioc32.c
+++ /dev/null
@@ -1,231 +0,0 @@
1/**
2 * \file mga_ioc32.c
3 *
4 * 32-bit ioctl compatibility routines for the MGA DRM.
5 *
6 * \author Dave Airlie <airlied@linux.ie> with code from patches by Egbert Eich
7 *
8 *
9 * Copyright (C) Paul Mackerras 2005
10 * Copyright (C) Egbert Eich 2003,2004
11 * Copyright (C) Dave Airlie 2005
12 * All Rights Reserved.
13 *
14 * Permission is hereby granted, free of charge, to any person obtaining a
15 * copy of this software and associated documentation files (the "Software"),
16 * to deal in the Software without restriction, including without limitation
17 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
18 * and/or sell copies of the Software, and to permit persons to whom the
19 * Software is furnished to do so, subject to the following conditions:
20 *
21 * The above copyright notice and this permission notice (including the next
22 * paragraph) shall be included in all copies or substantial portions of the
23 * Software.
24 *
25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
26 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
27 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
28 * THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
29 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
30 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
31 * IN THE SOFTWARE.
32 */
33#include <linux/compat.h>
34
35#include "drmP.h"
36#include "drm.h"
37#include "mga_drm.h"
38
39typedef struct drm32_mga_init {
40 int func;
41 u32 sarea_priv_offset;
42 int chipset;
43 int sgram;
44 unsigned int maccess;
45 unsigned int fb_cpp;
46 unsigned int front_offset, front_pitch;
47 unsigned int back_offset, back_pitch;
48 unsigned int depth_cpp;
49 unsigned int depth_offset, depth_pitch;
50 unsigned int texture_offset[MGA_NR_TEX_HEAPS];
51 unsigned int texture_size[MGA_NR_TEX_HEAPS];
52 u32 fb_offset;
53 u32 mmio_offset;
54 u32 status_offset;
55 u32 warp_offset;
56 u32 primary_offset;
57 u32 buffers_offset;
58} drm_mga_init32_t;
59
60static int compat_mga_init(struct file *file, unsigned int cmd,
61 unsigned long arg)
62{
63 drm_mga_init32_t init32;
64 drm_mga_init_t __user *init;
65 int err = 0, i;
66
67 if (copy_from_user(&init32, (void __user *)arg, sizeof(init32)))
68 return -EFAULT;
69
70 init = compat_alloc_user_space(sizeof(*init));
71 if (!access_ok(VERIFY_WRITE, init, sizeof(*init))
72 || __put_user(init32.func, &init->func)
73 || __put_user(init32.sarea_priv_offset, &init->sarea_priv_offset)
74 || __put_user(init32.chipset, &init->chipset)
75 || __put_user(init32.sgram, &init->sgram)
76 || __put_user(init32.maccess, &init->maccess)
77 || __put_user(init32.fb_cpp, &init->fb_cpp)
78 || __put_user(init32.front_offset, &init->front_offset)
79 || __put_user(init32.front_pitch, &init->front_pitch)
80 || __put_user(init32.back_offset, &init->back_offset)
81 || __put_user(init32.back_pitch, &init->back_pitch)
82 || __put_user(init32.depth_cpp, &init->depth_cpp)
83 || __put_user(init32.depth_offset, &init->depth_offset)
84 || __put_user(init32.depth_pitch, &init->depth_pitch)
85 || __put_user(init32.fb_offset, &init->fb_offset)
86 || __put_user(init32.mmio_offset, &init->mmio_offset)
87 || __put_user(init32.status_offset, &init->status_offset)
88 || __put_user(init32.warp_offset, &init->warp_offset)
89 || __put_user(init32.primary_offset, &init->primary_offset)
90 || __put_user(init32.buffers_offset, &init->buffers_offset))
91 return -EFAULT;
92
93 for (i = 0; i < MGA_NR_TEX_HEAPS; i++) {
94 err |=
95 __put_user(init32.texture_offset[i],
96 &init->texture_offset[i]);
97 err |=
98 __put_user(init32.texture_size[i], &init->texture_size[i]);
99 }
100 if (err)
101 return -EFAULT;
102
103 return drm_ioctl(file->f_path.dentry->d_inode, file,
104 DRM_IOCTL_MGA_INIT, (unsigned long)init);
105}
106
107typedef struct drm_mga_getparam32 {
108 int param;
109 u32 value;
110} drm_mga_getparam32_t;
111
112static int compat_mga_getparam(struct file *file, unsigned int cmd,
113 unsigned long arg)
114{
115 drm_mga_getparam32_t getparam32;
116 drm_mga_getparam_t __user *getparam;
117
118 if (copy_from_user(&getparam32, (void __user *)arg, sizeof(getparam32)))
119 return -EFAULT;
120
121 getparam = compat_alloc_user_space(sizeof(*getparam));
122 if (!access_ok(VERIFY_WRITE, getparam, sizeof(*getparam))
123 || __put_user(getparam32.param, &getparam->param)
124 || __put_user((void __user *)(unsigned long)getparam32.value,
125 &getparam->value))
126 return -EFAULT;
127
128 return drm_ioctl(file->f_path.dentry->d_inode, file,
129 DRM_IOCTL_MGA_GETPARAM, (unsigned long)getparam);
130}
131
132typedef struct drm_mga_drm_bootstrap32 {
133 u32 texture_handle;
134 u32 texture_size;
135 u32 primary_size;
136 u32 secondary_bin_count;
137 u32 secondary_bin_size;
138 u32 agp_mode;
139 u8 agp_size;
140} drm_mga_dma_bootstrap32_t;
141
142static int compat_mga_dma_bootstrap(struct file *file, unsigned int cmd,
143 unsigned long arg)
144{
145 drm_mga_dma_bootstrap32_t dma_bootstrap32;
146 drm_mga_dma_bootstrap_t __user *dma_bootstrap;
147 int err;
148
149 if (copy_from_user(&dma_bootstrap32, (void __user *)arg,
150 sizeof(dma_bootstrap32)))
151 return -EFAULT;
152
153 dma_bootstrap = compat_alloc_user_space(sizeof(*dma_bootstrap));
154 if (!access_ok(VERIFY_WRITE, dma_bootstrap, sizeof(*dma_bootstrap))
155 || __put_user(dma_bootstrap32.texture_handle,
156 &dma_bootstrap->texture_handle)
157 || __put_user(dma_bootstrap32.texture_size,
158 &dma_bootstrap->texture_size)
159 || __put_user(dma_bootstrap32.primary_size,
160 &dma_bootstrap->primary_size)
161 || __put_user(dma_bootstrap32.secondary_bin_count,
162 &dma_bootstrap->secondary_bin_count)
163 || __put_user(dma_bootstrap32.secondary_bin_size,
164 &dma_bootstrap->secondary_bin_size)
165 || __put_user(dma_bootstrap32.agp_mode, &dma_bootstrap->agp_mode)
166 || __put_user(dma_bootstrap32.agp_size, &dma_bootstrap->agp_size))
167 return -EFAULT;
168
169 err = drm_ioctl(file->f_path.dentry->d_inode, file,
170 DRM_IOCTL_MGA_DMA_BOOTSTRAP,
171 (unsigned long)dma_bootstrap);
172 if (err)
173 return err;
174
175 if (__get_user(dma_bootstrap32.texture_handle,
176 &dma_bootstrap->texture_handle)
177 || __get_user(dma_bootstrap32.texture_size,
178 &dma_bootstrap->texture_size)
179 || __get_user(dma_bootstrap32.primary_size,
180 &dma_bootstrap->primary_size)
181 || __get_user(dma_bootstrap32.secondary_bin_count,
182 &dma_bootstrap->secondary_bin_count)
183 || __get_user(dma_bootstrap32.secondary_bin_size,
184 &dma_bootstrap->secondary_bin_size)
185 || __get_user(dma_bootstrap32.agp_mode, &dma_bootstrap->agp_mode)
186 || __get_user(dma_bootstrap32.agp_size, &dma_bootstrap->agp_size))
187 return -EFAULT;
188
189 if (copy_to_user((void __user *)arg, &dma_bootstrap32,
190 sizeof(dma_bootstrap32)))
191 return -EFAULT;
192
193 return 0;
194}
195
196drm_ioctl_compat_t *mga_compat_ioctls[] = {
197 [DRM_MGA_INIT] = compat_mga_init,
198 [DRM_MGA_GETPARAM] = compat_mga_getparam,
199 [DRM_MGA_DMA_BOOTSTRAP] = compat_mga_dma_bootstrap,
200};
201
202/**
203 * Called whenever a 32-bit process running under a 64-bit kernel
204 * performs an ioctl on /dev/dri/card<n>.
205 *
206 * \param filp file pointer.
207 * \param cmd command.
208 * \param arg user argument.
209 * \return zero on success or negative number on failure.
210 */
211long mga_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
212{
213 unsigned int nr = DRM_IOCTL_NR(cmd);
214 drm_ioctl_compat_t *fn = NULL;
215 int ret;
216
217 if (nr < DRM_COMMAND_BASE)
218 return drm_compat_ioctl(filp, cmd, arg);
219
220 if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(mga_compat_ioctls))
221 fn = mga_compat_ioctls[nr - DRM_COMMAND_BASE];
222
223 lock_kernel(); /* XXX for now */
224 if (fn != NULL)
225 ret = (*fn) (filp, cmd, arg);
226 else
227 ret = drm_ioctl(filp->f_path.dentry->d_inode, filp, cmd, arg);
228 unlock_kernel();
229
230 return ret;
231}
diff --git a/drivers/char/drm/mga_irq.c b/drivers/char/drm/mga_irq.c
deleted file mode 100644
index 06852fb4b278..000000000000
--- a/drivers/char/drm/mga_irq.c
+++ /dev/null
@@ -1,181 +0,0 @@
1/* mga_irq.c -- IRQ handling for radeon -*- linux-c -*-
2 *
3 * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
4 *
5 * The Weather Channel (TM) funded Tungsten Graphics to develop the
6 * initial release of the Radeon 8500 driver under the XFree86 license.
7 * This notice must be preserved.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice (including the next
17 * paragraph) shall be included in all copies or substantial portions of the
18 * Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
24 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
25 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 * DEALINGS IN THE SOFTWARE.
27 *
28 * Authors:
29 * Keith Whitwell <keith@tungstengraphics.com>
30 * Eric Anholt <anholt@FreeBSD.org>
31 */
32
33#include "drmP.h"
34#include "drm.h"
35#include "mga_drm.h"
36#include "mga_drv.h"
37
38u32 mga_get_vblank_counter(struct drm_device *dev, int crtc)
39{
40 const drm_mga_private_t *const dev_priv =
41 (drm_mga_private_t *) dev->dev_private;
42
43 if (crtc != 0) {
44 return 0;
45 }
46
47
48 return atomic_read(&dev_priv->vbl_received);
49}
50
51
52irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS)
53{
54 struct drm_device *dev = (struct drm_device *) arg;
55 drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
56 int status;
57 int handled = 0;
58
59 status = MGA_READ(MGA_STATUS);
60
61 /* VBLANK interrupt */
62 if (status & MGA_VLINEPEN) {
63 MGA_WRITE(MGA_ICLEAR, MGA_VLINEICLR);
64 atomic_inc(&dev_priv->vbl_received);
65 drm_handle_vblank(dev, 0);
66 handled = 1;
67 }
68
69 /* SOFTRAP interrupt */
70 if (status & MGA_SOFTRAPEN) {
71 const u32 prim_start = MGA_READ(MGA_PRIMADDRESS);
72 const u32 prim_end = MGA_READ(MGA_PRIMEND);
73
74 MGA_WRITE(MGA_ICLEAR, MGA_SOFTRAPICLR);
75
76 /* In addition to clearing the interrupt-pending bit, we
77 * have to write to MGA_PRIMEND to re-start the DMA operation.
78 */
79 if ((prim_start & ~0x03) != (prim_end & ~0x03)) {
80 MGA_WRITE(MGA_PRIMEND, prim_end);
81 }
82
83 atomic_inc(&dev_priv->last_fence_retired);
84 DRM_WAKEUP(&dev_priv->fence_queue);
85 handled = 1;
86 }
87
88 if (handled) {
89 return IRQ_HANDLED;
90 }
91 return IRQ_NONE;
92}
93
94int mga_enable_vblank(struct drm_device *dev, int crtc)
95{
96 drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
97
98 if (crtc != 0) {
99 DRM_ERROR("tried to enable vblank on non-existent crtc %d\n",
100 crtc);
101 return 0;
102 }
103
104 MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN);
105 return 0;
106}
107
108
109void mga_disable_vblank(struct drm_device *dev, int crtc)
110{
111 if (crtc != 0) {
112 DRM_ERROR("tried to disable vblank on non-existent crtc %d\n",
113 crtc);
114 }
115
116 /* Do *NOT* disable the vertical refresh interrupt. MGA doesn't have
117 * a nice hardware counter that tracks the number of refreshes when
118 * the interrupt is disabled, and the kernel doesn't know the refresh
119 * rate to calculate an estimate.
120 */
121 /* MGA_WRITE(MGA_IEN, MGA_VLINEIEN | MGA_SOFTRAPEN); */
122}
123
124int mga_driver_fence_wait(struct drm_device * dev, unsigned int *sequence)
125{
126 drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
127 unsigned int cur_fence;
128 int ret = 0;
129
130 /* Assume that the user has missed the current sequence number
131 * by about a day rather than she wants to wait for years
132 * using fences.
133 */
134 DRM_WAIT_ON(ret, dev_priv->fence_queue, 3 * DRM_HZ,
135 (((cur_fence = atomic_read(&dev_priv->last_fence_retired))
136 - *sequence) <= (1 << 23)));
137
138 *sequence = cur_fence;
139
140 return ret;
141}
142
143void mga_driver_irq_preinstall(struct drm_device * dev)
144{
145 drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
146
147 /* Disable *all* interrupts */
148 MGA_WRITE(MGA_IEN, 0);
149 /* Clear bits if they're already high */
150 MGA_WRITE(MGA_ICLEAR, ~0);
151}
152
153int mga_driver_irq_postinstall(struct drm_device * dev)
154{
155 drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
156 int ret;
157
158 ret = drm_vblank_init(dev, 1);
159 if (ret)
160 return ret;
161
162 DRM_INIT_WAITQUEUE(&dev_priv->fence_queue);
163
164 /* Turn on soft trap interrupt. Vertical blank interrupts are enabled
165 * in mga_enable_vblank.
166 */
167 MGA_WRITE(MGA_IEN, MGA_SOFTRAPEN);
168 return 0;
169}
170
171void mga_driver_irq_uninstall(struct drm_device * dev)
172{
173 drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
174 if (!dev_priv)
175 return;
176
177 /* Disable *all* interrupts */
178 MGA_WRITE(MGA_IEN, 0);
179
180 dev->irq_enabled = 0;
181}
diff --git a/drivers/char/drm/mga_state.c b/drivers/char/drm/mga_state.c
deleted file mode 100644
index d3f8aade07b3..000000000000
--- a/drivers/char/drm/mga_state.c
+++ /dev/null
@@ -1,1104 +0,0 @@
1/* mga_state.c -- State support for MGA G200/G400 -*- linux-c -*-
2 * Created: Thu Jan 27 02:53:43 2000 by jhartmann@precisioninsight.com
3 *
4 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
5 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
6 * All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice (including the next
16 * paragraph) shall be included in all copies or substantial portions of the
17 * Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
23 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25 * OTHER DEALINGS IN THE SOFTWARE.
26 *
27 * Authors:
28 * Jeff Hartmann <jhartmann@valinux.com>
29 * Keith Whitwell <keith@tungstengraphics.com>
30 *
31 * Rewritten by:
32 * Gareth Hughes <gareth@valinux.com>
33 */
34
35#include "drmP.h"
36#include "drm.h"
37#include "mga_drm.h"
38#include "mga_drv.h"
39
40/* ================================================================
41 * DMA hardware state programming functions
42 */
43
44static void mga_emit_clip_rect(drm_mga_private_t * dev_priv,
45 struct drm_clip_rect * box)
46{
47 drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
48 drm_mga_context_regs_t *ctx = &sarea_priv->context_state;
49 unsigned int pitch = dev_priv->front_pitch;
50 DMA_LOCALS;
51
52 BEGIN_DMA(2);
53
54 /* Force reset of DWGCTL on G400 (eliminates clip disable bit).
55 */
56 if (dev_priv->chipset >= MGA_CARD_TYPE_G400) {
57 DMA_BLOCK(MGA_DWGCTL, ctx->dwgctl,
58 MGA_LEN + MGA_EXEC, 0x80000000,
59 MGA_DWGCTL, ctx->dwgctl,
60 MGA_LEN + MGA_EXEC, 0x80000000);
61 }
62 DMA_BLOCK(MGA_DMAPAD, 0x00000000,
63 MGA_CXBNDRY, ((box->x2 - 1) << 16) | box->x1,
64 MGA_YTOP, box->y1 * pitch, MGA_YBOT, (box->y2 - 1) * pitch);
65
66 ADVANCE_DMA();
67}
68
69static __inline__ void mga_g200_emit_context(drm_mga_private_t * dev_priv)
70{
71 drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
72 drm_mga_context_regs_t *ctx = &sarea_priv->context_state;
73 DMA_LOCALS;
74
75 BEGIN_DMA(3);
76
77 DMA_BLOCK(MGA_DSTORG, ctx->dstorg,
78 MGA_MACCESS, ctx->maccess,
79 MGA_PLNWT, ctx->plnwt, MGA_DWGCTL, ctx->dwgctl);
80
81 DMA_BLOCK(MGA_ALPHACTRL, ctx->alphactrl,
82 MGA_FOGCOL, ctx->fogcolor,
83 MGA_WFLAG, ctx->wflag, MGA_ZORG, dev_priv->depth_offset);
84
85 DMA_BLOCK(MGA_FCOL, ctx->fcol,
86 MGA_DMAPAD, 0x00000000,
87 MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000);
88
89 ADVANCE_DMA();
90}
91
92static __inline__ void mga_g400_emit_context(drm_mga_private_t * dev_priv)
93{
94 drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
95 drm_mga_context_regs_t *ctx = &sarea_priv->context_state;
96 DMA_LOCALS;
97
98 BEGIN_DMA(4);
99
100 DMA_BLOCK(MGA_DSTORG, ctx->dstorg,
101 MGA_MACCESS, ctx->maccess,
102 MGA_PLNWT, ctx->plnwt, MGA_DWGCTL, ctx->dwgctl);
103
104 DMA_BLOCK(MGA_ALPHACTRL, ctx->alphactrl,
105 MGA_FOGCOL, ctx->fogcolor,
106 MGA_WFLAG, ctx->wflag, MGA_ZORG, dev_priv->depth_offset);
107
108 DMA_BLOCK(MGA_WFLAG1, ctx->wflag,
109 MGA_TDUALSTAGE0, ctx->tdualstage0,
110 MGA_TDUALSTAGE1, ctx->tdualstage1, MGA_FCOL, ctx->fcol);
111
112 DMA_BLOCK(MGA_STENCIL, ctx->stencil,
113 MGA_STENCILCTL, ctx->stencilctl,
114 MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000);
115
116 ADVANCE_DMA();
117}
118
119static __inline__ void mga_g200_emit_tex0(drm_mga_private_t * dev_priv)
120{
121 drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
122 drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[0];
123 DMA_LOCALS;
124
125 BEGIN_DMA(4);
126
127 DMA_BLOCK(MGA_TEXCTL2, tex->texctl2,
128 MGA_TEXCTL, tex->texctl,
129 MGA_TEXFILTER, tex->texfilter,
130 MGA_TEXBORDERCOL, tex->texbordercol);
131
132 DMA_BLOCK(MGA_TEXORG, tex->texorg,
133 MGA_TEXORG1, tex->texorg1,
134 MGA_TEXORG2, tex->texorg2, MGA_TEXORG3, tex->texorg3);
135
136 DMA_BLOCK(MGA_TEXORG4, tex->texorg4,
137 MGA_TEXWIDTH, tex->texwidth,
138 MGA_TEXHEIGHT, tex->texheight, MGA_WR24, tex->texwidth);
139
140 DMA_BLOCK(MGA_WR34, tex->texheight,
141 MGA_TEXTRANS, 0x0000ffff,
142 MGA_TEXTRANSHIGH, 0x0000ffff, MGA_DMAPAD, 0x00000000);
143
144 ADVANCE_DMA();
145}
146
147static __inline__ void mga_g400_emit_tex0(drm_mga_private_t * dev_priv)
148{
149 drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
150 drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[0];
151 DMA_LOCALS;
152
153/* printk("mga_g400_emit_tex0 %x %x %x\n", tex->texorg, */
154/* tex->texctl, tex->texctl2); */
155
156 BEGIN_DMA(6);
157
158 DMA_BLOCK(MGA_TEXCTL2, tex->texctl2 | MGA_G400_TC2_MAGIC,
159 MGA_TEXCTL, tex->texctl,
160 MGA_TEXFILTER, tex->texfilter,
161 MGA_TEXBORDERCOL, tex->texbordercol);
162
163 DMA_BLOCK(MGA_TEXORG, tex->texorg,
164 MGA_TEXORG1, tex->texorg1,
165 MGA_TEXORG2, tex->texorg2, MGA_TEXORG3, tex->texorg3);
166
167 DMA_BLOCK(MGA_TEXORG4, tex->texorg4,
168 MGA_TEXWIDTH, tex->texwidth,
169 MGA_TEXHEIGHT, tex->texheight, MGA_WR49, 0x00000000);
170
171 DMA_BLOCK(MGA_WR57, 0x00000000,
172 MGA_WR53, 0x00000000,
173 MGA_WR61, 0x00000000, MGA_WR52, MGA_G400_WR_MAGIC);
174
175 DMA_BLOCK(MGA_WR60, MGA_G400_WR_MAGIC,
176 MGA_WR54, tex->texwidth | MGA_G400_WR_MAGIC,
177 MGA_WR62, tex->texheight | MGA_G400_WR_MAGIC,
178 MGA_DMAPAD, 0x00000000);
179
180 DMA_BLOCK(MGA_DMAPAD, 0x00000000,
181 MGA_DMAPAD, 0x00000000,
182 MGA_TEXTRANS, 0x0000ffff, MGA_TEXTRANSHIGH, 0x0000ffff);
183
184 ADVANCE_DMA();
185}
186
187static __inline__ void mga_g400_emit_tex1(drm_mga_private_t * dev_priv)
188{
189 drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
190 drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[1];
191 DMA_LOCALS;
192
193/* printk("mga_g400_emit_tex1 %x %x %x\n", tex->texorg, */
194/* tex->texctl, tex->texctl2); */
195
196 BEGIN_DMA(5);
197
198 DMA_BLOCK(MGA_TEXCTL2, (tex->texctl2 |
199 MGA_MAP1_ENABLE |
200 MGA_G400_TC2_MAGIC),
201 MGA_TEXCTL, tex->texctl,
202 MGA_TEXFILTER, tex->texfilter,
203 MGA_TEXBORDERCOL, tex->texbordercol);
204
205 DMA_BLOCK(MGA_TEXORG, tex->texorg,
206 MGA_TEXORG1, tex->texorg1,
207 MGA_TEXORG2, tex->texorg2, MGA_TEXORG3, tex->texorg3);
208
209 DMA_BLOCK(MGA_TEXORG4, tex->texorg4,
210 MGA_TEXWIDTH, tex->texwidth,
211 MGA_TEXHEIGHT, tex->texheight, MGA_WR49, 0x00000000);
212
213 DMA_BLOCK(MGA_WR57, 0x00000000,
214 MGA_WR53, 0x00000000,
215 MGA_WR61, 0x00000000,
216 MGA_WR52, tex->texwidth | MGA_G400_WR_MAGIC);
217
218 DMA_BLOCK(MGA_WR60, tex->texheight | MGA_G400_WR_MAGIC,
219 MGA_TEXTRANS, 0x0000ffff,
220 MGA_TEXTRANSHIGH, 0x0000ffff,
221 MGA_TEXCTL2, tex->texctl2 | MGA_G400_TC2_MAGIC);
222
223 ADVANCE_DMA();
224}
225
226static __inline__ void mga_g200_emit_pipe(drm_mga_private_t * dev_priv)
227{
228 drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
229 unsigned int pipe = sarea_priv->warp_pipe;
230 DMA_LOCALS;
231
232 BEGIN_DMA(3);
233
234 DMA_BLOCK(MGA_WIADDR, MGA_WMODE_SUSPEND,
235 MGA_WVRTXSZ, 0x00000007,
236 MGA_WFLAG, 0x00000000, MGA_WR24, 0x00000000);
237
238 DMA_BLOCK(MGA_WR25, 0x00000100,
239 MGA_WR34, 0x00000000,
240 MGA_WR42, 0x0000ffff, MGA_WR60, 0x0000ffff);
241
242 /* Padding required to to hardware bug.
243 */
244 DMA_BLOCK(MGA_DMAPAD, 0xffffffff,
245 MGA_DMAPAD, 0xffffffff,
246 MGA_DMAPAD, 0xffffffff,
247 MGA_WIADDR, (dev_priv->warp_pipe_phys[pipe] |
248 MGA_WMODE_START | dev_priv->wagp_enable));
249
250 ADVANCE_DMA();
251}
252
253static __inline__ void mga_g400_emit_pipe(drm_mga_private_t * dev_priv)
254{
255 drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
256 unsigned int pipe = sarea_priv->warp_pipe;
257 DMA_LOCALS;
258
259/* printk("mga_g400_emit_pipe %x\n", pipe); */
260
261 BEGIN_DMA(10);
262
263 DMA_BLOCK(MGA_WIADDR2, MGA_WMODE_SUSPEND,
264 MGA_DMAPAD, 0x00000000,
265 MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000);
266
267 if (pipe & MGA_T2) {
268 DMA_BLOCK(MGA_WVRTXSZ, 0x00001e09,
269 MGA_DMAPAD, 0x00000000,
270 MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000);
271
272 DMA_BLOCK(MGA_WACCEPTSEQ, 0x00000000,
273 MGA_WACCEPTSEQ, 0x00000000,
274 MGA_WACCEPTSEQ, 0x00000000,
275 MGA_WACCEPTSEQ, 0x1e000000);
276 } else {
277 if (dev_priv->warp_pipe & MGA_T2) {
278 /* Flush the WARP pipe */
279 DMA_BLOCK(MGA_YDST, 0x00000000,
280 MGA_FXLEFT, 0x00000000,
281 MGA_FXRIGHT, 0x00000001,
282 MGA_DWGCTL, MGA_DWGCTL_FLUSH);
283
284 DMA_BLOCK(MGA_LEN + MGA_EXEC, 0x00000001,
285 MGA_DWGSYNC, 0x00007000,
286 MGA_TEXCTL2, MGA_G400_TC2_MAGIC,
287 MGA_LEN + MGA_EXEC, 0x00000000);
288
289 DMA_BLOCK(MGA_TEXCTL2, (MGA_DUALTEX |
290 MGA_G400_TC2_MAGIC),
291 MGA_LEN + MGA_EXEC, 0x00000000,
292 MGA_TEXCTL2, MGA_G400_TC2_MAGIC,
293 MGA_DMAPAD, 0x00000000);
294 }
295
296 DMA_BLOCK(MGA_WVRTXSZ, 0x00001807,
297 MGA_DMAPAD, 0x00000000,
298 MGA_DMAPAD, 0x00000000, MGA_DMAPAD, 0x00000000);
299
300 DMA_BLOCK(MGA_WACCEPTSEQ, 0x00000000,
301 MGA_WACCEPTSEQ, 0x00000000,
302 MGA_WACCEPTSEQ, 0x00000000,
303 MGA_WACCEPTSEQ, 0x18000000);
304 }
305
306 DMA_BLOCK(MGA_WFLAG, 0x00000000,
307 MGA_WFLAG1, 0x00000000,
308 MGA_WR56, MGA_G400_WR56_MAGIC, MGA_DMAPAD, 0x00000000);
309
310 DMA_BLOCK(MGA_WR49, 0x00000000, /* tex0 */
311 MGA_WR57, 0x00000000, /* tex0 */
312 MGA_WR53, 0x00000000, /* tex1 */
313 MGA_WR61, 0x00000000); /* tex1 */
314
315 DMA_BLOCK(MGA_WR54, MGA_G400_WR_MAGIC, /* tex0 width */
316 MGA_WR62, MGA_G400_WR_MAGIC, /* tex0 height */
317 MGA_WR52, MGA_G400_WR_MAGIC, /* tex1 width */
318 MGA_WR60, MGA_G400_WR_MAGIC); /* tex1 height */
319
320 /* Padding required to to hardware bug */
321 DMA_BLOCK(MGA_DMAPAD, 0xffffffff,
322 MGA_DMAPAD, 0xffffffff,
323 MGA_DMAPAD, 0xffffffff,
324 MGA_WIADDR2, (dev_priv->warp_pipe_phys[pipe] |
325 MGA_WMODE_START | dev_priv->wagp_enable));
326
327 ADVANCE_DMA();
328}
329
330static void mga_g200_emit_state(drm_mga_private_t * dev_priv)
331{
332 drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
333 unsigned int dirty = sarea_priv->dirty;
334
335 if (sarea_priv->warp_pipe != dev_priv->warp_pipe) {
336 mga_g200_emit_pipe(dev_priv);
337 dev_priv->warp_pipe = sarea_priv->warp_pipe;
338 }
339
340 if (dirty & MGA_UPLOAD_CONTEXT) {
341 mga_g200_emit_context(dev_priv);
342 sarea_priv->dirty &= ~MGA_UPLOAD_CONTEXT;
343 }
344
345 if (dirty & MGA_UPLOAD_TEX0) {
346 mga_g200_emit_tex0(dev_priv);
347 sarea_priv->dirty &= ~MGA_UPLOAD_TEX0;
348 }
349}
350
351static void mga_g400_emit_state(drm_mga_private_t * dev_priv)
352{
353 drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
354 unsigned int dirty = sarea_priv->dirty;
355 int multitex = sarea_priv->warp_pipe & MGA_T2;
356
357 if (sarea_priv->warp_pipe != dev_priv->warp_pipe) {
358 mga_g400_emit_pipe(dev_priv);
359 dev_priv->warp_pipe = sarea_priv->warp_pipe;
360 }
361
362 if (dirty & MGA_UPLOAD_CONTEXT) {
363 mga_g400_emit_context(dev_priv);
364 sarea_priv->dirty &= ~MGA_UPLOAD_CONTEXT;
365 }
366
367 if (dirty & MGA_UPLOAD_TEX0) {
368 mga_g400_emit_tex0(dev_priv);
369 sarea_priv->dirty &= ~MGA_UPLOAD_TEX0;
370 }
371
372 if ((dirty & MGA_UPLOAD_TEX1) && multitex) {
373 mga_g400_emit_tex1(dev_priv);
374 sarea_priv->dirty &= ~MGA_UPLOAD_TEX1;
375 }
376}
377
378/* ================================================================
379 * SAREA state verification
380 */
381
382/* Disallow all write destinations except the front and backbuffer.
383 */
384static int mga_verify_context(drm_mga_private_t * dev_priv)
385{
386 drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
387 drm_mga_context_regs_t *ctx = &sarea_priv->context_state;
388
389 if (ctx->dstorg != dev_priv->front_offset &&
390 ctx->dstorg != dev_priv->back_offset) {
391 DRM_ERROR("*** bad DSTORG: %x (front %x, back %x)\n\n",
392 ctx->dstorg, dev_priv->front_offset,
393 dev_priv->back_offset);
394 ctx->dstorg = 0;
395 return -EINVAL;
396 }
397
398 return 0;
399}
400
401/* Disallow texture reads from PCI space.
402 */
403static int mga_verify_tex(drm_mga_private_t * dev_priv, int unit)
404{
405 drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
406 drm_mga_texture_regs_t *tex = &sarea_priv->tex_state[unit];
407 unsigned int org;
408
409 org = tex->texorg & (MGA_TEXORGMAP_MASK | MGA_TEXORGACC_MASK);
410
411 if (org == (MGA_TEXORGMAP_SYSMEM | MGA_TEXORGACC_PCI)) {
412 DRM_ERROR("*** bad TEXORG: 0x%x, unit %d\n", tex->texorg, unit);
413 tex->texorg = 0;
414 return -EINVAL;
415 }
416
417 return 0;
418}
419
420static int mga_verify_state(drm_mga_private_t * dev_priv)
421{
422 drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
423 unsigned int dirty = sarea_priv->dirty;
424 int ret = 0;
425
426 if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS)
427 sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS;
428
429 if (dirty & MGA_UPLOAD_CONTEXT)
430 ret |= mga_verify_context(dev_priv);
431
432 if (dirty & MGA_UPLOAD_TEX0)
433 ret |= mga_verify_tex(dev_priv, 0);
434
435 if (dev_priv->chipset >= MGA_CARD_TYPE_G400) {
436 if (dirty & MGA_UPLOAD_TEX1)
437 ret |= mga_verify_tex(dev_priv, 1);
438
439 if (dirty & MGA_UPLOAD_PIPE)
440 ret |= (sarea_priv->warp_pipe > MGA_MAX_G400_PIPES);
441 } else {
442 if (dirty & MGA_UPLOAD_PIPE)
443 ret |= (sarea_priv->warp_pipe > MGA_MAX_G200_PIPES);
444 }
445
446 return (ret == 0);
447}
448
449static int mga_verify_iload(drm_mga_private_t * dev_priv,
450 unsigned int dstorg, unsigned int length)
451{
452 if (dstorg < dev_priv->texture_offset ||
453 dstorg + length > (dev_priv->texture_offset +
454 dev_priv->texture_size)) {
455 DRM_ERROR("*** bad iload DSTORG: 0x%x\n", dstorg);
456 return -EINVAL;
457 }
458
459 if (length & MGA_ILOAD_MASK) {
460 DRM_ERROR("*** bad iload length: 0x%x\n",
461 length & MGA_ILOAD_MASK);
462 return -EINVAL;
463 }
464
465 return 0;
466}
467
468static int mga_verify_blit(drm_mga_private_t * dev_priv,
469 unsigned int srcorg, unsigned int dstorg)
470{
471 if ((srcorg & 0x3) == (MGA_SRCACC_PCI | MGA_SRCMAP_SYSMEM) ||
472 (dstorg & 0x3) == (MGA_SRCACC_PCI | MGA_SRCMAP_SYSMEM)) {
473 DRM_ERROR("*** bad blit: src=0x%x dst=0x%x\n", srcorg, dstorg);
474 return -EINVAL;
475 }
476 return 0;
477}
478
479/* ================================================================
480 *
481 */
482
483static void mga_dma_dispatch_clear(struct drm_device * dev, drm_mga_clear_t * clear)
484{
485 drm_mga_private_t *dev_priv = dev->dev_private;
486 drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
487 drm_mga_context_regs_t *ctx = &sarea_priv->context_state;
488 struct drm_clip_rect *pbox = sarea_priv->boxes;
489 int nbox = sarea_priv->nbox;
490 int i;
491 DMA_LOCALS;
492 DRM_DEBUG("\n");
493
494 BEGIN_DMA(1);
495
496 DMA_BLOCK(MGA_DMAPAD, 0x00000000,
497 MGA_DMAPAD, 0x00000000,
498 MGA_DWGSYNC, 0x00007100, MGA_DWGSYNC, 0x00007000);
499
500 ADVANCE_DMA();
501
502 for (i = 0; i < nbox; i++) {
503 struct drm_clip_rect *box = &pbox[i];
504 u32 height = box->y2 - box->y1;
505
506 DRM_DEBUG(" from=%d,%d to=%d,%d\n",
507 box->x1, box->y1, box->x2, box->y2);
508
509 if (clear->flags & MGA_FRONT) {
510 BEGIN_DMA(2);
511
512 DMA_BLOCK(MGA_DMAPAD, 0x00000000,
513 MGA_PLNWT, clear->color_mask,
514 MGA_YDSTLEN, (box->y1 << 16) | height,
515 MGA_FXBNDRY, (box->x2 << 16) | box->x1);
516
517 DMA_BLOCK(MGA_DMAPAD, 0x00000000,
518 MGA_FCOL, clear->clear_color,
519 MGA_DSTORG, dev_priv->front_offset,
520 MGA_DWGCTL + MGA_EXEC, dev_priv->clear_cmd);
521
522 ADVANCE_DMA();
523 }
524
525 if (clear->flags & MGA_BACK) {
526 BEGIN_DMA(2);
527
528 DMA_BLOCK(MGA_DMAPAD, 0x00000000,
529 MGA_PLNWT, clear->color_mask,
530 MGA_YDSTLEN, (box->y1 << 16) | height,
531 MGA_FXBNDRY, (box->x2 << 16) | box->x1);
532
533 DMA_BLOCK(MGA_DMAPAD, 0x00000000,
534 MGA_FCOL, clear->clear_color,
535 MGA_DSTORG, dev_priv->back_offset,
536 MGA_DWGCTL + MGA_EXEC, dev_priv->clear_cmd);
537
538 ADVANCE_DMA();
539 }
540
541 if (clear->flags & MGA_DEPTH) {
542 BEGIN_DMA(2);
543
544 DMA_BLOCK(MGA_DMAPAD, 0x00000000,
545 MGA_PLNWT, clear->depth_mask,
546 MGA_YDSTLEN, (box->y1 << 16) | height,
547 MGA_FXBNDRY, (box->x2 << 16) | box->x1);
548
549 DMA_BLOCK(MGA_DMAPAD, 0x00000000,
550 MGA_FCOL, clear->clear_depth,
551 MGA_DSTORG, dev_priv->depth_offset,
552 MGA_DWGCTL + MGA_EXEC, dev_priv->clear_cmd);
553
554 ADVANCE_DMA();
555 }
556
557 }
558
559 BEGIN_DMA(1);
560
561 /* Force reset of DWGCTL */
562 DMA_BLOCK(MGA_DMAPAD, 0x00000000,
563 MGA_DMAPAD, 0x00000000,
564 MGA_PLNWT, ctx->plnwt, MGA_DWGCTL, ctx->dwgctl);
565
566 ADVANCE_DMA();
567
568 FLUSH_DMA();
569}
570
571static void mga_dma_dispatch_swap(struct drm_device * dev)
572{
573 drm_mga_private_t *dev_priv = dev->dev_private;
574 drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
575 drm_mga_context_regs_t *ctx = &sarea_priv->context_state;
576 struct drm_clip_rect *pbox = sarea_priv->boxes;
577 int nbox = sarea_priv->nbox;
578 int i;
579 DMA_LOCALS;
580 DRM_DEBUG("\n");
581
582 sarea_priv->last_frame.head = dev_priv->prim.tail;
583 sarea_priv->last_frame.wrap = dev_priv->prim.last_wrap;
584
585 BEGIN_DMA(4 + nbox);
586
587 DMA_BLOCK(MGA_DMAPAD, 0x00000000,
588 MGA_DMAPAD, 0x00000000,
589 MGA_DWGSYNC, 0x00007100, MGA_DWGSYNC, 0x00007000);
590
591 DMA_BLOCK(MGA_DSTORG, dev_priv->front_offset,
592 MGA_MACCESS, dev_priv->maccess,
593 MGA_SRCORG, dev_priv->back_offset,
594 MGA_AR5, dev_priv->front_pitch);
595
596 DMA_BLOCK(MGA_DMAPAD, 0x00000000,
597 MGA_DMAPAD, 0x00000000,
598 MGA_PLNWT, 0xffffffff, MGA_DWGCTL, MGA_DWGCTL_COPY);
599
600 for (i = 0; i < nbox; i++) {
601 struct drm_clip_rect *box = &pbox[i];
602 u32 height = box->y2 - box->y1;
603 u32 start = box->y1 * dev_priv->front_pitch;
604
605 DRM_DEBUG(" from=%d,%d to=%d,%d\n",
606 box->x1, box->y1, box->x2, box->y2);
607
608 DMA_BLOCK(MGA_AR0, start + box->x2 - 1,
609 MGA_AR3, start + box->x1,
610 MGA_FXBNDRY, ((box->x2 - 1) << 16) | box->x1,
611 MGA_YDSTLEN + MGA_EXEC, (box->y1 << 16) | height);
612 }
613
614 DMA_BLOCK(MGA_DMAPAD, 0x00000000,
615 MGA_PLNWT, ctx->plnwt,
616 MGA_SRCORG, dev_priv->front_offset, MGA_DWGCTL, ctx->dwgctl);
617
618 ADVANCE_DMA();
619
620 FLUSH_DMA();
621
622 DRM_DEBUG("... done.\n");
623}
624
625static void mga_dma_dispatch_vertex(struct drm_device * dev, struct drm_buf * buf)
626{
627 drm_mga_private_t *dev_priv = dev->dev_private;
628 drm_mga_buf_priv_t *buf_priv = buf->dev_private;
629 drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
630 u32 address = (u32) buf->bus_address;
631 u32 length = (u32) buf->used;
632 int i = 0;
633 DMA_LOCALS;
634 DRM_DEBUG("buf=%d used=%d\n", buf->idx, buf->used);
635
636 if (buf->used) {
637 buf_priv->dispatched = 1;
638
639 MGA_EMIT_STATE(dev_priv, sarea_priv->dirty);
640
641 do {
642 if (i < sarea_priv->nbox) {
643 mga_emit_clip_rect(dev_priv,
644 &sarea_priv->boxes[i]);
645 }
646
647 BEGIN_DMA(1);
648
649 DMA_BLOCK(MGA_DMAPAD, 0x00000000,
650 MGA_DMAPAD, 0x00000000,
651 MGA_SECADDRESS, (address |
652 MGA_DMA_VERTEX),
653 MGA_SECEND, ((address + length) |
654 dev_priv->dma_access));
655
656 ADVANCE_DMA();
657 } while (++i < sarea_priv->nbox);
658 }
659
660 if (buf_priv->discard) {
661 AGE_BUFFER(buf_priv);
662 buf->pending = 0;
663 buf->used = 0;
664 buf_priv->dispatched = 0;
665
666 mga_freelist_put(dev, buf);
667 }
668
669 FLUSH_DMA();
670}
671
672static void mga_dma_dispatch_indices(struct drm_device * dev, struct drm_buf * buf,
673 unsigned int start, unsigned int end)
674{
675 drm_mga_private_t *dev_priv = dev->dev_private;
676 drm_mga_buf_priv_t *buf_priv = buf->dev_private;
677 drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
678 u32 address = (u32) buf->bus_address;
679 int i = 0;
680 DMA_LOCALS;
681 DRM_DEBUG("buf=%d start=%d end=%d\n", buf->idx, start, end);
682
683 if (start != end) {
684 buf_priv->dispatched = 1;
685
686 MGA_EMIT_STATE(dev_priv, sarea_priv->dirty);
687
688 do {
689 if (i < sarea_priv->nbox) {
690 mga_emit_clip_rect(dev_priv,
691 &sarea_priv->boxes[i]);
692 }
693
694 BEGIN_DMA(1);
695
696 DMA_BLOCK(MGA_DMAPAD, 0x00000000,
697 MGA_DMAPAD, 0x00000000,
698 MGA_SETUPADDRESS, address + start,
699 MGA_SETUPEND, ((address + end) |
700 dev_priv->dma_access));
701
702 ADVANCE_DMA();
703 } while (++i < sarea_priv->nbox);
704 }
705
706 if (buf_priv->discard) {
707 AGE_BUFFER(buf_priv);
708 buf->pending = 0;
709 buf->used = 0;
710 buf_priv->dispatched = 0;
711
712 mga_freelist_put(dev, buf);
713 }
714
715 FLUSH_DMA();
716}
717
718/* This copies a 64 byte aligned agp region to the frambuffer with a
719 * standard blit, the ioctl needs to do checking.
720 */
721static void mga_dma_dispatch_iload(struct drm_device * dev, struct drm_buf * buf,
722 unsigned int dstorg, unsigned int length)
723{
724 drm_mga_private_t *dev_priv = dev->dev_private;
725 drm_mga_buf_priv_t *buf_priv = buf->dev_private;
726 drm_mga_context_regs_t *ctx = &dev_priv->sarea_priv->context_state;
727 u32 srcorg =
728 buf->bus_address | dev_priv->dma_access | MGA_SRCMAP_SYSMEM;
729 u32 y2;
730 DMA_LOCALS;
731 DRM_DEBUG("buf=%d used=%d\n", buf->idx, buf->used);
732
733 y2 = length / 64;
734
735 BEGIN_DMA(5);
736
737 DMA_BLOCK(MGA_DMAPAD, 0x00000000,
738 MGA_DMAPAD, 0x00000000,
739 MGA_DWGSYNC, 0x00007100, MGA_DWGSYNC, 0x00007000);
740
741 DMA_BLOCK(MGA_DSTORG, dstorg,
742 MGA_MACCESS, 0x00000000, MGA_SRCORG, srcorg, MGA_AR5, 64);
743
744 DMA_BLOCK(MGA_PITCH, 64,
745 MGA_PLNWT, 0xffffffff,
746 MGA_DMAPAD, 0x00000000, MGA_DWGCTL, MGA_DWGCTL_COPY);
747
748 DMA_BLOCK(MGA_AR0, 63,
749 MGA_AR3, 0,
750 MGA_FXBNDRY, (63 << 16) | 0, MGA_YDSTLEN + MGA_EXEC, y2);
751
752 DMA_BLOCK(MGA_PLNWT, ctx->plnwt,
753 MGA_SRCORG, dev_priv->front_offset,
754 MGA_PITCH, dev_priv->front_pitch, MGA_DWGSYNC, 0x00007000);
755
756 ADVANCE_DMA();
757
758 AGE_BUFFER(buf_priv);
759
760 buf->pending = 0;
761 buf->used = 0;
762 buf_priv->dispatched = 0;
763
764 mga_freelist_put(dev, buf);
765
766 FLUSH_DMA();
767}
768
769static void mga_dma_dispatch_blit(struct drm_device * dev, drm_mga_blit_t * blit)
770{
771 drm_mga_private_t *dev_priv = dev->dev_private;
772 drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
773 drm_mga_context_regs_t *ctx = &sarea_priv->context_state;
774 struct drm_clip_rect *pbox = sarea_priv->boxes;
775 int nbox = sarea_priv->nbox;
776 u32 scandir = 0, i;
777 DMA_LOCALS;
778 DRM_DEBUG("\n");
779
780 BEGIN_DMA(4 + nbox);
781
782 DMA_BLOCK(MGA_DMAPAD, 0x00000000,
783 MGA_DMAPAD, 0x00000000,
784 MGA_DWGSYNC, 0x00007100, MGA_DWGSYNC, 0x00007000);
785
786 DMA_BLOCK(MGA_DWGCTL, MGA_DWGCTL_COPY,
787 MGA_PLNWT, blit->planemask,
788 MGA_SRCORG, blit->srcorg, MGA_DSTORG, blit->dstorg);
789
790 DMA_BLOCK(MGA_SGN, scandir,
791 MGA_MACCESS, dev_priv->maccess,
792 MGA_AR5, blit->ydir * blit->src_pitch,
793 MGA_PITCH, blit->dst_pitch);
794
795 for (i = 0; i < nbox; i++) {
796 int srcx = pbox[i].x1 + blit->delta_sx;
797 int srcy = pbox[i].y1 + blit->delta_sy;
798 int dstx = pbox[i].x1 + blit->delta_dx;
799 int dsty = pbox[i].y1 + blit->delta_dy;
800 int h = pbox[i].y2 - pbox[i].y1;
801 int w = pbox[i].x2 - pbox[i].x1 - 1;
802 int start;
803
804 if (blit->ydir == -1) {
805 srcy = blit->height - srcy - 1;
806 }
807
808 start = srcy * blit->src_pitch + srcx;
809
810 DMA_BLOCK(MGA_AR0, start + w,
811 MGA_AR3, start,
812 MGA_FXBNDRY, ((dstx + w) << 16) | (dstx & 0xffff),
813 MGA_YDSTLEN + MGA_EXEC, (dsty << 16) | h);
814 }
815
816 /* Do something to flush AGP?
817 */
818
819 /* Force reset of DWGCTL */
820 DMA_BLOCK(MGA_DMAPAD, 0x00000000,
821 MGA_PLNWT, ctx->plnwt,
822 MGA_PITCH, dev_priv->front_pitch, MGA_DWGCTL, ctx->dwgctl);
823
824 ADVANCE_DMA();
825}
826
827/* ================================================================
828 *
829 */
830
831static int mga_dma_clear(struct drm_device *dev, void *data, struct drm_file *file_priv)
832{
833 drm_mga_private_t *dev_priv = dev->dev_private;
834 drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
835 drm_mga_clear_t *clear = data;
836
837 LOCK_TEST_WITH_RETURN(dev, file_priv);
838
839 if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS)
840 sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS;
841
842 WRAP_TEST_WITH_RETURN(dev_priv);
843
844 mga_dma_dispatch_clear(dev, clear);
845
846 /* Make sure we restore the 3D state next time.
847 */
848 dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CONTEXT;
849
850 return 0;
851}
852
853static int mga_dma_swap(struct drm_device *dev, void *data, struct drm_file *file_priv)
854{
855 drm_mga_private_t *dev_priv = dev->dev_private;
856 drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
857
858 LOCK_TEST_WITH_RETURN(dev, file_priv);
859
860 if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS)
861 sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS;
862
863 WRAP_TEST_WITH_RETURN(dev_priv);
864
865 mga_dma_dispatch_swap(dev);
866
867 /* Make sure we restore the 3D state next time.
868 */
869 dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CONTEXT;
870
871 return 0;
872}
873
874static int mga_dma_vertex(struct drm_device *dev, void *data, struct drm_file *file_priv)
875{
876 drm_mga_private_t *dev_priv = dev->dev_private;
877 struct drm_device_dma *dma = dev->dma;
878 struct drm_buf *buf;
879 drm_mga_buf_priv_t *buf_priv;
880 drm_mga_vertex_t *vertex = data;
881
882 LOCK_TEST_WITH_RETURN(dev, file_priv);
883
884 if (vertex->idx < 0 || vertex->idx > dma->buf_count)
885 return -EINVAL;
886 buf = dma->buflist[vertex->idx];
887 buf_priv = buf->dev_private;
888
889 buf->used = vertex->used;
890 buf_priv->discard = vertex->discard;
891
892 if (!mga_verify_state(dev_priv)) {
893 if (vertex->discard) {
894 if (buf_priv->dispatched == 1)
895 AGE_BUFFER(buf_priv);
896 buf_priv->dispatched = 0;
897 mga_freelist_put(dev, buf);
898 }
899 return -EINVAL;
900 }
901
902 WRAP_TEST_WITH_RETURN(dev_priv);
903
904 mga_dma_dispatch_vertex(dev, buf);
905
906 return 0;
907}
908
909static int mga_dma_indices(struct drm_device *dev, void *data, struct drm_file *file_priv)
910{
911 drm_mga_private_t *dev_priv = dev->dev_private;
912 struct drm_device_dma *dma = dev->dma;
913 struct drm_buf *buf;
914 drm_mga_buf_priv_t *buf_priv;
915 drm_mga_indices_t *indices = data;
916
917 LOCK_TEST_WITH_RETURN(dev, file_priv);
918
919 if (indices->idx < 0 || indices->idx > dma->buf_count)
920 return -EINVAL;
921
922 buf = dma->buflist[indices->idx];
923 buf_priv = buf->dev_private;
924
925 buf_priv->discard = indices->discard;
926
927 if (!mga_verify_state(dev_priv)) {
928 if (indices->discard) {
929 if (buf_priv->dispatched == 1)
930 AGE_BUFFER(buf_priv);
931 buf_priv->dispatched = 0;
932 mga_freelist_put(dev, buf);
933 }
934 return -EINVAL;
935 }
936
937 WRAP_TEST_WITH_RETURN(dev_priv);
938
939 mga_dma_dispatch_indices(dev, buf, indices->start, indices->end);
940
941 return 0;
942}
943
944static int mga_dma_iload(struct drm_device *dev, void *data, struct drm_file *file_priv)
945{
946 struct drm_device_dma *dma = dev->dma;
947 drm_mga_private_t *dev_priv = dev->dev_private;
948 struct drm_buf *buf;
949 drm_mga_buf_priv_t *buf_priv;
950 drm_mga_iload_t *iload = data;
951 DRM_DEBUG("\n");
952
953 LOCK_TEST_WITH_RETURN(dev, file_priv);
954
955#if 0
956 if (mga_do_wait_for_idle(dev_priv) < 0) {
957 if (MGA_DMA_DEBUG)
958 DRM_INFO("-EBUSY\n");
959 return -EBUSY;
960 }
961#endif
962 if (iload->idx < 0 || iload->idx > dma->buf_count)
963 return -EINVAL;
964
965 buf = dma->buflist[iload->idx];
966 buf_priv = buf->dev_private;
967
968 if (mga_verify_iload(dev_priv, iload->dstorg, iload->length)) {
969 mga_freelist_put(dev, buf);
970 return -EINVAL;
971 }
972
973 WRAP_TEST_WITH_RETURN(dev_priv);
974
975 mga_dma_dispatch_iload(dev, buf, iload->dstorg, iload->length);
976
977 /* Make sure we restore the 3D state next time.
978 */
979 dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CONTEXT;
980
981 return 0;
982}
983
984static int mga_dma_blit(struct drm_device *dev, void *data, struct drm_file *file_priv)
985{
986 drm_mga_private_t *dev_priv = dev->dev_private;
987 drm_mga_sarea_t *sarea_priv = dev_priv->sarea_priv;
988 drm_mga_blit_t *blit = data;
989 DRM_DEBUG("\n");
990
991 LOCK_TEST_WITH_RETURN(dev, file_priv);
992
993 if (sarea_priv->nbox > MGA_NR_SAREA_CLIPRECTS)
994 sarea_priv->nbox = MGA_NR_SAREA_CLIPRECTS;
995
996 if (mga_verify_blit(dev_priv, blit->srcorg, blit->dstorg))
997 return -EINVAL;
998
999 WRAP_TEST_WITH_RETURN(dev_priv);
1000
1001 mga_dma_dispatch_blit(dev, blit);
1002
1003 /* Make sure we restore the 3D state next time.
1004 */
1005 dev_priv->sarea_priv->dirty |= MGA_UPLOAD_CONTEXT;
1006
1007 return 0;
1008}
1009
1010static int mga_getparam(struct drm_device *dev, void *data, struct drm_file *file_priv)
1011{
1012 drm_mga_private_t *dev_priv = dev->dev_private;
1013 drm_mga_getparam_t *param = data;
1014 int value;
1015
1016 if (!dev_priv) {
1017 DRM_ERROR("called with no initialization\n");
1018 return -EINVAL;
1019 }
1020
1021 DRM_DEBUG("pid=%d\n", DRM_CURRENTPID);
1022
1023 switch (param->param) {
1024 case MGA_PARAM_IRQ_NR:
1025 value = dev->irq;
1026 break;
1027 case MGA_PARAM_CARD_TYPE:
1028 value = dev_priv->chipset;
1029 break;
1030 default:
1031 return -EINVAL;
1032 }
1033
1034 if (DRM_COPY_TO_USER(param->value, &value, sizeof(int))) {
1035 DRM_ERROR("copy_to_user\n");
1036 return -EFAULT;
1037 }
1038
1039 return 0;
1040}
1041
1042static int mga_set_fence(struct drm_device *dev, void *data, struct drm_file *file_priv)
1043{
1044 drm_mga_private_t *dev_priv = dev->dev_private;
1045 u32 *fence = data;
1046 DMA_LOCALS;
1047
1048 if (!dev_priv) {
1049 DRM_ERROR("called with no initialization\n");
1050 return -EINVAL;
1051 }
1052
1053 DRM_DEBUG("pid=%d\n", DRM_CURRENTPID);
1054
1055 /* I would normal do this assignment in the declaration of fence,
1056 * but dev_priv may be NULL.
1057 */
1058
1059 *fence = dev_priv->next_fence_to_post;
1060 dev_priv->next_fence_to_post++;
1061
1062 BEGIN_DMA(1);
1063 DMA_BLOCK(MGA_DMAPAD, 0x00000000,
1064 MGA_DMAPAD, 0x00000000,
1065 MGA_DMAPAD, 0x00000000, MGA_SOFTRAP, 0x00000000);
1066 ADVANCE_DMA();
1067
1068 return 0;
1069}
1070
1071static int mga_wait_fence(struct drm_device *dev, void *data, struct drm_file *
1072file_priv)
1073{
1074 drm_mga_private_t *dev_priv = dev->dev_private;
1075 u32 *fence = data;
1076
1077 if (!dev_priv) {
1078 DRM_ERROR("called with no initialization\n");
1079 return -EINVAL;
1080 }
1081
1082 DRM_DEBUG("pid=%d\n", DRM_CURRENTPID);
1083
1084 mga_driver_fence_wait(dev, fence);
1085 return 0;
1086}
1087
1088struct drm_ioctl_desc mga_ioctls[] = {
1089 DRM_IOCTL_DEF(DRM_MGA_INIT, mga_dma_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
1090 DRM_IOCTL_DEF(DRM_MGA_FLUSH, mga_dma_flush, DRM_AUTH),
1091 DRM_IOCTL_DEF(DRM_MGA_RESET, mga_dma_reset, DRM_AUTH),
1092 DRM_IOCTL_DEF(DRM_MGA_SWAP, mga_dma_swap, DRM_AUTH),
1093 DRM_IOCTL_DEF(DRM_MGA_CLEAR, mga_dma_clear, DRM_AUTH),
1094 DRM_IOCTL_DEF(DRM_MGA_VERTEX, mga_dma_vertex, DRM_AUTH),
1095 DRM_IOCTL_DEF(DRM_MGA_INDICES, mga_dma_indices, DRM_AUTH),
1096 DRM_IOCTL_DEF(DRM_MGA_ILOAD, mga_dma_iload, DRM_AUTH),
1097 DRM_IOCTL_DEF(DRM_MGA_BLIT, mga_dma_blit, DRM_AUTH),
1098 DRM_IOCTL_DEF(DRM_MGA_GETPARAM, mga_getparam, DRM_AUTH),
1099 DRM_IOCTL_DEF(DRM_MGA_SET_FENCE, mga_set_fence, DRM_AUTH),
1100 DRM_IOCTL_DEF(DRM_MGA_WAIT_FENCE, mga_wait_fence, DRM_AUTH),
1101 DRM_IOCTL_DEF(DRM_MGA_DMA_BOOTSTRAP, mga_dma_bootstrap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
1102};
1103
1104int mga_max_ioctl = DRM_ARRAY_SIZE(mga_ioctls);
diff --git a/drivers/char/drm/mga_ucode.h b/drivers/char/drm/mga_ucode.h
deleted file mode 100644
index b611e27470e1..000000000000
--- a/drivers/char/drm/mga_ucode.h
+++ /dev/null
@@ -1,11645 +0,0 @@
1/* mga_ucode.h -- Matrox G200/G400 WARP engine microcode -*- linux-c -*-
2 * Created: Thu Jan 11 21:20:43 2001 by gareth@valinux.com
3 *
4 * Copyright 1999 Matrox Graphics Inc.
5 * All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice shall be included
15 * in all copies or substantial portions of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
18 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * MATROX GRAPHICS INC., OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
21 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
22 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
23 * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 *
25 * Kernel-based WARP engine management:
26 * Gareth Hughes <gareth@valinux.com>
27 */
28
29/*
30 * WARP pipes are named according to the functions they perform, where:
31 *
32 * - T stands for computation of texture stage 0
33 * - T2 stands for computation of both texture stage 0 and texture stage 1
34 * - G stands for computation of triangle intensity (Gouraud interpolation)
35 * - Z stands for computation of Z buffer interpolation
36 * - S stands for computation of specular highlight
37 * - A stands for computation of the alpha channel
38 * - F stands for computation of vertex fog interpolation
39 */
40
41static unsigned char warp_g200_tgz[] = {
42
43 0x00, 0x80, 0x00, 0xE8,
44 0x00, 0x80, 0x00, 0xE8,
45
46 0x00, 0x80, 0x00, 0xE8,
47 0x00, 0x80, 0x00, 0xE8,
48
49 0x00, 0x80, 0x00, 0xE8,
50 0x00, 0x80, 0x00, 0xE8,
51
52 0x00, 0x80, 0x00, 0xE8,
53 0x00, 0x80, 0x00, 0xE8,
54
55 0x00, 0x80, 0x00, 0xE8,
56 0x00, 0x80, 0x00, 0xE8,
57
58 0x00, 0x98, 0xA0, 0xE9,
59 0x40, 0x40, 0xD8, 0xEC,
60
61 0xFF, 0x80, 0xC0, 0xE9,
62 0x00, 0x80, 0x00, 0xE8,
63
64 0x1F, 0xD7, 0x18, 0xBD,
65 0x3F, 0xD7, 0x22, 0xBD,
66
67 0x81, 0x04,
68 0x89, 0x04,
69 0x01, 0x04,
70 0x09, 0x04,
71
72 0xC9, 0x41, 0xC0, 0xEC,
73 0x11, 0x04,
74 0x00, 0xE0,
75
76 0x41, 0xCC, 0x41, 0xCD,
77 0x49, 0xCC, 0x49, 0xCD,
78
79 0xD1, 0x41, 0xC0, 0xEC,
80 0x51, 0xCC, 0x51, 0xCD,
81
82 0x80, 0x04,
83 0x10, 0x04,
84 0x08, 0x04,
85 0x00, 0xE0,
86
87 0x00, 0xCC, 0xC0, 0xCD,
88 0xD1, 0x49, 0xC0, 0xEC,
89
90 0x8A, 0x1F, 0x20, 0xE9,
91 0x8B, 0x3F, 0x20, 0xE9,
92
93 0x41, 0x3C, 0x41, 0xAD,
94 0x49, 0x3C, 0x49, 0xAD,
95
96 0x10, 0xCC, 0x10, 0xCD,
97 0x08, 0xCC, 0x08, 0xCD,
98
99 0xB9, 0x41, 0x49, 0xBB,
100 0x1F, 0xF0, 0x41, 0xCD,
101
102 0x51, 0x3C, 0x51, 0xAD,
103 0x00, 0x98, 0x80, 0xE9,
104
105 0x72, 0x80, 0x07, 0xEA,
106 0x24, 0x1F, 0x20, 0xE9,
107
108 0x15, 0x41, 0x49, 0xBD,
109 0x1D, 0x41, 0x51, 0xBD,
110
111 0x2E, 0x41, 0x2A, 0xB8,
112 0x34, 0x53, 0xA0, 0xE8,
113
114 0x15, 0x30,
115 0x1D, 0x30,
116 0x58, 0xE3,
117 0x00, 0xE0,
118
119 0xB5, 0x40, 0x48, 0xBD,
120 0x3D, 0x40, 0x50, 0xBD,
121
122 0x24, 0x43, 0xA0, 0xE8,
123 0x2C, 0x4B, 0xA0, 0xE8,
124
125 0x15, 0x72,
126 0x09, 0xE3,
127 0x00, 0xE0,
128 0x1D, 0x72,
129
130 0x35, 0x30,
131 0xB5, 0x30,
132 0xBD, 0x30,
133 0x3D, 0x30,
134
135 0x9C, 0x97, 0x57, 0x9F,
136 0x00, 0x80, 0x00, 0xE8,
137
138 0x6C, 0x64, 0xC8, 0xEC,
139 0x98, 0xE1,
140 0xB5, 0x05,
141
142 0xBD, 0x05,
143 0x2E, 0x30,
144 0x32, 0xC0, 0xA0, 0xE8,
145
146 0x33, 0xC0, 0xA0, 0xE8,
147 0x74, 0x64, 0xC8, 0xEC,
148
149 0x40, 0x3C, 0x40, 0xAD,
150 0x32, 0x6A,
151 0x2A, 0x30,
152
153 0x20, 0x73,
154 0x33, 0x6A,
155 0x00, 0xE0,
156 0x28, 0x73,
157
158 0x1C, 0x72,
159 0x83, 0xE2,
160 0x60, 0x80, 0x15, 0xEA,
161
162 0xB8, 0x3D, 0x28, 0xDF,
163 0x30, 0x35, 0x20, 0xDF,
164
165 0x40, 0x30,
166 0x00, 0xE0,
167 0xCC, 0xE2,
168 0x64, 0x72,
169
170 0x25, 0x42, 0x52, 0xBF,
171 0x2D, 0x42, 0x4A, 0xBF,
172
173 0x30, 0x2E, 0x30, 0xDF,
174 0x38, 0x2E, 0x38, 0xDF,
175
176 0x18, 0x1D, 0x45, 0xE9,
177 0x1E, 0x15, 0x45, 0xE9,
178
179 0x2B, 0x49, 0x51, 0xBD,
180 0x00, 0xE0,
181 0x1F, 0x73,
182
183 0x38, 0x38, 0x40, 0xAF,
184 0x30, 0x30, 0x40, 0xAF,
185
186 0x24, 0x1F, 0x24, 0xDF,
187 0x1D, 0x32, 0x20, 0xE9,
188
189 0x2C, 0x1F, 0x2C, 0xDF,
190 0x1A, 0x33, 0x20, 0xE9,
191
192 0xB0, 0x10,
193 0x08, 0xE3,
194 0x40, 0x10,
195 0xB8, 0x10,
196
197 0x26, 0xF0, 0x30, 0xCD,
198 0x2F, 0xF0, 0x38, 0xCD,
199
200 0x2B, 0x80, 0x20, 0xE9,
201 0x2A, 0x80, 0x20, 0xE9,
202
203 0xA6, 0x20,
204 0x88, 0xE2,
205 0x00, 0xE0,
206 0xAF, 0x20,
207
208 0x28, 0x2A, 0x26, 0xAF,
209 0x20, 0x2A, 0xC0, 0xAF,
210
211 0x34, 0x1F, 0x34, 0xDF,
212 0x46, 0x24, 0x46, 0xDF,
213
214 0x28, 0x30, 0x80, 0xBF,
215 0x20, 0x38, 0x80, 0xBF,
216
217 0x47, 0x24, 0x47, 0xDF,
218 0x4E, 0x2C, 0x4E, 0xDF,
219
220 0x4F, 0x2C, 0x4F, 0xDF,
221 0x56, 0x34, 0x56, 0xDF,
222
223 0x28, 0x15, 0x28, 0xDF,
224 0x20, 0x1D, 0x20, 0xDF,
225
226 0x57, 0x34, 0x57, 0xDF,
227 0x00, 0xE0,
228 0x1D, 0x05,
229
230 0x04, 0x80, 0x10, 0xEA,
231 0x89, 0xE2,
232 0x2B, 0x30,
233
234 0x3F, 0xC1, 0x1D, 0xBD,
235 0x00, 0x80, 0x00, 0xE8,
236
237 0x00, 0x80, 0x00, 0xE8,
238 0x00, 0x80, 0x00, 0xE8,
239
240 0xA0, 0x68,
241 0xBF, 0x25,
242 0x00, 0x80, 0x00, 0xE8,
243
244 0x20, 0xC0, 0x20, 0xAF,
245 0x28, 0x05,
246 0x97, 0x74,
247
248 0x00, 0xE0,
249 0x2A, 0x10,
250 0x16, 0xC0, 0x20, 0xE9,
251
252 0x04, 0x80, 0x10, 0xEA,
253 0x8C, 0xE2,
254 0x95, 0x05,
255
256 0x28, 0xC1, 0x28, 0xAD,
257 0x1F, 0xC1, 0x15, 0xBD,
258
259 0x00, 0x80, 0x00, 0xE8,
260 0x00, 0x80, 0x00, 0xE8,
261
262 0xA8, 0x67,
263 0x9F, 0x6B,
264 0x00, 0x80, 0x00, 0xE8,
265
266 0x28, 0xC0, 0x28, 0xAD,
267 0x1D, 0x25,
268 0x20, 0x05,
269
270 0x28, 0x32, 0x80, 0xAD,
271 0x40, 0x2A, 0x40, 0xBD,
272
273 0x1C, 0x80, 0x20, 0xE9,
274 0x20, 0x33, 0x20, 0xAD,
275
276 0x20, 0x73,
277 0x00, 0xE0,
278 0xB6, 0x49, 0x51, 0xBB,
279
280 0x26, 0x2F, 0xB0, 0xE8,
281 0x19, 0x20, 0x20, 0xE9,
282
283 0x35, 0x20, 0x35, 0xDF,
284 0x3D, 0x20, 0x3D, 0xDF,
285
286 0x15, 0x20, 0x15, 0xDF,
287 0x1D, 0x20, 0x1D, 0xDF,
288
289 0x26, 0xD0, 0x26, 0xCD,
290 0x29, 0x49, 0x2A, 0xB8,
291
292 0x26, 0x40, 0x80, 0xBD,
293 0x3B, 0x48, 0x50, 0xBD,
294
295 0x3E, 0x54, 0x57, 0x9F,
296 0x00, 0xE0,
297 0x82, 0xE1,
298
299 0x1E, 0xAF, 0x59, 0x9F,
300 0x00, 0x80, 0x00, 0xE8,
301
302 0x26, 0x30,
303 0x29, 0x30,
304 0x48, 0x3C, 0x48, 0xAD,
305
306 0x2B, 0x72,
307 0xC2, 0xE1,
308 0x2C, 0xC0, 0x44, 0xC2,
309
310 0x05, 0x24, 0x34, 0xBF,
311 0x0D, 0x24, 0x2C, 0xBF,
312
313 0x2D, 0x46, 0x4E, 0xBF,
314 0x25, 0x46, 0x56, 0xBF,
315
316 0x20, 0x1D, 0x6F, 0x8F,
317 0x32, 0x3E, 0x5F, 0xE9,
318
319 0x3E, 0x50, 0x56, 0x9F,
320 0x00, 0xE0,
321 0x3B, 0x30,
322
323 0x1E, 0x8F, 0x51, 0x9F,
324 0x33, 0x1E, 0x5F, 0xE9,
325
326 0x05, 0x44, 0x54, 0xB2,
327 0x0D, 0x44, 0x4C, 0xB2,
328
329 0x19, 0xC0, 0xB0, 0xE8,
330 0x34, 0xC0, 0x44, 0xC4,
331
332 0x33, 0x73,
333 0x00, 0xE0,
334 0x3E, 0x62, 0x57, 0x9F,
335
336 0x1E, 0xAF, 0x59, 0x9F,
337 0x00, 0xE0,
338 0x0D, 0x20,
339
340 0x84, 0x3E, 0x58, 0xE9,
341 0x28, 0x1D, 0x6F, 0x8F,
342
343 0x05, 0x20,
344 0x00, 0xE0,
345 0x85, 0x1E, 0x58, 0xE9,
346
347 0x9B, 0x3B, 0x33, 0xDF,
348 0x20, 0x20, 0x42, 0xAF,
349
350 0x30, 0x42, 0x56, 0x9F,
351 0x80, 0x3E, 0x57, 0xE9,
352
353 0x3F, 0x8F, 0x51, 0x9F,
354 0x30, 0x80, 0x5F, 0xE9,
355
356 0x28, 0x28, 0x24, 0xAF,
357 0x81, 0x1E, 0x57, 0xE9,
358
359 0x05, 0x47, 0x57, 0xBF,
360 0x0D, 0x47, 0x4F, 0xBF,
361
362 0x88, 0x80, 0x58, 0xE9,
363 0x1B, 0x29, 0x1B, 0xDF,
364
365 0x30, 0x1D, 0x6F, 0x8F,
366 0x3A, 0x30, 0x4F, 0xE9,
367
368 0x1C, 0x30, 0x26, 0xDF,
369 0x09, 0xE3,
370 0x3B, 0x05,
371
372 0x3E, 0x50, 0x56, 0x9F,
373 0x3B, 0x3F, 0x4F, 0xE9,
374
375 0x1E, 0x8F, 0x51, 0x9F,
376 0x00, 0xE0,
377 0xAC, 0x20,
378
379 0x2D, 0x44, 0x4C, 0xB4,
380 0x2C, 0x1C, 0xC0, 0xAF,
381
382 0x25, 0x44, 0x54, 0xB4,
383 0x00, 0xE0,
384 0xC8, 0x30,
385
386 0x30, 0x46, 0x30, 0xAF,
387 0x1B, 0x1B, 0x48, 0xAF,
388
389 0x00, 0xE0,
390 0x25, 0x20,
391 0x38, 0x2C, 0x4F, 0xE9,
392
393 0x86, 0x80, 0x57, 0xE9,
394 0x38, 0x1D, 0x6F, 0x8F,
395
396 0x28, 0x74,
397 0x00, 0xE0,
398 0x0D, 0x44, 0x4C, 0xB0,
399
400 0x05, 0x44, 0x54, 0xB0,
401 0x2D, 0x20,
402 0x9B, 0x10,
403
404 0x82, 0x3E, 0x57, 0xE9,
405 0x32, 0xF0, 0x1B, 0xCD,
406
407 0x1E, 0xBD, 0x59, 0x9F,
408 0x83, 0x1E, 0x57, 0xE9,
409
410 0x38, 0x47, 0x38, 0xAF,
411 0x34, 0x20,
412 0x2A, 0x30,
413
414 0x00, 0xE0,
415 0x0D, 0x20,
416 0x32, 0x20,
417 0x05, 0x20,
418
419 0x87, 0x80, 0x57, 0xE9,
420 0x1F, 0x54, 0x57, 0x9F,
421
422 0x17, 0x42, 0x56, 0x9F,
423 0x00, 0xE0,
424 0x3B, 0x6A,
425
426 0x3F, 0x8F, 0x51, 0x9F,
427 0x37, 0x1E, 0x4F, 0xE9,
428
429 0x37, 0x32, 0x2A, 0xAF,
430 0x00, 0xE0,
431 0x32, 0x00,
432
433 0x00, 0x80, 0x00, 0xE8,
434 0x27, 0xC0, 0x44, 0xC0,
435
436 0x36, 0x1F, 0x4F, 0xE9,
437 0x1F, 0x1F, 0x26, 0xDF,
438
439 0x37, 0x1B, 0x37, 0xBF,
440 0x17, 0x26, 0x17, 0xDF,
441
442 0x3E, 0x17, 0x4F, 0xE9,
443 0x3F, 0x3F, 0x4F, 0xE9,
444
445 0x34, 0x1F, 0x34, 0xAF,
446 0x2B, 0x05,
447 0xA7, 0x20,
448
449 0x33, 0x2B, 0x37, 0xDF,
450 0x27, 0x17, 0xC0, 0xAF,
451
452 0x34, 0x80, 0x4F, 0xE9,
453 0x00, 0x80, 0x00, 0xE8,
454
455 0x03, 0x80, 0x0A, 0xEA,
456 0x17, 0xC1, 0x2B, 0xBD,
457
458 0x00, 0x80, 0x00, 0xE8,
459 0x00, 0x80, 0x00, 0xE8,
460
461 0xB3, 0x68,
462 0x97, 0x25,
463 0x00, 0x80, 0x00, 0xE8,
464
465 0x33, 0xC0, 0x33, 0xAF,
466 0x3C, 0x27, 0x4F, 0xE9,
467
468 0x57, 0x39, 0x20, 0xE9,
469 0x28, 0x19, 0x60, 0xEC,
470
471 0x2B, 0x32, 0x20, 0xE9,
472 0x1D, 0x3B, 0x20, 0xE9,
473
474 0xB3, 0x05,
475 0x00, 0xE0,
476 0x16, 0x28, 0x20, 0xE9,
477
478 0x23, 0x3B, 0x33, 0xAD,
479 0x1E, 0x2B, 0x20, 0xE9,
480
481 0x1C, 0x80, 0x20, 0xE9,
482 0x57, 0x36, 0x20, 0xE9,
483
484 0x00, 0x80, 0xA0, 0xE9,
485 0x40, 0x40, 0xD8, 0xEC,
486
487 0xFF, 0x80, 0xC0, 0xE9,
488 0x90, 0xE2,
489 0x00, 0xE0,
490
491 0x85, 0xFF, 0x20, 0xEA,
492 0x19, 0xC8, 0xC1, 0xCD,
493
494 0x1F, 0xD7, 0x18, 0xBD,
495 0x3F, 0xD7, 0x22, 0xBD,
496
497 0x9F, 0x41, 0x49, 0xBD,
498 0x00, 0x80, 0x00, 0xE8,
499
500 0x25, 0x41, 0x49, 0xBD,
501 0x2D, 0x41, 0x51, 0xBD,
502
503 0x0D, 0x80, 0x07, 0xEA,
504 0x00, 0x80, 0x00, 0xE8,
505
506 0x35, 0x40, 0x48, 0xBD,
507 0x3D, 0x40, 0x50, 0xBD,
508
509 0x00, 0x80, 0x00, 0xE8,
510 0x25, 0x30,
511 0x2D, 0x30,
512
513 0x35, 0x30,
514 0xB5, 0x30,
515 0xBD, 0x30,
516 0x3D, 0x30,
517
518 0x9C, 0xA7, 0x5B, 0x9F,
519 0x00, 0x80, 0x00, 0xE8,
520
521 0x00, 0x80, 0x00, 0xE8,
522 0x00, 0x80, 0x00, 0xE8,
523
524 0x00, 0x80, 0x00, 0xE8,
525 0x00, 0x80, 0x00, 0xE8,
526
527 0x00, 0x80, 0x00, 0xE8,
528 0x00, 0x80, 0x00, 0xE8,
529
530 0x00, 0x80, 0x00, 0xE8,
531 0x00, 0x80, 0x00, 0xE8,
532
533 0x84, 0xFF, 0x0A, 0xEA,
534 0x00, 0x80, 0x00, 0xE8,
535
536 0xC9, 0x41, 0xC8, 0xEC,
537 0x42, 0xE1,
538 0x00, 0xE0,
539
540 0x82, 0xFF, 0x20, 0xEA,
541 0x00, 0x80, 0x00, 0xE8,
542
543 0x00, 0x80, 0x00, 0xE8,
544 0x00, 0x80, 0x00, 0xE8,
545
546 0xC8, 0x40, 0xC0, 0xEC,
547 0x00, 0x80, 0x00, 0xE8,
548
549 0x7F, 0xFF, 0x20, 0xEA,
550 0x00, 0x80, 0x00, 0xE8,
551
552 0x00, 0x80, 0x00, 0xE8,
553 0x00, 0x80, 0x00, 0xE8,
554
555};
556
557static unsigned char warp_g200_tgza[] = {
558
559 0x00, 0x98, 0xA0, 0xE9,
560 0x40, 0x40, 0xD8, 0xEC,
561
562 0xFF, 0x80, 0xC0, 0xE9,
563 0x00, 0x80, 0x00, 0xE8,
564
565 0x1F, 0xD7, 0x18, 0xBD,
566 0x3F, 0xD7, 0x22, 0xBD,
567
568 0x81, 0x04,
569 0x89, 0x04,
570 0x01, 0x04,
571 0x09, 0x04,
572
573 0xC9, 0x41, 0xC0, 0xEC,
574 0x11, 0x04,
575 0x00, 0xE0,
576
577 0x41, 0xCC, 0x41, 0xCD,
578 0x49, 0xCC, 0x49, 0xCD,
579
580 0xD1, 0x41, 0xC0, 0xEC,
581 0x51, 0xCC, 0x51, 0xCD,
582
583 0x80, 0x04,
584 0x10, 0x04,
585 0x08, 0x04,
586 0x00, 0xE0,
587
588 0x00, 0xCC, 0xC0, 0xCD,
589 0xD1, 0x49, 0xC0, 0xEC,
590
591 0x8A, 0x1F, 0x20, 0xE9,
592 0x8B, 0x3F, 0x20, 0xE9,
593
594 0x41, 0x3C, 0x41, 0xAD,
595 0x49, 0x3C, 0x49, 0xAD,
596
597 0x10, 0xCC, 0x10, 0xCD,
598 0x08, 0xCC, 0x08, 0xCD,
599
600 0xB9, 0x41, 0x49, 0xBB,
601 0x1F, 0xF0, 0x41, 0xCD,
602
603 0x51, 0x3C, 0x51, 0xAD,
604 0x00, 0x98, 0x80, 0xE9,
605
606 0x7D, 0x80, 0x07, 0xEA,
607 0x24, 0x1F, 0x20, 0xE9,
608
609 0x15, 0x41, 0x49, 0xBD,
610 0x1D, 0x41, 0x51, 0xBD,
611
612 0x2E, 0x41, 0x2A, 0xB8,
613 0x34, 0x53, 0xA0, 0xE8,
614
615 0x15, 0x30,
616 0x1D, 0x30,
617 0x58, 0xE3,
618 0x00, 0xE0,
619
620 0xB5, 0x40, 0x48, 0xBD,
621 0x3D, 0x40, 0x50, 0xBD,
622
623 0x24, 0x43, 0xA0, 0xE8,
624 0x2C, 0x4B, 0xA0, 0xE8,
625
626 0x15, 0x72,
627 0x09, 0xE3,
628 0x00, 0xE0,
629 0x1D, 0x72,
630
631 0x35, 0x30,
632 0xB5, 0x30,
633 0xBD, 0x30,
634 0x3D, 0x30,
635
636 0x9C, 0x97, 0x57, 0x9F,
637 0x00, 0x80, 0x00, 0xE8,
638
639 0x6C, 0x64, 0xC8, 0xEC,
640 0x98, 0xE1,
641 0xB5, 0x05,
642
643 0xBD, 0x05,
644 0x2E, 0x30,
645 0x32, 0xC0, 0xA0, 0xE8,
646
647 0x33, 0xC0, 0xA0, 0xE8,
648 0x74, 0x64, 0xC8, 0xEC,
649
650 0x40, 0x3C, 0x40, 0xAD,
651 0x32, 0x6A,
652 0x2A, 0x30,
653
654 0x20, 0x73,
655 0x33, 0x6A,
656 0x00, 0xE0,
657 0x28, 0x73,
658
659 0x1C, 0x72,
660 0x83, 0xE2,
661 0x6B, 0x80, 0x15, 0xEA,
662
663 0xB8, 0x3D, 0x28, 0xDF,
664 0x30, 0x35, 0x20, 0xDF,
665
666 0x40, 0x30,
667 0x00, 0xE0,
668 0xCC, 0xE2,
669 0x64, 0x72,
670
671 0x25, 0x42, 0x52, 0xBF,
672 0x2D, 0x42, 0x4A, 0xBF,
673
674 0x30, 0x2E, 0x30, 0xDF,
675 0x38, 0x2E, 0x38, 0xDF,
676
677 0x18, 0x1D, 0x45, 0xE9,
678 0x1E, 0x15, 0x45, 0xE9,
679
680 0x2B, 0x49, 0x51, 0xBD,
681 0x00, 0xE0,
682 0x1F, 0x73,
683
684 0x38, 0x38, 0x40, 0xAF,
685 0x30, 0x30, 0x40, 0xAF,
686
687 0x24, 0x1F, 0x24, 0xDF,
688 0x1D, 0x32, 0x20, 0xE9,
689
690 0x2C, 0x1F, 0x2C, 0xDF,
691 0x1A, 0x33, 0x20, 0xE9,
692
693 0xB0, 0x10,
694 0x08, 0xE3,
695 0x40, 0x10,
696 0xB8, 0x10,
697
698 0x26, 0xF0, 0x30, 0xCD,
699 0x2F, 0xF0, 0x38, 0xCD,
700
701 0x2B, 0x80, 0x20, 0xE9,
702 0x2A, 0x80, 0x20, 0xE9,
703
704 0xA6, 0x20,
705 0x88, 0xE2,
706 0x00, 0xE0,
707 0xAF, 0x20,
708
709 0x28, 0x2A, 0x26, 0xAF,
710 0x20, 0x2A, 0xC0, 0xAF,
711
712 0x34, 0x1F, 0x34, 0xDF,
713 0x46, 0x24, 0x46, 0xDF,
714
715 0x28, 0x30, 0x80, 0xBF,
716 0x20, 0x38, 0x80, 0xBF,
717
718 0x47, 0x24, 0x47, 0xDF,
719 0x4E, 0x2C, 0x4E, 0xDF,
720
721 0x4F, 0x2C, 0x4F, 0xDF,
722 0x56, 0x34, 0x56, 0xDF,
723
724 0x28, 0x15, 0x28, 0xDF,
725 0x20, 0x1D, 0x20, 0xDF,
726
727 0x57, 0x34, 0x57, 0xDF,
728 0x00, 0xE0,
729 0x1D, 0x05,
730
731 0x04, 0x80, 0x10, 0xEA,
732 0x89, 0xE2,
733 0x2B, 0x30,
734
735 0x3F, 0xC1, 0x1D, 0xBD,
736 0x00, 0x80, 0x00, 0xE8,
737
738 0x00, 0x80, 0x00, 0xE8,
739 0x00, 0x80, 0x00, 0xE8,
740
741 0xA0, 0x68,
742 0xBF, 0x25,
743 0x00, 0x80, 0x00, 0xE8,
744
745 0x20, 0xC0, 0x20, 0xAF,
746 0x28, 0x05,
747 0x97, 0x74,
748
749 0x00, 0xE0,
750 0x2A, 0x10,
751 0x16, 0xC0, 0x20, 0xE9,
752
753 0x04, 0x80, 0x10, 0xEA,
754 0x8C, 0xE2,
755 0x95, 0x05,
756
757 0x28, 0xC1, 0x28, 0xAD,
758 0x1F, 0xC1, 0x15, 0xBD,
759
760 0x00, 0x80, 0x00, 0xE8,
761 0x00, 0x80, 0x00, 0xE8,
762
763 0xA8, 0x67,
764 0x9F, 0x6B,
765 0x00, 0x80, 0x00, 0xE8,
766
767 0x28, 0xC0, 0x28, 0xAD,
768 0x1D, 0x25,
769 0x20, 0x05,
770
771 0x28, 0x32, 0x80, 0xAD,
772 0x40, 0x2A, 0x40, 0xBD,
773
774 0x1C, 0x80, 0x20, 0xE9,
775 0x20, 0x33, 0x20, 0xAD,
776
777 0x20, 0x73,
778 0x00, 0xE0,
779 0xB6, 0x49, 0x51, 0xBB,
780
781 0x26, 0x2F, 0xB0, 0xE8,
782 0x19, 0x20, 0x20, 0xE9,
783
784 0x35, 0x20, 0x35, 0xDF,
785 0x3D, 0x20, 0x3D, 0xDF,
786
787 0x15, 0x20, 0x15, 0xDF,
788 0x1D, 0x20, 0x1D, 0xDF,
789
790 0x26, 0xD0, 0x26, 0xCD,
791 0x29, 0x49, 0x2A, 0xB8,
792
793 0x26, 0x40, 0x80, 0xBD,
794 0x3B, 0x48, 0x50, 0xBD,
795
796 0x3E, 0x54, 0x57, 0x9F,
797 0x00, 0xE0,
798 0x82, 0xE1,
799
800 0x1E, 0xAF, 0x59, 0x9F,
801 0x00, 0x80, 0x00, 0xE8,
802
803 0x26, 0x30,
804 0x29, 0x30,
805 0x48, 0x3C, 0x48, 0xAD,
806
807 0x2B, 0x72,
808 0xC2, 0xE1,
809 0x2C, 0xC0, 0x44, 0xC2,
810
811 0x05, 0x24, 0x34, 0xBF,
812 0x0D, 0x24, 0x2C, 0xBF,
813
814 0x2D, 0x46, 0x4E, 0xBF,
815 0x25, 0x46, 0x56, 0xBF,
816
817 0x20, 0x1D, 0x6F, 0x8F,
818 0x32, 0x3E, 0x5F, 0xE9,
819
820 0x3E, 0x50, 0x56, 0x9F,
821 0x00, 0xE0,
822 0x3B, 0x30,
823
824 0x1E, 0x8F, 0x51, 0x9F,
825 0x33, 0x1E, 0x5F, 0xE9,
826
827 0x05, 0x44, 0x54, 0xB2,
828 0x0D, 0x44, 0x4C, 0xB2,
829
830 0x19, 0xC0, 0xB0, 0xE8,
831 0x34, 0xC0, 0x44, 0xC4,
832
833 0x33, 0x73,
834 0x00, 0xE0,
835 0x3E, 0x62, 0x57, 0x9F,
836
837 0x1E, 0xAF, 0x59, 0x9F,
838 0x00, 0xE0,
839 0x0D, 0x20,
840
841 0x84, 0x3E, 0x58, 0xE9,
842 0x28, 0x1D, 0x6F, 0x8F,
843
844 0x05, 0x20,
845 0x00, 0xE0,
846 0x85, 0x1E, 0x58, 0xE9,
847
848 0x9B, 0x3B, 0x33, 0xDF,
849 0x20, 0x20, 0x42, 0xAF,
850
851 0x30, 0x42, 0x56, 0x9F,
852 0x80, 0x3E, 0x57, 0xE9,
853
854 0x3F, 0x8F, 0x51, 0x9F,
855 0x30, 0x80, 0x5F, 0xE9,
856
857 0x28, 0x28, 0x24, 0xAF,
858 0x81, 0x1E, 0x57, 0xE9,
859
860 0x05, 0x47, 0x57, 0xBF,
861 0x0D, 0x47, 0x4F, 0xBF,
862
863 0x88, 0x80, 0x58, 0xE9,
864 0x1B, 0x29, 0x1B, 0xDF,
865
866 0x30, 0x1D, 0x6F, 0x8F,
867 0x3A, 0x30, 0x4F, 0xE9,
868
869 0x1C, 0x30, 0x26, 0xDF,
870 0x09, 0xE3,
871 0x3B, 0x05,
872
873 0x3E, 0x50, 0x56, 0x9F,
874 0x3B, 0x3F, 0x4F, 0xE9,
875
876 0x1E, 0x8F, 0x51, 0x9F,
877 0x00, 0xE0,
878 0xAC, 0x20,
879
880 0x2D, 0x44, 0x4C, 0xB4,
881 0x2C, 0x1C, 0xC0, 0xAF,
882
883 0x25, 0x44, 0x54, 0xB4,
884 0x00, 0xE0,
885 0xC8, 0x30,
886
887 0x30, 0x46, 0x30, 0xAF,
888 0x1B, 0x1B, 0x48, 0xAF,
889
890 0x00, 0xE0,
891 0x25, 0x20,
892 0x38, 0x2C, 0x4F, 0xE9,
893
894 0x86, 0x80, 0x57, 0xE9,
895 0x38, 0x1D, 0x6F, 0x8F,
896
897 0x28, 0x74,
898 0x00, 0xE0,
899 0x0D, 0x44, 0x4C, 0xB0,
900
901 0x05, 0x44, 0x54, 0xB0,
902 0x2D, 0x20,
903 0x9B, 0x10,
904
905 0x82, 0x3E, 0x57, 0xE9,
906 0x32, 0xF0, 0x1B, 0xCD,
907
908 0x1E, 0xBD, 0x59, 0x9F,
909 0x83, 0x1E, 0x57, 0xE9,
910
911 0x38, 0x47, 0x38, 0xAF,
912 0x34, 0x20,
913 0x2A, 0x30,
914
915 0x00, 0xE0,
916 0x0D, 0x20,
917 0x32, 0x20,
918 0x05, 0x20,
919
920 0x87, 0x80, 0x57, 0xE9,
921 0x1F, 0x54, 0x57, 0x9F,
922
923 0x17, 0x42, 0x56, 0x9F,
924 0x00, 0xE0,
925 0x3B, 0x6A,
926
927 0x3F, 0x8F, 0x51, 0x9F,
928 0x37, 0x1E, 0x4F, 0xE9,
929
930 0x37, 0x32, 0x2A, 0xAF,
931 0x00, 0xE0,
932 0x32, 0x00,
933
934 0x00, 0x80, 0x00, 0xE8,
935 0x27, 0xC0, 0x44, 0xC0,
936
937 0x36, 0x1F, 0x4F, 0xE9,
938 0x1F, 0x1F, 0x26, 0xDF,
939
940 0x37, 0x1B, 0x37, 0xBF,
941 0x17, 0x26, 0x17, 0xDF,
942
943 0x3E, 0x17, 0x4F, 0xE9,
944 0x3F, 0x3F, 0x4F, 0xE9,
945
946 0x34, 0x1F, 0x34, 0xAF,
947 0x2B, 0x05,
948 0xA7, 0x20,
949
950 0x33, 0x2B, 0x37, 0xDF,
951 0x27, 0x17, 0xC0, 0xAF,
952
953 0x34, 0x80, 0x4F, 0xE9,
954 0x00, 0x80, 0x00, 0xE8,
955
956 0x2D, 0x44, 0x4C, 0xB6,
957 0x25, 0x44, 0x54, 0xB6,
958
959 0x03, 0x80, 0x2A, 0xEA,
960 0x17, 0xC1, 0x2B, 0xBD,
961
962 0x2D, 0x20,
963 0x25, 0x20,
964 0x07, 0xC0, 0x44, 0xC6,
965
966 0xB3, 0x68,
967 0x97, 0x25,
968 0x00, 0x80, 0x00, 0xE8,
969
970 0x33, 0xC0, 0x33, 0xAF,
971 0x3C, 0x27, 0x4F, 0xE9,
972
973 0x1F, 0x62, 0x57, 0x9F,
974 0x00, 0x80, 0x00, 0xE8,
975
976 0x3F, 0x3D, 0x5D, 0x9F,
977 0x00, 0xE0,
978 0x07, 0x20,
979
980 0x00, 0x80, 0x00, 0xE8,
981 0x28, 0x19, 0x60, 0xEC,
982
983 0xB3, 0x05,
984 0x00, 0xE0,
985 0x00, 0x80, 0x00, 0xE8,
986
987 0x23, 0x3B, 0x33, 0xAD,
988 0x00, 0x80, 0x00, 0xE8,
989
990 0x1F, 0x26, 0x1F, 0xDF,
991 0x9D, 0x1F, 0x4F, 0xE9,
992
993 0x00, 0x80, 0x00, 0xE8,
994 0x00, 0x80, 0x00, 0xE8,
995
996 0x00, 0x80, 0x00, 0xE8,
997 0x9E, 0x3F, 0x4F, 0xE9,
998
999 0x07, 0x07, 0x1F, 0xAF,
1000 0x00, 0x80, 0x00, 0xE8,
1001
1002 0x00, 0x80, 0x00, 0xE8,
1003 0x00, 0x80, 0x00, 0xE8,
1004
1005 0x9C, 0x80, 0x4F, 0xE9,
1006 0x00, 0x80, 0x00, 0xE8,
1007
1008 0x00, 0x80, 0x00, 0xE8,
1009 0x57, 0x39, 0x20, 0xE9,
1010
1011 0x16, 0x28, 0x20, 0xE9,
1012 0x1D, 0x3B, 0x20, 0xE9,
1013
1014 0x1E, 0x2B, 0x20, 0xE9,
1015 0x2B, 0x32, 0x20, 0xE9,
1016
1017 0x1C, 0x23, 0x20, 0xE9,
1018 0x57, 0x36, 0x20, 0xE9,
1019
1020 0x00, 0x80, 0xA0, 0xE9,
1021 0x40, 0x40, 0xD8, 0xEC,
1022
1023 0xFF, 0x80, 0xC0, 0xE9,
1024 0x90, 0xE2,
1025 0x00, 0xE0,
1026
1027 0x7A, 0xFF, 0x20, 0xEA,
1028 0x19, 0xC8, 0xC1, 0xCD,
1029
1030 0x1F, 0xD7, 0x18, 0xBD,
1031 0x3F, 0xD7, 0x22, 0xBD,
1032
1033 0x9F, 0x41, 0x49, 0xBD,
1034 0x00, 0x80, 0x00, 0xE8,
1035
1036 0x25, 0x41, 0x49, 0xBD,
1037 0x2D, 0x41, 0x51, 0xBD,
1038
1039 0x0D, 0x80, 0x07, 0xEA,
1040 0x00, 0x80, 0x00, 0xE8,
1041
1042 0x35, 0x40, 0x48, 0xBD,
1043 0x3D, 0x40, 0x50, 0xBD,
1044
1045 0x00, 0x80, 0x00, 0xE8,
1046 0x25, 0x30,
1047 0x2D, 0x30,
1048
1049 0x35, 0x30,
1050 0xB5, 0x30,
1051 0xBD, 0x30,
1052 0x3D, 0x30,
1053
1054 0x9C, 0xA7, 0x5B, 0x9F,
1055 0x00, 0x80, 0x00, 0xE8,
1056
1057 0x00, 0x80, 0x00, 0xE8,
1058 0x00, 0x80, 0x00, 0xE8,
1059
1060 0x00, 0x80, 0x00, 0xE8,
1061 0x00, 0x80, 0x00, 0xE8,
1062
1063 0x00, 0x80, 0x00, 0xE8,
1064 0x00, 0x80, 0x00, 0xE8,
1065
1066 0x00, 0x80, 0x00, 0xE8,
1067 0x00, 0x80, 0x00, 0xE8,
1068
1069 0x79, 0xFF, 0x0A, 0xEA,
1070 0x00, 0x80, 0x00, 0xE8,
1071
1072 0xC9, 0x41, 0xC8, 0xEC,
1073 0x42, 0xE1,
1074 0x00, 0xE0,
1075
1076 0x77, 0xFF, 0x20, 0xEA,
1077 0x00, 0x80, 0x00, 0xE8,
1078
1079 0x00, 0x80, 0x00, 0xE8,
1080 0x00, 0x80, 0x00, 0xE8,
1081
1082 0xC8, 0x40, 0xC0, 0xEC,
1083 0x00, 0x80, 0x00, 0xE8,
1084
1085 0x74, 0xFF, 0x20, 0xEA,
1086 0x00, 0x80, 0x00, 0xE8,
1087
1088 0x00, 0x80, 0x00, 0xE8,
1089 0x00, 0x80, 0x00, 0xE8,
1090
1091};
1092
1093static unsigned char warp_g200_tgzaf[] = {
1094
1095 0x00, 0x80, 0x00, 0xE8,
1096 0x00, 0x80, 0x00, 0xE8,
1097
1098 0x00, 0x80, 0x00, 0xE8,
1099 0x00, 0x80, 0x00, 0xE8,
1100
1101 0x00, 0x80, 0x00, 0xE8,
1102 0x00, 0x80, 0x00, 0xE8,
1103
1104 0x00, 0x80, 0x00, 0xE8,
1105 0x00, 0x80, 0x00, 0xE8,
1106
1107 0x00, 0x80, 0x00, 0xE8,
1108 0x00, 0x80, 0x00, 0xE8,
1109
1110 0x00, 0x80, 0x00, 0xE8,
1111 0x00, 0x80, 0x00, 0xE8,
1112
1113 0x00, 0x80, 0x00, 0xE8,
1114 0x00, 0x80, 0x00, 0xE8,
1115
1116 0x00, 0x80, 0x00, 0xE8,
1117 0x00, 0x80, 0x00, 0xE8,
1118
1119 0x00, 0x80, 0x00, 0xE8,
1120 0x00, 0x80, 0x00, 0xE8,
1121
1122 0x00, 0x80, 0x00, 0xE8,
1123 0x00, 0x80, 0x00, 0xE8,
1124
1125 0x00, 0x98, 0xA0, 0xE9,
1126 0x40, 0x40, 0xD8, 0xEC,
1127
1128 0xFF, 0x80, 0xC0, 0xE9,
1129 0x00, 0x80, 0x00, 0xE8,
1130
1131 0x1F, 0xD7, 0x18, 0xBD,
1132 0x3F, 0xD7, 0x22, 0xBD,
1133
1134 0x81, 0x04,
1135 0x89, 0x04,
1136 0x01, 0x04,
1137 0x09, 0x04,
1138
1139 0xC9, 0x41, 0xC0, 0xEC,
1140 0x11, 0x04,
1141 0x00, 0xE0,
1142
1143 0x41, 0xCC, 0x41, 0xCD,
1144 0x49, 0xCC, 0x49, 0xCD,
1145
1146 0xD1, 0x41, 0xC0, 0xEC,
1147 0x51, 0xCC, 0x51, 0xCD,
1148
1149 0x80, 0x04,
1150 0x10, 0x04,
1151 0x08, 0x04,
1152 0x00, 0xE0,
1153
1154 0x00, 0xCC, 0xC0, 0xCD,
1155 0xD1, 0x49, 0xC0, 0xEC,
1156
1157 0x8A, 0x1F, 0x20, 0xE9,
1158 0x8B, 0x3F, 0x20, 0xE9,
1159
1160 0x41, 0x3C, 0x41, 0xAD,
1161 0x49, 0x3C, 0x49, 0xAD,
1162
1163 0x10, 0xCC, 0x10, 0xCD,
1164 0x08, 0xCC, 0x08, 0xCD,
1165
1166 0xB9, 0x41, 0x49, 0xBB,
1167 0x1F, 0xF0, 0x41, 0xCD,
1168
1169 0x51, 0x3C, 0x51, 0xAD,
1170 0x00, 0x98, 0x80, 0xE9,
1171
1172 0x83, 0x80, 0x07, 0xEA,
1173 0x24, 0x1F, 0x20, 0xE9,
1174
1175 0x21, 0x45, 0x80, 0xE8,
1176 0x1A, 0x4D, 0x80, 0xE8,
1177
1178 0x31, 0x55, 0x80, 0xE8,
1179 0x00, 0x80, 0x00, 0xE8,
1180
1181 0x15, 0x41, 0x49, 0xBD,
1182 0x1D, 0x41, 0x51, 0xBD,
1183
1184 0x2E, 0x41, 0x2A, 0xB8,
1185 0x34, 0x53, 0xA0, 0xE8,
1186
1187 0x15, 0x30,
1188 0x1D, 0x30,
1189 0x58, 0xE3,
1190 0x00, 0xE0,
1191
1192 0xB5, 0x40, 0x48, 0xBD,
1193 0x3D, 0x40, 0x50, 0xBD,
1194
1195 0x24, 0x43, 0xA0, 0xE8,
1196 0x2C, 0x4B, 0xA0, 0xE8,
1197
1198 0x15, 0x72,
1199 0x09, 0xE3,
1200 0x00, 0xE0,
1201 0x1D, 0x72,
1202
1203 0x35, 0x30,
1204 0xB5, 0x30,
1205 0xBD, 0x30,
1206 0x3D, 0x30,
1207
1208 0x9C, 0x97, 0x57, 0x9F,
1209 0x00, 0x80, 0x00, 0xE8,
1210
1211 0x6C, 0x64, 0xC8, 0xEC,
1212 0x98, 0xE1,
1213 0xB5, 0x05,
1214
1215 0xBD, 0x05,
1216 0x2E, 0x30,
1217 0x32, 0xC0, 0xA0, 0xE8,
1218
1219 0x33, 0xC0, 0xA0, 0xE8,
1220 0x74, 0x64, 0xC8, 0xEC,
1221
1222 0x40, 0x3C, 0x40, 0xAD,
1223 0x32, 0x6A,
1224 0x2A, 0x30,
1225
1226 0x20, 0x73,
1227 0x33, 0x6A,
1228 0x00, 0xE0,
1229 0x28, 0x73,
1230
1231 0x1C, 0x72,
1232 0x83, 0xE2,
1233 0x6F, 0x80, 0x15, 0xEA,
1234
1235 0xB8, 0x3D, 0x28, 0xDF,
1236 0x30, 0x35, 0x20, 0xDF,
1237
1238 0x40, 0x30,
1239 0x00, 0xE0,
1240 0xCC, 0xE2,
1241 0x64, 0x72,
1242
1243 0x25, 0x42, 0x52, 0xBF,
1244 0x2D, 0x42, 0x4A, 0xBF,
1245
1246 0x30, 0x2E, 0x30, 0xDF,
1247 0x38, 0x2E, 0x38, 0xDF,
1248
1249 0x18, 0x1D, 0x45, 0xE9,
1250 0x1E, 0x15, 0x45, 0xE9,
1251
1252 0x2B, 0x49, 0x51, 0xBD,
1253 0x00, 0xE0,
1254 0x1F, 0x73,
1255
1256 0x38, 0x38, 0x40, 0xAF,
1257 0x30, 0x30, 0x40, 0xAF,
1258
1259 0x24, 0x1F, 0x24, 0xDF,
1260 0x1D, 0x32, 0x20, 0xE9,
1261
1262 0x2C, 0x1F, 0x2C, 0xDF,
1263 0x1A, 0x33, 0x20, 0xE9,
1264
1265 0xB0, 0x10,
1266 0x08, 0xE3,
1267 0x40, 0x10,
1268 0xB8, 0x10,
1269
1270 0x26, 0xF0, 0x30, 0xCD,
1271 0x2F, 0xF0, 0x38, 0xCD,
1272
1273 0x2B, 0x80, 0x20, 0xE9,
1274 0x2A, 0x80, 0x20, 0xE9,
1275
1276 0xA6, 0x20,
1277 0x88, 0xE2,
1278 0x00, 0xE0,
1279 0xAF, 0x20,
1280
1281 0x28, 0x2A, 0x26, 0xAF,
1282 0x20, 0x2A, 0xC0, 0xAF,
1283
1284 0x34, 0x1F, 0x34, 0xDF,
1285 0x46, 0x24, 0x46, 0xDF,
1286
1287 0x28, 0x30, 0x80, 0xBF,
1288 0x20, 0x38, 0x80, 0xBF,
1289
1290 0x47, 0x24, 0x47, 0xDF,
1291 0x4E, 0x2C, 0x4E, 0xDF,
1292
1293 0x4F, 0x2C, 0x4F, 0xDF,
1294 0x56, 0x34, 0x56, 0xDF,
1295
1296 0x28, 0x15, 0x28, 0xDF,
1297 0x20, 0x1D, 0x20, 0xDF,
1298
1299 0x57, 0x34, 0x57, 0xDF,
1300 0x00, 0xE0,
1301 0x1D, 0x05,
1302
1303 0x04, 0x80, 0x10, 0xEA,
1304 0x89, 0xE2,
1305 0x2B, 0x30,
1306
1307 0x3F, 0xC1, 0x1D, 0xBD,
1308 0x00, 0x80, 0x00, 0xE8,
1309
1310 0x00, 0x80, 0x00, 0xE8,
1311 0x00, 0x80, 0x00, 0xE8,
1312
1313 0xA0, 0x68,
1314 0xBF, 0x25,
1315 0x00, 0x80, 0x00, 0xE8,
1316
1317 0x20, 0xC0, 0x20, 0xAF,
1318 0x28, 0x05,
1319 0x97, 0x74,
1320
1321 0x00, 0xE0,
1322 0x2A, 0x10,
1323 0x16, 0xC0, 0x20, 0xE9,
1324
1325 0x04, 0x80, 0x10, 0xEA,
1326 0x8C, 0xE2,
1327 0x95, 0x05,
1328
1329 0x28, 0xC1, 0x28, 0xAD,
1330 0x1F, 0xC1, 0x15, 0xBD,
1331
1332 0x00, 0x80, 0x00, 0xE8,
1333 0x00, 0x80, 0x00, 0xE8,
1334
1335 0xA8, 0x67,
1336 0x9F, 0x6B,
1337 0x00, 0x80, 0x00, 0xE8,
1338
1339 0x28, 0xC0, 0x28, 0xAD,
1340 0x1D, 0x25,
1341 0x20, 0x05,
1342
1343 0x28, 0x32, 0x80, 0xAD,
1344 0x40, 0x2A, 0x40, 0xBD,
1345
1346 0x1C, 0x80, 0x20, 0xE9,
1347 0x20, 0x33, 0x20, 0xAD,
1348
1349 0x20, 0x73,
1350 0x00, 0xE0,
1351 0xB6, 0x49, 0x51, 0xBB,
1352
1353 0x26, 0x2F, 0xB0, 0xE8,
1354 0x19, 0x20, 0x20, 0xE9,
1355
1356 0x35, 0x20, 0x35, 0xDF,
1357 0x3D, 0x20, 0x3D, 0xDF,
1358
1359 0x15, 0x20, 0x15, 0xDF,
1360 0x1D, 0x20, 0x1D, 0xDF,
1361
1362 0x26, 0xD0, 0x26, 0xCD,
1363 0x29, 0x49, 0x2A, 0xB8,
1364
1365 0x26, 0x40, 0x80, 0xBD,
1366 0x3B, 0x48, 0x50, 0xBD,
1367
1368 0x3E, 0x54, 0x57, 0x9F,
1369 0x00, 0xE0,
1370 0x82, 0xE1,
1371
1372 0x1E, 0xAF, 0x59, 0x9F,
1373 0x00, 0x80, 0x00, 0xE8,
1374
1375 0x26, 0x30,
1376 0x29, 0x30,
1377 0x48, 0x3C, 0x48, 0xAD,
1378
1379 0x2B, 0x72,
1380 0xC2, 0xE1,
1381 0x2C, 0xC0, 0x44, 0xC2,
1382
1383 0x05, 0x24, 0x34, 0xBF,
1384 0x0D, 0x24, 0x2C, 0xBF,
1385
1386 0x2D, 0x46, 0x4E, 0xBF,
1387 0x25, 0x46, 0x56, 0xBF,
1388
1389 0x20, 0x1D, 0x6F, 0x8F,
1390 0x32, 0x3E, 0x5F, 0xE9,
1391
1392 0x3E, 0x50, 0x56, 0x9F,
1393 0x00, 0xE0,
1394 0x3B, 0x30,
1395
1396 0x1E, 0x8F, 0x51, 0x9F,
1397 0x33, 0x1E, 0x5F, 0xE9,
1398
1399 0x05, 0x44, 0x54, 0xB2,
1400 0x0D, 0x44, 0x4C, 0xB2,
1401
1402 0x19, 0xC0, 0xB0, 0xE8,
1403 0x34, 0xC0, 0x44, 0xC4,
1404
1405 0x33, 0x73,
1406 0x00, 0xE0,
1407 0x3E, 0x62, 0x57, 0x9F,
1408
1409 0x1E, 0xAF, 0x59, 0x9F,
1410 0x00, 0xE0,
1411 0x0D, 0x20,
1412
1413 0x84, 0x3E, 0x58, 0xE9,
1414 0x28, 0x1D, 0x6F, 0x8F,
1415
1416 0x05, 0x20,
1417 0x00, 0xE0,
1418 0x85, 0x1E, 0x58, 0xE9,
1419
1420 0x9B, 0x3B, 0x33, 0xDF,
1421 0x20, 0x20, 0x42, 0xAF,
1422
1423 0x30, 0x42, 0x56, 0x9F,
1424 0x80, 0x3E, 0x57, 0xE9,
1425
1426 0x3F, 0x8F, 0x51, 0x9F,
1427 0x30, 0x80, 0x5F, 0xE9,
1428
1429 0x28, 0x28, 0x24, 0xAF,
1430 0x81, 0x1E, 0x57, 0xE9,
1431
1432 0x05, 0x47, 0x57, 0xBF,
1433 0x0D, 0x47, 0x4F, 0xBF,
1434
1435 0x88, 0x80, 0x58, 0xE9,
1436 0x1B, 0x29, 0x1B, 0xDF,
1437
1438 0x30, 0x1D, 0x6F, 0x8F,
1439 0x3A, 0x30, 0x4F, 0xE9,
1440
1441 0x1C, 0x30, 0x26, 0xDF,
1442 0x09, 0xE3,
1443 0x3B, 0x05,
1444
1445 0x3E, 0x50, 0x56, 0x9F,
1446 0x3B, 0x3F, 0x4F, 0xE9,
1447
1448 0x1E, 0x8F, 0x51, 0x9F,
1449 0x00, 0xE0,
1450 0xAC, 0x20,
1451
1452 0x2D, 0x44, 0x4C, 0xB4,
1453 0x2C, 0x1C, 0xC0, 0xAF,
1454
1455 0x25, 0x44, 0x54, 0xB4,
1456 0x00, 0xE0,
1457 0xC8, 0x30,
1458
1459 0x30, 0x46, 0x30, 0xAF,
1460 0x1B, 0x1B, 0x48, 0xAF,
1461
1462 0x00, 0xE0,
1463 0x25, 0x20,
1464 0x38, 0x2C, 0x4F, 0xE9,
1465
1466 0x86, 0x80, 0x57, 0xE9,
1467 0x38, 0x1D, 0x6F, 0x8F,
1468
1469 0x28, 0x74,
1470 0x00, 0xE0,
1471 0x0D, 0x44, 0x4C, 0xB0,
1472
1473 0x05, 0x44, 0x54, 0xB0,
1474 0x2D, 0x20,
1475 0x9B, 0x10,
1476
1477 0x82, 0x3E, 0x57, 0xE9,
1478 0x32, 0xF0, 0x1B, 0xCD,
1479
1480 0x1E, 0xBD, 0x59, 0x9F,
1481 0x83, 0x1E, 0x57, 0xE9,
1482
1483 0x38, 0x47, 0x38, 0xAF,
1484 0x34, 0x20,
1485 0x2A, 0x30,
1486
1487 0x00, 0xE0,
1488 0x0D, 0x20,
1489 0x32, 0x20,
1490 0x05, 0x20,
1491
1492 0x87, 0x80, 0x57, 0xE9,
1493 0x1F, 0x54, 0x57, 0x9F,
1494
1495 0x17, 0x42, 0x56, 0x9F,
1496 0x00, 0xE0,
1497 0x3B, 0x6A,
1498
1499 0x3F, 0x8F, 0x51, 0x9F,
1500 0x37, 0x1E, 0x4F, 0xE9,
1501
1502 0x37, 0x32, 0x2A, 0xAF,
1503 0x00, 0xE0,
1504 0x32, 0x00,
1505
1506 0x00, 0x80, 0x00, 0xE8,
1507 0x27, 0xC0, 0x44, 0xC0,
1508
1509 0x36, 0x1F, 0x4F, 0xE9,
1510 0x1F, 0x1F, 0x26, 0xDF,
1511
1512 0x37, 0x1B, 0x37, 0xBF,
1513 0x17, 0x26, 0x17, 0xDF,
1514
1515 0x3E, 0x17, 0x4F, 0xE9,
1516 0x3F, 0x3F, 0x4F, 0xE9,
1517
1518 0x34, 0x1F, 0x34, 0xAF,
1519 0x2B, 0x05,
1520 0xA7, 0x20,
1521
1522 0x33, 0x2B, 0x37, 0xDF,
1523 0x27, 0x17, 0xC0, 0xAF,
1524
1525 0x34, 0x80, 0x4F, 0xE9,
1526 0x00, 0x80, 0x00, 0xE8,
1527
1528 0x0D, 0x21, 0x1A, 0xB6,
1529 0x05, 0x21, 0x31, 0xB6,
1530
1531 0x2D, 0x44, 0x4C, 0xB6,
1532 0x25, 0x44, 0x54, 0xB6,
1533
1534 0x03, 0x80, 0x2A, 0xEA,
1535 0x17, 0xC1, 0x2B, 0xBD,
1536
1537 0x0D, 0x20,
1538 0x05, 0x20,
1539 0x2F, 0xC0, 0x21, 0xC6,
1540
1541 0xB3, 0x68,
1542 0x97, 0x25,
1543 0x00, 0x80, 0x00, 0xE8,
1544
1545 0x33, 0xC0, 0x33, 0xAF,
1546 0x3C, 0x27, 0x4F, 0xE9,
1547
1548 0x00, 0xE0,
1549 0x25, 0x20,
1550 0x07, 0xC0, 0x44, 0xC6,
1551
1552 0x17, 0x50, 0x56, 0x9F,
1553 0x00, 0xE0,
1554 0x2D, 0x20,
1555
1556 0x37, 0x0F, 0x5C, 0x9F,
1557 0x00, 0xE0,
1558 0x2F, 0x20,
1559
1560 0x1F, 0x62, 0x57, 0x9F,
1561 0x00, 0xE0,
1562 0x07, 0x20,
1563
1564 0x3F, 0x3D, 0x5D, 0x9F,
1565 0x00, 0x80, 0x00, 0xE8,
1566
1567 0x00, 0x80, 0x00, 0xE8,
1568 0x28, 0x19, 0x60, 0xEC,
1569
1570 0xB3, 0x05,
1571 0x00, 0xE0,
1572 0x17, 0x26, 0x17, 0xDF,
1573
1574 0x23, 0x3B, 0x33, 0xAD,
1575 0x35, 0x17, 0x4F, 0xE9,
1576
1577 0x1F, 0x26, 0x1F, 0xDF,
1578 0x9D, 0x1F, 0x4F, 0xE9,
1579
1580 0x9E, 0x3F, 0x4F, 0xE9,
1581 0x39, 0x37, 0x4F, 0xE9,
1582
1583 0x2F, 0x2F, 0x17, 0xAF,
1584 0x00, 0x80, 0x00, 0xE8,
1585
1586 0x07, 0x07, 0x1F, 0xAF,
1587 0x00, 0x80, 0x00, 0xE8,
1588
1589 0x31, 0x80, 0x4F, 0xE9,
1590 0x00, 0x80, 0x00, 0xE8,
1591
1592 0x9C, 0x80, 0x4F, 0xE9,
1593 0x00, 0x80, 0x00, 0xE8,
1594
1595 0x00, 0x80, 0x00, 0xE8,
1596 0x57, 0x39, 0x20, 0xE9,
1597
1598 0x16, 0x28, 0x20, 0xE9,
1599 0x1D, 0x3B, 0x20, 0xE9,
1600
1601 0x1E, 0x2B, 0x20, 0xE9,
1602 0x2B, 0x32, 0x20, 0xE9,
1603
1604 0x1C, 0x23, 0x20, 0xE9,
1605 0x57, 0x36, 0x20, 0xE9,
1606
1607 0x00, 0x80, 0xA0, 0xE9,
1608 0x40, 0x40, 0xD8, 0xEC,
1609
1610 0xFF, 0x80, 0xC0, 0xE9,
1611 0x90, 0xE2,
1612 0x00, 0xE0,
1613
1614 0x74, 0xFF, 0x20, 0xEA,
1615 0x19, 0xC8, 0xC1, 0xCD,
1616
1617 0x1F, 0xD7, 0x18, 0xBD,
1618 0x3F, 0xD7, 0x22, 0xBD,
1619
1620 0x9F, 0x41, 0x49, 0xBD,
1621 0x00, 0x80, 0x00, 0xE8,
1622
1623 0x25, 0x41, 0x49, 0xBD,
1624 0x2D, 0x41, 0x51, 0xBD,
1625
1626 0x0D, 0x80, 0x07, 0xEA,
1627 0x00, 0x80, 0x00, 0xE8,
1628
1629 0x35, 0x40, 0x48, 0xBD,
1630 0x3D, 0x40, 0x50, 0xBD,
1631
1632 0x00, 0x80, 0x00, 0xE8,
1633 0x25, 0x30,
1634 0x2D, 0x30,
1635
1636 0x35, 0x30,
1637 0xB5, 0x30,
1638 0xBD, 0x30,
1639 0x3D, 0x30,
1640
1641 0x9C, 0xA7, 0x5B, 0x9F,
1642 0x00, 0x80, 0x00, 0xE8,
1643
1644 0x00, 0x80, 0x00, 0xE8,
1645 0x00, 0x80, 0x00, 0xE8,
1646
1647 0x00, 0x80, 0x00, 0xE8,
1648 0x00, 0x80, 0x00, 0xE8,
1649
1650 0x00, 0x80, 0x00, 0xE8,
1651 0x00, 0x80, 0x00, 0xE8,
1652
1653 0x00, 0x80, 0x00, 0xE8,
1654 0x00, 0x80, 0x00, 0xE8,
1655
1656 0x73, 0xFF, 0x0A, 0xEA,
1657 0x00, 0x80, 0x00, 0xE8,
1658
1659 0xC9, 0x41, 0xC8, 0xEC,
1660 0x42, 0xE1,
1661 0x00, 0xE0,
1662
1663 0x71, 0xFF, 0x20, 0xEA,
1664 0x00, 0x80, 0x00, 0xE8,
1665
1666 0x00, 0x80, 0x00, 0xE8,
1667 0x00, 0x80, 0x00, 0xE8,
1668
1669 0xC8, 0x40, 0xC0, 0xEC,
1670 0x00, 0x80, 0x00, 0xE8,
1671
1672 0x6E, 0xFF, 0x20, 0xEA,
1673 0x00, 0x80, 0x00, 0xE8,
1674
1675 0x00, 0x80, 0x00, 0xE8,
1676 0x00, 0x80, 0x00, 0xE8,
1677
1678};
1679
1680static unsigned char warp_g200_tgzf[] = {
1681
1682 0x00, 0x80, 0x00, 0xE8,
1683 0x00, 0x80, 0x00, 0xE8,
1684
1685 0x00, 0x80, 0x00, 0xE8,
1686 0x00, 0x80, 0x00, 0xE8,
1687
1688 0x00, 0x80, 0x00, 0xE8,
1689 0x00, 0x80, 0x00, 0xE8,
1690
1691 0x00, 0x80, 0x00, 0xE8,
1692 0x00, 0x80, 0x00, 0xE8,
1693
1694 0x00, 0x80, 0x00, 0xE8,
1695 0x00, 0x80, 0x00, 0xE8,
1696
1697 0x00, 0x80, 0x00, 0xE8,
1698 0x00, 0x80, 0x00, 0xE8,
1699
1700 0x00, 0x80, 0x00, 0xE8,
1701 0x00, 0x80, 0x00, 0xE8,
1702
1703 0x00, 0x80, 0x00, 0xE8,
1704 0x00, 0x80, 0x00, 0xE8,
1705
1706 0x00, 0x80, 0x00, 0xE8,
1707 0x00, 0x80, 0x00, 0xE8,
1708
1709 0x00, 0x80, 0x00, 0xE8,
1710 0x00, 0x80, 0x00, 0xE8,
1711
1712 0x00, 0x98, 0xA0, 0xE9,
1713 0x40, 0x40, 0xD8, 0xEC,
1714
1715 0xFF, 0x80, 0xC0, 0xE9,
1716 0x00, 0x80, 0x00, 0xE8,
1717
1718 0x1F, 0xD7, 0x18, 0xBD,
1719 0x3F, 0xD7, 0x22, 0xBD,
1720
1721 0x81, 0x04,
1722 0x89, 0x04,
1723 0x01, 0x04,
1724 0x09, 0x04,
1725
1726 0xC9, 0x41, 0xC0, 0xEC,
1727 0x11, 0x04,
1728 0x00, 0xE0,
1729
1730 0x41, 0xCC, 0x41, 0xCD,
1731 0x49, 0xCC, 0x49, 0xCD,
1732
1733 0xD1, 0x41, 0xC0, 0xEC,
1734 0x51, 0xCC, 0x51, 0xCD,
1735
1736 0x80, 0x04,
1737 0x10, 0x04,
1738 0x08, 0x04,
1739 0x00, 0xE0,
1740
1741 0x00, 0xCC, 0xC0, 0xCD,
1742 0xD1, 0x49, 0xC0, 0xEC,
1743
1744 0x8A, 0x1F, 0x20, 0xE9,
1745 0x8B, 0x3F, 0x20, 0xE9,
1746
1747 0x41, 0x3C, 0x41, 0xAD,
1748 0x49, 0x3C, 0x49, 0xAD,
1749
1750 0x10, 0xCC, 0x10, 0xCD,
1751 0x08, 0xCC, 0x08, 0xCD,
1752
1753 0xB9, 0x41, 0x49, 0xBB,
1754 0x1F, 0xF0, 0x41, 0xCD,
1755
1756 0x51, 0x3C, 0x51, 0xAD,
1757 0x00, 0x98, 0x80, 0xE9,
1758
1759 0x7F, 0x80, 0x07, 0xEA,
1760 0x24, 0x1F, 0x20, 0xE9,
1761
1762 0x21, 0x45, 0x80, 0xE8,
1763 0x1A, 0x4D, 0x80, 0xE8,
1764
1765 0x31, 0x55, 0x80, 0xE8,
1766 0x00, 0x80, 0x00, 0xE8,
1767
1768 0x15, 0x41, 0x49, 0xBD,
1769 0x1D, 0x41, 0x51, 0xBD,
1770
1771 0x2E, 0x41, 0x2A, 0xB8,
1772 0x34, 0x53, 0xA0, 0xE8,
1773
1774 0x15, 0x30,
1775 0x1D, 0x30,
1776 0x58, 0xE3,
1777 0x00, 0xE0,
1778
1779 0xB5, 0x40, 0x48, 0xBD,
1780 0x3D, 0x40, 0x50, 0xBD,
1781
1782 0x24, 0x43, 0xA0, 0xE8,
1783 0x2C, 0x4B, 0xA0, 0xE8,
1784
1785 0x15, 0x72,
1786 0x09, 0xE3,
1787 0x00, 0xE0,
1788 0x1D, 0x72,
1789
1790 0x35, 0x30,
1791 0xB5, 0x30,
1792 0xBD, 0x30,
1793 0x3D, 0x30,
1794
1795 0x9C, 0x97, 0x57, 0x9F,
1796 0x00, 0x80, 0x00, 0xE8,
1797
1798 0x6C, 0x64, 0xC8, 0xEC,
1799 0x98, 0xE1,
1800 0xB5, 0x05,
1801
1802 0xBD, 0x05,
1803 0x2E, 0x30,
1804 0x32, 0xC0, 0xA0, 0xE8,
1805
1806 0x33, 0xC0, 0xA0, 0xE8,
1807 0x74, 0x64, 0xC8, 0xEC,
1808
1809 0x40, 0x3C, 0x40, 0xAD,
1810 0x32, 0x6A,
1811 0x2A, 0x30,
1812
1813 0x20, 0x73,
1814 0x33, 0x6A,
1815 0x00, 0xE0,
1816 0x28, 0x73,
1817
1818 0x1C, 0x72,
1819 0x83, 0xE2,
1820 0x6B, 0x80, 0x15, 0xEA,
1821
1822 0xB8, 0x3D, 0x28, 0xDF,
1823 0x30, 0x35, 0x20, 0xDF,
1824
1825 0x40, 0x30,
1826 0x00, 0xE0,
1827 0xCC, 0xE2,
1828 0x64, 0x72,
1829
1830 0x25, 0x42, 0x52, 0xBF,
1831 0x2D, 0x42, 0x4A, 0xBF,
1832
1833 0x30, 0x2E, 0x30, 0xDF,
1834 0x38, 0x2E, 0x38, 0xDF,
1835
1836 0x18, 0x1D, 0x45, 0xE9,
1837 0x1E, 0x15, 0x45, 0xE9,
1838
1839 0x2B, 0x49, 0x51, 0xBD,
1840 0x00, 0xE0,
1841 0x1F, 0x73,
1842
1843 0x38, 0x38, 0x40, 0xAF,
1844 0x30, 0x30, 0x40, 0xAF,
1845
1846 0x24, 0x1F, 0x24, 0xDF,
1847 0x1D, 0x32, 0x20, 0xE9,
1848
1849 0x2C, 0x1F, 0x2C, 0xDF,
1850 0x1A, 0x33, 0x20, 0xE9,
1851
1852 0xB0, 0x10,
1853 0x08, 0xE3,
1854 0x40, 0x10,
1855 0xB8, 0x10,
1856
1857 0x26, 0xF0, 0x30, 0xCD,
1858 0x2F, 0xF0, 0x38, 0xCD,
1859
1860 0x2B, 0x80, 0x20, 0xE9,
1861 0x2A, 0x80, 0x20, 0xE9,
1862
1863 0xA6, 0x20,
1864 0x88, 0xE2,
1865 0x00, 0xE0,
1866 0xAF, 0x20,
1867
1868 0x28, 0x2A, 0x26, 0xAF,
1869 0x20, 0x2A, 0xC0, 0xAF,
1870
1871 0x34, 0x1F, 0x34, 0xDF,
1872 0x46, 0x24, 0x46, 0xDF,
1873
1874 0x28, 0x30, 0x80, 0xBF,
1875 0x20, 0x38, 0x80, 0xBF,
1876
1877 0x47, 0x24, 0x47, 0xDF,
1878 0x4E, 0x2C, 0x4E, 0xDF,
1879
1880 0x4F, 0x2C, 0x4F, 0xDF,
1881 0x56, 0x34, 0x56, 0xDF,
1882
1883 0x28, 0x15, 0x28, 0xDF,
1884 0x20, 0x1D, 0x20, 0xDF,
1885
1886 0x57, 0x34, 0x57, 0xDF,
1887 0x00, 0xE0,
1888 0x1D, 0x05,
1889
1890 0x04, 0x80, 0x10, 0xEA,
1891 0x89, 0xE2,
1892 0x2B, 0x30,
1893
1894 0x3F, 0xC1, 0x1D, 0xBD,
1895 0x00, 0x80, 0x00, 0xE8,
1896
1897 0x00, 0x80, 0x00, 0xE8,
1898 0x00, 0x80, 0x00, 0xE8,
1899
1900 0xA0, 0x68,
1901 0xBF, 0x25,
1902 0x00, 0x80, 0x00, 0xE8,
1903
1904 0x20, 0xC0, 0x20, 0xAF,
1905 0x28, 0x05,
1906 0x97, 0x74,
1907
1908 0x00, 0xE0,
1909 0x2A, 0x10,
1910 0x16, 0xC0, 0x20, 0xE9,
1911
1912 0x04, 0x80, 0x10, 0xEA,
1913 0x8C, 0xE2,
1914 0x95, 0x05,
1915
1916 0x28, 0xC1, 0x28, 0xAD,
1917 0x1F, 0xC1, 0x15, 0xBD,
1918
1919 0x00, 0x80, 0x00, 0xE8,
1920 0x00, 0x80, 0x00, 0xE8,
1921
1922 0xA8, 0x67,
1923 0x9F, 0x6B,
1924 0x00, 0x80, 0x00, 0xE8,
1925
1926 0x28, 0xC0, 0x28, 0xAD,
1927 0x1D, 0x25,
1928 0x20, 0x05,
1929
1930 0x28, 0x32, 0x80, 0xAD,
1931 0x40, 0x2A, 0x40, 0xBD,
1932
1933 0x1C, 0x80, 0x20, 0xE9,
1934 0x20, 0x33, 0x20, 0xAD,
1935
1936 0x20, 0x73,
1937 0x00, 0xE0,
1938 0xB6, 0x49, 0x51, 0xBB,
1939
1940 0x26, 0x2F, 0xB0, 0xE8,
1941 0x19, 0x20, 0x20, 0xE9,
1942
1943 0x35, 0x20, 0x35, 0xDF,
1944 0x3D, 0x20, 0x3D, 0xDF,
1945
1946 0x15, 0x20, 0x15, 0xDF,
1947 0x1D, 0x20, 0x1D, 0xDF,
1948
1949 0x26, 0xD0, 0x26, 0xCD,
1950 0x29, 0x49, 0x2A, 0xB8,
1951
1952 0x26, 0x40, 0x80, 0xBD,
1953 0x3B, 0x48, 0x50, 0xBD,
1954
1955 0x3E, 0x54, 0x57, 0x9F,
1956 0x00, 0xE0,
1957 0x82, 0xE1,
1958
1959 0x1E, 0xAF, 0x59, 0x9F,
1960 0x00, 0x80, 0x00, 0xE8,
1961
1962 0x26, 0x30,
1963 0x29, 0x30,
1964 0x48, 0x3C, 0x48, 0xAD,
1965
1966 0x2B, 0x72,
1967 0xC2, 0xE1,
1968 0x2C, 0xC0, 0x44, 0xC2,
1969
1970 0x05, 0x24, 0x34, 0xBF,
1971 0x0D, 0x24, 0x2C, 0xBF,
1972
1973 0x2D, 0x46, 0x4E, 0xBF,
1974 0x25, 0x46, 0x56, 0xBF,
1975
1976 0x20, 0x1D, 0x6F, 0x8F,
1977 0x32, 0x3E, 0x5F, 0xE9,
1978
1979 0x3E, 0x50, 0x56, 0x9F,
1980 0x00, 0xE0,
1981 0x3B, 0x30,
1982
1983 0x1E, 0x8F, 0x51, 0x9F,
1984 0x33, 0x1E, 0x5F, 0xE9,
1985
1986 0x05, 0x44, 0x54, 0xB2,
1987 0x0D, 0x44, 0x4C, 0xB2,
1988
1989 0x19, 0xC0, 0xB0, 0xE8,
1990 0x34, 0xC0, 0x44, 0xC4,
1991
1992 0x33, 0x73,
1993 0x00, 0xE0,
1994 0x3E, 0x62, 0x57, 0x9F,
1995
1996 0x1E, 0xAF, 0x59, 0x9F,
1997 0x00, 0xE0,
1998 0x0D, 0x20,
1999
2000 0x84, 0x3E, 0x58, 0xE9,
2001 0x28, 0x1D, 0x6F, 0x8F,
2002
2003 0x05, 0x20,
2004 0x00, 0xE0,
2005 0x85, 0x1E, 0x58, 0xE9,
2006
2007 0x9B, 0x3B, 0x33, 0xDF,
2008 0x20, 0x20, 0x42, 0xAF,
2009
2010 0x30, 0x42, 0x56, 0x9F,
2011 0x80, 0x3E, 0x57, 0xE9,
2012
2013 0x3F, 0x8F, 0x51, 0x9F,
2014 0x30, 0x80, 0x5F, 0xE9,
2015
2016 0x28, 0x28, 0x24, 0xAF,
2017 0x81, 0x1E, 0x57, 0xE9,
2018
2019 0x05, 0x47, 0x57, 0xBF,
2020 0x0D, 0x47, 0x4F, 0xBF,
2021
2022 0x88, 0x80, 0x58, 0xE9,
2023 0x1B, 0x29, 0x1B, 0xDF,
2024
2025 0x30, 0x1D, 0x6F, 0x8F,
2026 0x3A, 0x30, 0x4F, 0xE9,
2027
2028 0x1C, 0x30, 0x26, 0xDF,
2029 0x09, 0xE3,
2030 0x3B, 0x05,
2031
2032 0x3E, 0x50, 0x56, 0x9F,
2033 0x3B, 0x3F, 0x4F, 0xE9,
2034
2035 0x1E, 0x8F, 0x51, 0x9F,
2036 0x00, 0xE0,
2037 0xAC, 0x20,
2038
2039 0x2D, 0x44, 0x4C, 0xB4,
2040 0x2C, 0x1C, 0xC0, 0xAF,
2041
2042 0x25, 0x44, 0x54, 0xB4,
2043 0x00, 0xE0,
2044 0xC8, 0x30,
2045
2046 0x30, 0x46, 0x30, 0xAF,
2047 0x1B, 0x1B, 0x48, 0xAF,
2048
2049 0x00, 0xE0,
2050 0x25, 0x20,
2051 0x38, 0x2C, 0x4F, 0xE9,
2052
2053 0x86, 0x80, 0x57, 0xE9,
2054 0x38, 0x1D, 0x6F, 0x8F,
2055
2056 0x28, 0x74,
2057 0x00, 0xE0,
2058 0x0D, 0x44, 0x4C, 0xB0,
2059
2060 0x05, 0x44, 0x54, 0xB0,
2061 0x2D, 0x20,
2062 0x9B, 0x10,
2063
2064 0x82, 0x3E, 0x57, 0xE9,
2065 0x32, 0xF0, 0x1B, 0xCD,
2066
2067 0x1E, 0xBD, 0x59, 0x9F,
2068 0x83, 0x1E, 0x57, 0xE9,
2069
2070 0x38, 0x47, 0x38, 0xAF,
2071 0x34, 0x20,
2072 0x2A, 0x30,
2073
2074 0x00, 0xE0,
2075 0x0D, 0x20,
2076 0x32, 0x20,
2077 0x05, 0x20,
2078
2079 0x87, 0x80, 0x57, 0xE9,
2080 0x1F, 0x54, 0x57, 0x9F,
2081
2082 0x17, 0x42, 0x56, 0x9F,
2083 0x00, 0xE0,
2084 0x3B, 0x6A,
2085
2086 0x3F, 0x8F, 0x51, 0x9F,
2087 0x37, 0x1E, 0x4F, 0xE9,
2088
2089 0x37, 0x32, 0x2A, 0xAF,
2090 0x00, 0xE0,
2091 0x32, 0x00,
2092
2093 0x00, 0x80, 0x00, 0xE8,
2094 0x27, 0xC0, 0x44, 0xC0,
2095
2096 0x36, 0x1F, 0x4F, 0xE9,
2097 0x1F, 0x1F, 0x26, 0xDF,
2098
2099 0x37, 0x1B, 0x37, 0xBF,
2100 0x17, 0x26, 0x17, 0xDF,
2101
2102 0x3E, 0x17, 0x4F, 0xE9,
2103 0x3F, 0x3F, 0x4F, 0xE9,
2104
2105 0x34, 0x1F, 0x34, 0xAF,
2106 0x2B, 0x05,
2107 0xA7, 0x20,
2108
2109 0x33, 0x2B, 0x37, 0xDF,
2110 0x27, 0x17, 0xC0, 0xAF,
2111
2112 0x34, 0x80, 0x4F, 0xE9,
2113 0x00, 0x80, 0x00, 0xE8,
2114
2115 0x0D, 0x21, 0x1A, 0xB6,
2116 0x05, 0x21, 0x31, 0xB6,
2117
2118 0x03, 0x80, 0x2A, 0xEA,
2119 0x17, 0xC1, 0x2B, 0xBD,
2120
2121 0x0D, 0x20,
2122 0x05, 0x20,
2123 0x2F, 0xC0, 0x21, 0xC6,
2124
2125 0xB3, 0x68,
2126 0x97, 0x25,
2127 0x00, 0x80, 0x00, 0xE8,
2128
2129 0x33, 0xC0, 0x33, 0xAF,
2130 0x3C, 0x27, 0x4F, 0xE9,
2131
2132 0x17, 0x50, 0x56, 0x9F,
2133 0x00, 0x80, 0x00, 0xE8,
2134
2135 0x37, 0x0F, 0x5C, 0x9F,
2136 0x00, 0xE0,
2137 0x2F, 0x20,
2138
2139 0x00, 0x80, 0x00, 0xE8,
2140 0x28, 0x19, 0x60, 0xEC,
2141
2142 0xB3, 0x05,
2143 0x00, 0xE0,
2144 0x00, 0x80, 0x00, 0xE8,
2145
2146 0x23, 0x3B, 0x33, 0xAD,
2147 0x00, 0x80, 0x00, 0xE8,
2148
2149 0x17, 0x26, 0x17, 0xDF,
2150 0x35, 0x17, 0x4F, 0xE9,
2151
2152 0x00, 0x80, 0x00, 0xE8,
2153 0x00, 0x80, 0x00, 0xE8,
2154
2155 0x00, 0x80, 0x00, 0xE8,
2156 0x39, 0x37, 0x4F, 0xE9,
2157
2158 0x2F, 0x2F, 0x17, 0xAF,
2159 0x00, 0x80, 0x00, 0xE8,
2160
2161 0x00, 0x80, 0x00, 0xE8,
2162 0x00, 0x80, 0x00, 0xE8,
2163
2164 0x31, 0x80, 0x4F, 0xE9,
2165 0x00, 0x80, 0x00, 0xE8,
2166
2167 0x00, 0x80, 0x00, 0xE8,
2168 0x57, 0x39, 0x20, 0xE9,
2169
2170 0x16, 0x28, 0x20, 0xE9,
2171 0x1D, 0x3B, 0x20, 0xE9,
2172
2173 0x1E, 0x2B, 0x20, 0xE9,
2174 0x2B, 0x32, 0x20, 0xE9,
2175
2176 0x1C, 0x23, 0x20, 0xE9,
2177 0x57, 0x36, 0x20, 0xE9,
2178
2179 0x00, 0x80, 0xA0, 0xE9,
2180 0x40, 0x40, 0xD8, 0xEC,
2181
2182 0xFF, 0x80, 0xC0, 0xE9,
2183 0x90, 0xE2,
2184 0x00, 0xE0,
2185
2186 0x78, 0xFF, 0x20, 0xEA,
2187 0x19, 0xC8, 0xC1, 0xCD,
2188
2189 0x1F, 0xD7, 0x18, 0xBD,
2190 0x3F, 0xD7, 0x22, 0xBD,
2191
2192 0x9F, 0x41, 0x49, 0xBD,
2193 0x00, 0x80, 0x00, 0xE8,
2194
2195 0x25, 0x41, 0x49, 0xBD,
2196 0x2D, 0x41, 0x51, 0xBD,
2197
2198 0x0D, 0x80, 0x07, 0xEA,
2199 0x00, 0x80, 0x00, 0xE8,
2200
2201 0x35, 0x40, 0x48, 0xBD,
2202 0x3D, 0x40, 0x50, 0xBD,
2203
2204 0x00, 0x80, 0x00, 0xE8,
2205 0x25, 0x30,
2206 0x2D, 0x30,
2207
2208 0x35, 0x30,
2209 0xB5, 0x30,
2210 0xBD, 0x30,
2211 0x3D, 0x30,
2212
2213 0x9C, 0xA7, 0x5B, 0x9F,
2214 0x00, 0x80, 0x00, 0xE8,
2215
2216 0x00, 0x80, 0x00, 0xE8,
2217 0x00, 0x80, 0x00, 0xE8,
2218
2219 0x00, 0x80, 0x00, 0xE8,
2220 0x00, 0x80, 0x00, 0xE8,
2221
2222 0x00, 0x80, 0x00, 0xE8,
2223 0x00, 0x80, 0x00, 0xE8,
2224
2225 0x00, 0x80, 0x00, 0xE8,
2226 0x00, 0x80, 0x00, 0xE8,
2227
2228 0x77, 0xFF, 0x0A, 0xEA,
2229 0x00, 0x80, 0x00, 0xE8,
2230
2231 0xC9, 0x41, 0xC8, 0xEC,
2232 0x42, 0xE1,
2233 0x00, 0xE0,
2234
2235 0x75, 0xFF, 0x20, 0xEA,
2236 0x00, 0x80, 0x00, 0xE8,
2237
2238 0x00, 0x80, 0x00, 0xE8,
2239 0x00, 0x80, 0x00, 0xE8,
2240
2241 0xC8, 0x40, 0xC0, 0xEC,
2242 0x00, 0x80, 0x00, 0xE8,
2243
2244 0x72, 0xFF, 0x20, 0xEA,
2245 0x00, 0x80, 0x00, 0xE8,
2246
2247 0x00, 0x80, 0x00, 0xE8,
2248 0x00, 0x80, 0x00, 0xE8,
2249
2250};
2251
2252static unsigned char warp_g200_tgzs[] = {
2253
2254 0x00, 0x80, 0x00, 0xE8,
2255 0x00, 0x80, 0x00, 0xE8,
2256
2257 0x00, 0x80, 0x00, 0xE8,
2258 0x00, 0x80, 0x00, 0xE8,
2259
2260 0x00, 0x80, 0x00, 0xE8,
2261 0x00, 0x80, 0x00, 0xE8,
2262
2263 0x00, 0x80, 0x00, 0xE8,
2264 0x00, 0x80, 0x00, 0xE8,
2265
2266 0x00, 0x80, 0x00, 0xE8,
2267 0x00, 0x80, 0x00, 0xE8,
2268
2269 0x00, 0x80, 0x00, 0xE8,
2270 0x00, 0x80, 0x00, 0xE8,
2271
2272 0x00, 0x80, 0x00, 0xE8,
2273 0x00, 0x80, 0x00, 0xE8,
2274
2275 0x00, 0x80, 0x00, 0xE8,
2276 0x00, 0x80, 0x00, 0xE8,
2277
2278 0x00, 0x80, 0x00, 0xE8,
2279 0x00, 0x80, 0x00, 0xE8,
2280
2281 0x00, 0x80, 0x00, 0xE8,
2282 0x00, 0x80, 0x00, 0xE8,
2283
2284 0x00, 0x80, 0x00, 0xE8,
2285 0x00, 0x80, 0x00, 0xE8,
2286
2287 0x00, 0x80, 0x00, 0xE8,
2288 0x00, 0x80, 0x00, 0xE8,
2289
2290 0x00, 0x80, 0x00, 0xE8,
2291 0x00, 0x80, 0x00, 0xE8,
2292
2293 0x00, 0x98, 0xA0, 0xE9,
2294 0x40, 0x40, 0xD8, 0xEC,
2295
2296 0xFF, 0x80, 0xC0, 0xE9,
2297 0x00, 0x80, 0x00, 0xE8,
2298
2299 0x1F, 0xD7, 0x18, 0xBD,
2300 0x3F, 0xD7, 0x22, 0xBD,
2301
2302 0x81, 0x04,
2303 0x89, 0x04,
2304 0x01, 0x04,
2305 0x09, 0x04,
2306
2307 0xC9, 0x41, 0xC0, 0xEC,
2308 0x11, 0x04,
2309 0x00, 0xE0,
2310
2311 0x41, 0xCC, 0x41, 0xCD,
2312 0x49, 0xCC, 0x49, 0xCD,
2313
2314 0xD1, 0x41, 0xC0, 0xEC,
2315 0x51, 0xCC, 0x51, 0xCD,
2316
2317 0x80, 0x04,
2318 0x10, 0x04,
2319 0x08, 0x04,
2320 0x00, 0xE0,
2321
2322 0x00, 0xCC, 0xC0, 0xCD,
2323 0xD1, 0x49, 0xC0, 0xEC,
2324
2325 0x8A, 0x1F, 0x20, 0xE9,
2326 0x8B, 0x3F, 0x20, 0xE9,
2327
2328 0x41, 0x3C, 0x41, 0xAD,
2329 0x49, 0x3C, 0x49, 0xAD,
2330
2331 0x10, 0xCC, 0x10, 0xCD,
2332 0x08, 0xCC, 0x08, 0xCD,
2333
2334 0xB9, 0x41, 0x49, 0xBB,
2335 0x1F, 0xF0, 0x41, 0xCD,
2336
2337 0x51, 0x3C, 0x51, 0xAD,
2338 0x00, 0x98, 0x80, 0xE9,
2339
2340 0x8B, 0x80, 0x07, 0xEA,
2341 0x24, 0x1F, 0x20, 0xE9,
2342
2343 0x21, 0x45, 0x80, 0xE8,
2344 0x1A, 0x4D, 0x80, 0xE8,
2345
2346 0x31, 0x55, 0x80, 0xE8,
2347 0x00, 0x80, 0x00, 0xE8,
2348
2349 0x15, 0x41, 0x49, 0xBD,
2350 0x1D, 0x41, 0x51, 0xBD,
2351
2352 0x2E, 0x41, 0x2A, 0xB8,
2353 0x34, 0x53, 0xA0, 0xE8,
2354
2355 0x15, 0x30,
2356 0x1D, 0x30,
2357 0x58, 0xE3,
2358 0x00, 0xE0,
2359
2360 0xB5, 0x40, 0x48, 0xBD,
2361 0x3D, 0x40, 0x50, 0xBD,
2362
2363 0x24, 0x43, 0xA0, 0xE8,
2364 0x2C, 0x4B, 0xA0, 0xE8,
2365
2366 0x15, 0x72,
2367 0x09, 0xE3,
2368 0x00, 0xE0,
2369 0x1D, 0x72,
2370
2371 0x35, 0x30,
2372 0xB5, 0x30,
2373 0xBD, 0x30,
2374 0x3D, 0x30,
2375
2376 0x9C, 0x97, 0x57, 0x9F,
2377 0x00, 0x80, 0x00, 0xE8,
2378
2379 0x6C, 0x64, 0xC8, 0xEC,
2380 0x98, 0xE1,
2381 0xB5, 0x05,
2382
2383 0xBD, 0x05,
2384 0x2E, 0x30,
2385 0x32, 0xC0, 0xA0, 0xE8,
2386
2387 0x33, 0xC0, 0xA0, 0xE8,
2388 0x74, 0x64, 0xC8, 0xEC,
2389
2390 0x40, 0x3C, 0x40, 0xAD,
2391 0x32, 0x6A,
2392 0x2A, 0x30,
2393
2394 0x20, 0x73,
2395 0x33, 0x6A,
2396 0x00, 0xE0,
2397 0x28, 0x73,
2398
2399 0x1C, 0x72,
2400 0x83, 0xE2,
2401 0x77, 0x80, 0x15, 0xEA,
2402
2403 0xB8, 0x3D, 0x28, 0xDF,
2404 0x30, 0x35, 0x20, 0xDF,
2405
2406 0x40, 0x30,
2407 0x00, 0xE0,
2408 0xCC, 0xE2,
2409 0x64, 0x72,
2410
2411 0x25, 0x42, 0x52, 0xBF,
2412 0x2D, 0x42, 0x4A, 0xBF,
2413
2414 0x30, 0x2E, 0x30, 0xDF,
2415 0x38, 0x2E, 0x38, 0xDF,
2416
2417 0x18, 0x1D, 0x45, 0xE9,
2418 0x1E, 0x15, 0x45, 0xE9,
2419
2420 0x2B, 0x49, 0x51, 0xBD,
2421 0x00, 0xE0,
2422 0x1F, 0x73,
2423
2424 0x38, 0x38, 0x40, 0xAF,
2425 0x30, 0x30, 0x40, 0xAF,
2426
2427 0x24, 0x1F, 0x24, 0xDF,
2428 0x1D, 0x32, 0x20, 0xE9,
2429
2430 0x2C, 0x1F, 0x2C, 0xDF,
2431 0x1A, 0x33, 0x20, 0xE9,
2432
2433 0xB0, 0x10,
2434 0x08, 0xE3,
2435 0x40, 0x10,
2436 0xB8, 0x10,
2437
2438 0x26, 0xF0, 0x30, 0xCD,
2439 0x2F, 0xF0, 0x38, 0xCD,
2440
2441 0x2B, 0x80, 0x20, 0xE9,
2442 0x2A, 0x80, 0x20, 0xE9,
2443
2444 0xA6, 0x20,
2445 0x88, 0xE2,
2446 0x00, 0xE0,
2447 0xAF, 0x20,
2448
2449 0x28, 0x2A, 0x26, 0xAF,
2450 0x20, 0x2A, 0xC0, 0xAF,
2451
2452 0x34, 0x1F, 0x34, 0xDF,
2453 0x46, 0x24, 0x46, 0xDF,
2454
2455 0x28, 0x30, 0x80, 0xBF,
2456 0x20, 0x38, 0x80, 0xBF,
2457
2458 0x47, 0x24, 0x47, 0xDF,
2459 0x4E, 0x2C, 0x4E, 0xDF,
2460
2461 0x4F, 0x2C, 0x4F, 0xDF,
2462 0x56, 0x34, 0x56, 0xDF,
2463
2464 0x28, 0x15, 0x28, 0xDF,
2465 0x20, 0x1D, 0x20, 0xDF,
2466
2467 0x57, 0x34, 0x57, 0xDF,
2468 0x00, 0xE0,
2469 0x1D, 0x05,
2470
2471 0x04, 0x80, 0x10, 0xEA,
2472 0x89, 0xE2,
2473 0x2B, 0x30,
2474
2475 0x3F, 0xC1, 0x1D, 0xBD,
2476 0x00, 0x80, 0x00, 0xE8,
2477
2478 0x00, 0x80, 0x00, 0xE8,
2479 0x00, 0x80, 0x00, 0xE8,
2480
2481 0xA0, 0x68,
2482 0xBF, 0x25,
2483 0x00, 0x80, 0x00, 0xE8,
2484
2485 0x20, 0xC0, 0x20, 0xAF,
2486 0x28, 0x05,
2487 0x97, 0x74,
2488
2489 0x00, 0xE0,
2490 0x2A, 0x10,
2491 0x16, 0xC0, 0x20, 0xE9,
2492
2493 0x04, 0x80, 0x10, 0xEA,
2494 0x8C, 0xE2,
2495 0x95, 0x05,
2496
2497 0x28, 0xC1, 0x28, 0xAD,
2498 0x1F, 0xC1, 0x15, 0xBD,
2499
2500 0x00, 0x80, 0x00, 0xE8,
2501 0x00, 0x80, 0x00, 0xE8,
2502
2503 0xA8, 0x67,
2504 0x9F, 0x6B,
2505 0x00, 0x80, 0x00, 0xE8,
2506
2507 0x28, 0xC0, 0x28, 0xAD,
2508 0x1D, 0x25,
2509 0x20, 0x05,
2510
2511 0x28, 0x32, 0x80, 0xAD,
2512 0x40, 0x2A, 0x40, 0xBD,
2513
2514 0x1C, 0x80, 0x20, 0xE9,
2515 0x20, 0x33, 0x20, 0xAD,
2516
2517 0x20, 0x73,
2518 0x00, 0xE0,
2519 0xB6, 0x49, 0x51, 0xBB,
2520
2521 0x26, 0x2F, 0xB0, 0xE8,
2522 0x19, 0x20, 0x20, 0xE9,
2523
2524 0x35, 0x20, 0x35, 0xDF,
2525 0x3D, 0x20, 0x3D, 0xDF,
2526
2527 0x15, 0x20, 0x15, 0xDF,
2528 0x1D, 0x20, 0x1D, 0xDF,
2529
2530 0x26, 0xD0, 0x26, 0xCD,
2531 0x29, 0x49, 0x2A, 0xB8,
2532
2533 0x26, 0x40, 0x80, 0xBD,
2534 0x3B, 0x48, 0x50, 0xBD,
2535
2536 0x3E, 0x54, 0x57, 0x9F,
2537 0x00, 0xE0,
2538 0x82, 0xE1,
2539
2540 0x1E, 0xAF, 0x59, 0x9F,
2541 0x00, 0x80, 0x00, 0xE8,
2542
2543 0x26, 0x30,
2544 0x29, 0x30,
2545 0x48, 0x3C, 0x48, 0xAD,
2546
2547 0x2B, 0x72,
2548 0xC2, 0xE1,
2549 0x2C, 0xC0, 0x44, 0xC2,
2550
2551 0x05, 0x24, 0x34, 0xBF,
2552 0x0D, 0x24, 0x2C, 0xBF,
2553
2554 0x2D, 0x46, 0x4E, 0xBF,
2555 0x25, 0x46, 0x56, 0xBF,
2556
2557 0x20, 0x1D, 0x6F, 0x8F,
2558 0x32, 0x3E, 0x5F, 0xE9,
2559
2560 0x3E, 0x50, 0x56, 0x9F,
2561 0x00, 0xE0,
2562 0x3B, 0x30,
2563
2564 0x1E, 0x8F, 0x51, 0x9F,
2565 0x33, 0x1E, 0x5F, 0xE9,
2566
2567 0x05, 0x44, 0x54, 0xB2,
2568 0x0D, 0x44, 0x4C, 0xB2,
2569
2570 0x19, 0xC0, 0xB0, 0xE8,
2571 0x34, 0xC0, 0x44, 0xC4,
2572
2573 0x33, 0x73,
2574 0x00, 0xE0,
2575 0x3E, 0x62, 0x57, 0x9F,
2576
2577 0x1E, 0xAF, 0x59, 0x9F,
2578 0x00, 0xE0,
2579 0x0D, 0x20,
2580
2581 0x84, 0x3E, 0x58, 0xE9,
2582 0x28, 0x1D, 0x6F, 0x8F,
2583
2584 0x05, 0x20,
2585 0x00, 0xE0,
2586 0x85, 0x1E, 0x58, 0xE9,
2587
2588 0x9B, 0x3B, 0x33, 0xDF,
2589 0x20, 0x20, 0x42, 0xAF,
2590
2591 0x30, 0x42, 0x56, 0x9F,
2592 0x80, 0x3E, 0x57, 0xE9,
2593
2594 0x3F, 0x8F, 0x51, 0x9F,
2595 0x30, 0x80, 0x5F, 0xE9,
2596
2597 0x28, 0x28, 0x24, 0xAF,
2598 0x81, 0x1E, 0x57, 0xE9,
2599
2600 0x05, 0x47, 0x57, 0xBF,
2601 0x0D, 0x47, 0x4F, 0xBF,
2602
2603 0x88, 0x80, 0x58, 0xE9,
2604 0x1B, 0x29, 0x1B, 0xDF,
2605
2606 0x30, 0x1D, 0x6F, 0x8F,
2607 0x3A, 0x30, 0x4F, 0xE9,
2608
2609 0x1C, 0x30, 0x26, 0xDF,
2610 0x09, 0xE3,
2611 0x3B, 0x05,
2612
2613 0x3E, 0x50, 0x56, 0x9F,
2614 0x3B, 0x3F, 0x4F, 0xE9,
2615
2616 0x1E, 0x8F, 0x51, 0x9F,
2617 0x00, 0xE0,
2618 0xAC, 0x20,
2619
2620 0x2D, 0x44, 0x4C, 0xB4,
2621 0x2C, 0x1C, 0xC0, 0xAF,
2622
2623 0x25, 0x44, 0x54, 0xB4,
2624 0x00, 0xE0,
2625 0xC8, 0x30,
2626
2627 0x30, 0x46, 0x30, 0xAF,
2628 0x1B, 0x1B, 0x48, 0xAF,
2629
2630 0x00, 0xE0,
2631 0x25, 0x20,
2632 0x38, 0x2C, 0x4F, 0xE9,
2633
2634 0x86, 0x80, 0x57, 0xE9,
2635 0x38, 0x1D, 0x6F, 0x8F,
2636
2637 0x28, 0x74,
2638 0x00, 0xE0,
2639 0x0D, 0x44, 0x4C, 0xB0,
2640
2641 0x05, 0x44, 0x54, 0xB0,
2642 0x2D, 0x20,
2643 0x9B, 0x10,
2644
2645 0x82, 0x3E, 0x57, 0xE9,
2646 0x32, 0xF0, 0x1B, 0xCD,
2647
2648 0x1E, 0xBD, 0x59, 0x9F,
2649 0x83, 0x1E, 0x57, 0xE9,
2650
2651 0x38, 0x47, 0x38, 0xAF,
2652 0x34, 0x20,
2653 0x2A, 0x30,
2654
2655 0x00, 0xE0,
2656 0x0D, 0x20,
2657 0x32, 0x20,
2658 0x05, 0x20,
2659
2660 0x87, 0x80, 0x57, 0xE9,
2661 0x1F, 0x54, 0x57, 0x9F,
2662
2663 0x17, 0x42, 0x56, 0x9F,
2664 0x00, 0xE0,
2665 0x3B, 0x6A,
2666
2667 0x3F, 0x8F, 0x51, 0x9F,
2668 0x37, 0x1E, 0x4F, 0xE9,
2669
2670 0x37, 0x32, 0x2A, 0xAF,
2671 0x00, 0xE0,
2672 0x32, 0x00,
2673
2674 0x00, 0x80, 0x00, 0xE8,
2675 0x27, 0xC0, 0x44, 0xC0,
2676
2677 0x36, 0x1F, 0x4F, 0xE9,
2678 0x1F, 0x1F, 0x26, 0xDF,
2679
2680 0x37, 0x1B, 0x37, 0xBF,
2681 0x17, 0x26, 0x17, 0xDF,
2682
2683 0x3E, 0x17, 0x4F, 0xE9,
2684 0x3F, 0x3F, 0x4F, 0xE9,
2685
2686 0x34, 0x1F, 0x34, 0xAF,
2687 0x2B, 0x05,
2688 0xA7, 0x20,
2689
2690 0x33, 0x2B, 0x37, 0xDF,
2691 0x27, 0x17, 0xC0, 0xAF,
2692
2693 0x34, 0x80, 0x4F, 0xE9,
2694 0x00, 0x80, 0x00, 0xE8,
2695
2696 0x2D, 0x21, 0x1A, 0xB0,
2697 0x25, 0x21, 0x31, 0xB0,
2698
2699 0x0D, 0x21, 0x1A, 0xB2,
2700 0x05, 0x21, 0x31, 0xB2,
2701
2702 0x03, 0x80, 0x2A, 0xEA,
2703 0x17, 0xC1, 0x2B, 0xBD,
2704
2705 0x2D, 0x20,
2706 0x25, 0x20,
2707 0x05, 0x20,
2708 0x0D, 0x20,
2709
2710 0xB3, 0x68,
2711 0x97, 0x25,
2712 0x00, 0x80, 0x00, 0xE8,
2713
2714 0x33, 0xC0, 0x33, 0xAF,
2715 0x2F, 0xC0, 0x21, 0xC0,
2716
2717 0x16, 0x42, 0x56, 0x9F,
2718 0x3C, 0x27, 0x4F, 0xE9,
2719
2720 0x1E, 0x62, 0x57, 0x9F,
2721 0x00, 0x80, 0x00, 0xE8,
2722
2723 0x25, 0x21, 0x31, 0xB4,
2724 0x2D, 0x21, 0x1A, 0xB4,
2725
2726 0x3F, 0x2F, 0x5D, 0x9F,
2727 0x00, 0x80, 0x00, 0xE8,
2728
2729 0x33, 0x05,
2730 0x00, 0xE0,
2731 0x28, 0x19, 0x60, 0xEC,
2732
2733 0x37, 0x0F, 0x5C, 0x9F,
2734 0x00, 0xE0,
2735 0x2F, 0x20,
2736
2737 0x23, 0x3B, 0x33, 0xAD,
2738 0x1E, 0x26, 0x1E, 0xDF,
2739
2740 0xA7, 0x1E, 0x4F, 0xE9,
2741 0x17, 0x26, 0x16, 0xDF,
2742
2743 0x2D, 0x20,
2744 0x00, 0xE0,
2745 0xA8, 0x3F, 0x4F, 0xE9,
2746
2747 0x2F, 0x2F, 0x1E, 0xAF,
2748 0x25, 0x20,
2749 0x00, 0xE0,
2750
2751 0xA4, 0x16, 0x4F, 0xE9,
2752 0x0F, 0xC0, 0x21, 0xC2,
2753
2754 0xA6, 0x80, 0x4F, 0xE9,
2755 0x1F, 0x62, 0x57, 0x9F,
2756
2757 0x3F, 0x2F, 0x5D, 0x9F,
2758 0x00, 0xE0,
2759 0x8F, 0x20,
2760
2761 0xA5, 0x37, 0x4F, 0xE9,
2762 0x0F, 0x17, 0x0F, 0xAF,
2763
2764 0x06, 0xC0, 0x21, 0xC4,
2765 0x00, 0x80, 0x00, 0xE8,
2766
2767 0x00, 0x80, 0x00, 0xE8,
2768 0xA3, 0x80, 0x4F, 0xE9,
2769
2770 0x06, 0x20,
2771 0x00, 0xE0,
2772 0x1F, 0x26, 0x1F, 0xDF,
2773
2774 0xA1, 0x1F, 0x4F, 0xE9,
2775 0xA2, 0x3F, 0x4F, 0xE9,
2776
2777 0x00, 0x80, 0x00, 0xE8,
2778 0x00, 0x80, 0x00, 0xE8,
2779
2780 0x06, 0x06, 0x1F, 0xAF,
2781 0x00, 0x80, 0x00, 0xE8,
2782
2783 0x00, 0x80, 0x00, 0xE8,
2784 0x00, 0x80, 0x00, 0xE8,
2785
2786 0xA0, 0x80, 0x4F, 0xE9,
2787 0x00, 0x80, 0x00, 0xE8,
2788
2789 0x00, 0x80, 0x00, 0xE8,
2790 0x57, 0x39, 0x20, 0xE9,
2791
2792 0x16, 0x28, 0x20, 0xE9,
2793 0x1D, 0x3B, 0x20, 0xE9,
2794
2795 0x1E, 0x2B, 0x20, 0xE9,
2796 0x2B, 0x32, 0x20, 0xE9,
2797
2798 0x1C, 0x23, 0x20, 0xE9,
2799 0x57, 0x36, 0x20, 0xE9,
2800
2801 0x00, 0x80, 0xA0, 0xE9,
2802 0x40, 0x40, 0xD8, 0xEC,
2803
2804 0xFF, 0x80, 0xC0, 0xE9,
2805 0x90, 0xE2,
2806 0x00, 0xE0,
2807
2808 0x6C, 0xFF, 0x20, 0xEA,
2809 0x19, 0xC8, 0xC1, 0xCD,
2810
2811 0x1F, 0xD7, 0x18, 0xBD,
2812 0x3F, 0xD7, 0x22, 0xBD,
2813
2814 0x9F, 0x41, 0x49, 0xBD,
2815 0x00, 0x80, 0x00, 0xE8,
2816
2817 0x25, 0x41, 0x49, 0xBD,
2818 0x2D, 0x41, 0x51, 0xBD,
2819
2820 0x0D, 0x80, 0x07, 0xEA,
2821 0x00, 0x80, 0x00, 0xE8,
2822
2823 0x35, 0x40, 0x48, 0xBD,
2824 0x3D, 0x40, 0x50, 0xBD,
2825
2826 0x00, 0x80, 0x00, 0xE8,
2827 0x25, 0x30,
2828 0x2D, 0x30,
2829
2830 0x35, 0x30,
2831 0xB5, 0x30,
2832 0xBD, 0x30,
2833 0x3D, 0x30,
2834
2835 0x9C, 0xA7, 0x5B, 0x9F,
2836 0x00, 0x80, 0x00, 0xE8,
2837
2838 0x00, 0x80, 0x00, 0xE8,
2839 0x00, 0x80, 0x00, 0xE8,
2840
2841 0x00, 0x80, 0x00, 0xE8,
2842 0x00, 0x80, 0x00, 0xE8,
2843
2844 0x00, 0x80, 0x00, 0xE8,
2845 0x00, 0x80, 0x00, 0xE8,
2846
2847 0x00, 0x80, 0x00, 0xE8,
2848 0x00, 0x80, 0x00, 0xE8,
2849
2850 0x6B, 0xFF, 0x0A, 0xEA,
2851 0x00, 0x80, 0x00, 0xE8,
2852
2853 0xC9, 0x41, 0xC8, 0xEC,
2854 0x42, 0xE1,
2855 0x00, 0xE0,
2856
2857 0x69, 0xFF, 0x20, 0xEA,
2858 0x00, 0x80, 0x00, 0xE8,
2859
2860 0x00, 0x80, 0x00, 0xE8,
2861 0x00, 0x80, 0x00, 0xE8,
2862
2863 0xC8, 0x40, 0xC0, 0xEC,
2864 0x00, 0x80, 0x00, 0xE8,
2865
2866 0x66, 0xFF, 0x20, 0xEA,
2867 0x00, 0x80, 0x00, 0xE8,
2868
2869 0x00, 0x80, 0x00, 0xE8,
2870 0x00, 0x80, 0x00, 0xE8,
2871
2872};
2873
2874static unsigned char warp_g200_tgzsa[] = {
2875
2876 0x00, 0x80, 0x00, 0xE8,
2877 0x00, 0x80, 0x00, 0xE8,
2878
2879 0x00, 0x80, 0x00, 0xE8,
2880 0x00, 0x80, 0x00, 0xE8,
2881
2882 0x00, 0x80, 0x00, 0xE8,
2883 0x00, 0x80, 0x00, 0xE8,
2884
2885 0x00, 0x80, 0x00, 0xE8,
2886 0x00, 0x80, 0x00, 0xE8,
2887
2888 0x00, 0x80, 0x00, 0xE8,
2889 0x00, 0x80, 0x00, 0xE8,
2890
2891 0x00, 0x80, 0x00, 0xE8,
2892 0x00, 0x80, 0x00, 0xE8,
2893
2894 0x00, 0x80, 0x00, 0xE8,
2895 0x00, 0x80, 0x00, 0xE8,
2896
2897 0x00, 0x80, 0x00, 0xE8,
2898 0x00, 0x80, 0x00, 0xE8,
2899
2900 0x00, 0x80, 0x00, 0xE8,
2901 0x00, 0x80, 0x00, 0xE8,
2902
2903 0x00, 0x80, 0x00, 0xE8,
2904 0x00, 0x80, 0x00, 0xE8,
2905
2906 0x00, 0x80, 0x00, 0xE8,
2907 0x00, 0x80, 0x00, 0xE8,
2908
2909 0x00, 0x80, 0x00, 0xE8,
2910 0x00, 0x80, 0x00, 0xE8,
2911
2912 0x00, 0x80, 0x00, 0xE8,
2913 0x00, 0x80, 0x00, 0xE8,
2914
2915 0x00, 0x98, 0xA0, 0xE9,
2916 0x40, 0x40, 0xD8, 0xEC,
2917
2918 0xFF, 0x80, 0xC0, 0xE9,
2919 0x00, 0x80, 0x00, 0xE8,
2920
2921 0x1F, 0xD7, 0x18, 0xBD,
2922 0x3F, 0xD7, 0x22, 0xBD,
2923
2924 0x81, 0x04,
2925 0x89, 0x04,
2926 0x01, 0x04,
2927 0x09, 0x04,
2928
2929 0xC9, 0x41, 0xC0, 0xEC,
2930 0x11, 0x04,
2931 0x00, 0xE0,
2932
2933 0x41, 0xCC, 0x41, 0xCD,
2934 0x49, 0xCC, 0x49, 0xCD,
2935
2936 0xD1, 0x41, 0xC0, 0xEC,
2937 0x51, 0xCC, 0x51, 0xCD,
2938
2939 0x80, 0x04,
2940 0x10, 0x04,
2941 0x08, 0x04,
2942 0x00, 0xE0,
2943
2944 0x00, 0xCC, 0xC0, 0xCD,
2945 0xD1, 0x49, 0xC0, 0xEC,
2946
2947 0x8A, 0x1F, 0x20, 0xE9,
2948 0x8B, 0x3F, 0x20, 0xE9,
2949
2950 0x41, 0x3C, 0x41, 0xAD,
2951 0x49, 0x3C, 0x49, 0xAD,
2952
2953 0x10, 0xCC, 0x10, 0xCD,
2954 0x08, 0xCC, 0x08, 0xCD,
2955
2956 0xB9, 0x41, 0x49, 0xBB,
2957 0x1F, 0xF0, 0x41, 0xCD,
2958
2959 0x51, 0x3C, 0x51, 0xAD,
2960 0x00, 0x98, 0x80, 0xE9,
2961
2962 0x8F, 0x80, 0x07, 0xEA,
2963 0x24, 0x1F, 0x20, 0xE9,
2964
2965 0x21, 0x45, 0x80, 0xE8,
2966 0x1A, 0x4D, 0x80, 0xE8,
2967
2968 0x31, 0x55, 0x80, 0xE8,
2969 0x00, 0x80, 0x00, 0xE8,
2970
2971 0x15, 0x41, 0x49, 0xBD,
2972 0x1D, 0x41, 0x51, 0xBD,
2973
2974 0x2E, 0x41, 0x2A, 0xB8,
2975 0x34, 0x53, 0xA0, 0xE8,
2976
2977 0x15, 0x30,
2978 0x1D, 0x30,
2979 0x58, 0xE3,
2980 0x00, 0xE0,
2981
2982 0xB5, 0x40, 0x48, 0xBD,
2983 0x3D, 0x40, 0x50, 0xBD,
2984
2985 0x24, 0x43, 0xA0, 0xE8,
2986 0x2C, 0x4B, 0xA0, 0xE8,
2987
2988 0x15, 0x72,
2989 0x09, 0xE3,
2990 0x00, 0xE0,
2991 0x1D, 0x72,
2992
2993 0x35, 0x30,
2994 0xB5, 0x30,
2995 0xBD, 0x30,
2996 0x3D, 0x30,
2997
2998 0x9C, 0x97, 0x57, 0x9F,
2999 0x00, 0x80, 0x00, 0xE8,
3000
3001 0x6C, 0x64, 0xC8, 0xEC,
3002 0x98, 0xE1,
3003 0xB5, 0x05,
3004
3005 0xBD, 0x05,
3006 0x2E, 0x30,
3007 0x32, 0xC0, 0xA0, 0xE8,
3008
3009 0x33, 0xC0, 0xA0, 0xE8,
3010 0x74, 0x64, 0xC8, 0xEC,
3011
3012 0x40, 0x3C, 0x40, 0xAD,
3013 0x32, 0x6A,
3014 0x2A, 0x30,
3015
3016 0x20, 0x73,
3017 0x33, 0x6A,
3018 0x00, 0xE0,
3019 0x28, 0x73,
3020
3021 0x1C, 0x72,
3022 0x83, 0xE2,
3023 0x7B, 0x80, 0x15, 0xEA,
3024
3025 0xB8, 0x3D, 0x28, 0xDF,
3026 0x30, 0x35, 0x20, 0xDF,
3027
3028 0x40, 0x30,
3029 0x00, 0xE0,
3030 0xCC, 0xE2,
3031 0x64, 0x72,
3032
3033 0x25, 0x42, 0x52, 0xBF,
3034 0x2D, 0x42, 0x4A, 0xBF,
3035
3036 0x30, 0x2E, 0x30, 0xDF,
3037 0x38, 0x2E, 0x38, 0xDF,
3038
3039 0x18, 0x1D, 0x45, 0xE9,
3040 0x1E, 0x15, 0x45, 0xE9,
3041
3042 0x2B, 0x49, 0x51, 0xBD,
3043 0x00, 0xE0,
3044 0x1F, 0x73,
3045
3046 0x38, 0x38, 0x40, 0xAF,
3047 0x30, 0x30, 0x40, 0xAF,
3048
3049 0x24, 0x1F, 0x24, 0xDF,
3050 0x1D, 0x32, 0x20, 0xE9,
3051
3052 0x2C, 0x1F, 0x2C, 0xDF,
3053 0x1A, 0x33, 0x20, 0xE9,
3054
3055 0xB0, 0x10,
3056 0x08, 0xE3,
3057 0x40, 0x10,
3058 0xB8, 0x10,
3059
3060 0x26, 0xF0, 0x30, 0xCD,
3061 0x2F, 0xF0, 0x38, 0xCD,
3062
3063 0x2B, 0x80, 0x20, 0xE9,
3064 0x2A, 0x80, 0x20, 0xE9,
3065
3066 0xA6, 0x20,
3067 0x88, 0xE2,
3068 0x00, 0xE0,
3069 0xAF, 0x20,
3070
3071 0x28, 0x2A, 0x26, 0xAF,
3072 0x20, 0x2A, 0xC0, 0xAF,
3073
3074 0x34, 0x1F, 0x34, 0xDF,
3075 0x46, 0x24, 0x46, 0xDF,
3076
3077 0x28, 0x30, 0x80, 0xBF,
3078 0x20, 0x38, 0x80, 0xBF,
3079
3080 0x47, 0x24, 0x47, 0xDF,
3081 0x4E, 0x2C, 0x4E, 0xDF,
3082
3083 0x4F, 0x2C, 0x4F, 0xDF,
3084 0x56, 0x34, 0x56, 0xDF,
3085
3086 0x28, 0x15, 0x28, 0xDF,
3087 0x20, 0x1D, 0x20, 0xDF,
3088
3089 0x57, 0x34, 0x57, 0xDF,
3090 0x00, 0xE0,
3091 0x1D, 0x05,
3092
3093 0x04, 0x80, 0x10, 0xEA,
3094 0x89, 0xE2,
3095 0x2B, 0x30,
3096
3097 0x3F, 0xC1, 0x1D, 0xBD,
3098 0x00, 0x80, 0x00, 0xE8,
3099
3100 0x00, 0x80, 0x00, 0xE8,
3101 0x00, 0x80, 0x00, 0xE8,
3102
3103 0xA0, 0x68,
3104 0xBF, 0x25,
3105 0x00, 0x80, 0x00, 0xE8,
3106
3107 0x20, 0xC0, 0x20, 0xAF,
3108 0x28, 0x05,
3109 0x97, 0x74,
3110
3111 0x00, 0xE0,
3112 0x2A, 0x10,
3113 0x16, 0xC0, 0x20, 0xE9,
3114
3115 0x04, 0x80, 0x10, 0xEA,
3116 0x8C, 0xE2,
3117 0x95, 0x05,
3118
3119 0x28, 0xC1, 0x28, 0xAD,
3120 0x1F, 0xC1, 0x15, 0xBD,
3121
3122 0x00, 0x80, 0x00, 0xE8,
3123 0x00, 0x80, 0x00, 0xE8,
3124
3125 0xA8, 0x67,
3126 0x9F, 0x6B,
3127 0x00, 0x80, 0x00, 0xE8,
3128
3129 0x28, 0xC0, 0x28, 0xAD,
3130 0x1D, 0x25,
3131 0x20, 0x05,
3132
3133 0x28, 0x32, 0x80, 0xAD,
3134 0x40, 0x2A, 0x40, 0xBD,
3135
3136 0x1C, 0x80, 0x20, 0xE9,
3137 0x20, 0x33, 0x20, 0xAD,
3138
3139 0x20, 0x73,
3140 0x00, 0xE0,
3141 0xB6, 0x49, 0x51, 0xBB,
3142
3143 0x26, 0x2F, 0xB0, 0xE8,
3144 0x19, 0x20, 0x20, 0xE9,
3145
3146 0x35, 0x20, 0x35, 0xDF,
3147 0x3D, 0x20, 0x3D, 0xDF,
3148
3149 0x15, 0x20, 0x15, 0xDF,
3150 0x1D, 0x20, 0x1D, 0xDF,
3151
3152 0x26, 0xD0, 0x26, 0xCD,
3153 0x29, 0x49, 0x2A, 0xB8,
3154
3155 0x26, 0x40, 0x80, 0xBD,
3156 0x3B, 0x48, 0x50, 0xBD,
3157
3158 0x3E, 0x54, 0x57, 0x9F,
3159 0x00, 0xE0,
3160 0x82, 0xE1,
3161
3162 0x1E, 0xAF, 0x59, 0x9F,
3163 0x00, 0x80, 0x00, 0xE8,
3164
3165 0x26, 0x30,
3166 0x29, 0x30,
3167 0x48, 0x3C, 0x48, 0xAD,
3168
3169 0x2B, 0x72,
3170 0xC2, 0xE1,
3171 0x2C, 0xC0, 0x44, 0xC2,
3172
3173 0x05, 0x24, 0x34, 0xBF,
3174 0x0D, 0x24, 0x2C, 0xBF,
3175
3176 0x2D, 0x46, 0x4E, 0xBF,
3177 0x25, 0x46, 0x56, 0xBF,
3178
3179 0x20, 0x1D, 0x6F, 0x8F,
3180 0x32, 0x3E, 0x5F, 0xE9,
3181
3182 0x3E, 0x50, 0x56, 0x9F,
3183 0x00, 0xE0,
3184 0x3B, 0x30,
3185
3186 0x1E, 0x8F, 0x51, 0x9F,
3187 0x33, 0x1E, 0x5F, 0xE9,
3188
3189 0x05, 0x44, 0x54, 0xB2,
3190 0x0D, 0x44, 0x4C, 0xB2,
3191
3192 0x19, 0xC0, 0xB0, 0xE8,
3193 0x34, 0xC0, 0x44, 0xC4,
3194
3195 0x33, 0x73,
3196 0x00, 0xE0,
3197 0x3E, 0x62, 0x57, 0x9F,
3198
3199 0x1E, 0xAF, 0x59, 0x9F,
3200 0x00, 0xE0,
3201 0x0D, 0x20,
3202
3203 0x84, 0x3E, 0x58, 0xE9,
3204 0x28, 0x1D, 0x6F, 0x8F,
3205
3206 0x05, 0x20,
3207 0x00, 0xE0,
3208 0x85, 0x1E, 0x58, 0xE9,
3209
3210 0x9B, 0x3B, 0x33, 0xDF,
3211 0x20, 0x20, 0x42, 0xAF,
3212
3213 0x30, 0x42, 0x56, 0x9F,
3214 0x80, 0x3E, 0x57, 0xE9,
3215
3216 0x3F, 0x8F, 0x51, 0x9F,
3217 0x30, 0x80, 0x5F, 0xE9,
3218
3219 0x28, 0x28, 0x24, 0xAF,
3220 0x81, 0x1E, 0x57, 0xE9,
3221
3222 0x05, 0x47, 0x57, 0xBF,
3223 0x0D, 0x47, 0x4F, 0xBF,
3224
3225 0x88, 0x80, 0x58, 0xE9,
3226 0x1B, 0x29, 0x1B, 0xDF,
3227
3228 0x30, 0x1D, 0x6F, 0x8F,
3229 0x3A, 0x30, 0x4F, 0xE9,
3230
3231 0x1C, 0x30, 0x26, 0xDF,
3232 0x09, 0xE3,
3233 0x3B, 0x05,
3234
3235 0x3E, 0x50, 0x56, 0x9F,
3236 0x3B, 0x3F, 0x4F, 0xE9,
3237
3238 0x1E, 0x8F, 0x51, 0x9F,
3239 0x00, 0xE0,
3240 0xAC, 0x20,
3241
3242 0x2D, 0x44, 0x4C, 0xB4,
3243 0x2C, 0x1C, 0xC0, 0xAF,
3244
3245 0x25, 0x44, 0x54, 0xB4,
3246 0x00, 0xE0,
3247 0xC8, 0x30,
3248
3249 0x30, 0x46, 0x30, 0xAF,
3250 0x1B, 0x1B, 0x48, 0xAF,
3251
3252 0x00, 0xE0,
3253 0x25, 0x20,
3254 0x38, 0x2C, 0x4F, 0xE9,
3255
3256 0x86, 0x80, 0x57, 0xE9,
3257 0x38, 0x1D, 0x6F, 0x8F,
3258
3259 0x28, 0x74,
3260 0x00, 0xE0,
3261 0x0D, 0x44, 0x4C, 0xB0,
3262
3263 0x05, 0x44, 0x54, 0xB0,
3264 0x2D, 0x20,
3265 0x9B, 0x10,
3266
3267 0x82, 0x3E, 0x57, 0xE9,
3268 0x32, 0xF0, 0x1B, 0xCD,
3269
3270 0x1E, 0xBD, 0x59, 0x9F,
3271 0x83, 0x1E, 0x57, 0xE9,
3272
3273 0x38, 0x47, 0x38, 0xAF,
3274 0x34, 0x20,
3275 0x2A, 0x30,
3276
3277 0x00, 0xE0,
3278 0x0D, 0x20,
3279 0x32, 0x20,
3280 0x05, 0x20,
3281
3282 0x87, 0x80, 0x57, 0xE9,
3283 0x1F, 0x54, 0x57, 0x9F,
3284
3285 0x17, 0x42, 0x56, 0x9F,
3286 0x00, 0xE0,
3287 0x3B, 0x6A,
3288
3289 0x3F, 0x8F, 0x51, 0x9F,
3290 0x37, 0x1E, 0x4F, 0xE9,
3291
3292 0x37, 0x32, 0x2A, 0xAF,
3293 0x00, 0xE0,
3294 0x32, 0x00,
3295
3296 0x00, 0x80, 0x00, 0xE8,
3297 0x27, 0xC0, 0x44, 0xC0,
3298
3299 0x36, 0x1F, 0x4F, 0xE9,
3300 0x1F, 0x1F, 0x26, 0xDF,
3301
3302 0x37, 0x1B, 0x37, 0xBF,
3303 0x17, 0x26, 0x17, 0xDF,
3304
3305 0x3E, 0x17, 0x4F, 0xE9,
3306 0x3F, 0x3F, 0x4F, 0xE9,
3307
3308 0x34, 0x1F, 0x34, 0xAF,
3309 0x2B, 0x05,
3310 0xA7, 0x20,
3311
3312 0x33, 0x2B, 0x37, 0xDF,
3313 0x27, 0x17, 0xC0, 0xAF,
3314
3315 0x34, 0x80, 0x4F, 0xE9,
3316 0x00, 0x80, 0x00, 0xE8,
3317
3318 0x2D, 0x21, 0x1A, 0xB0,
3319 0x25, 0x21, 0x31, 0xB0,
3320
3321 0x0D, 0x21, 0x1A, 0xB2,
3322 0x05, 0x21, 0x31, 0xB2,
3323
3324 0x03, 0x80, 0x2A, 0xEA,
3325 0x17, 0xC1, 0x2B, 0xBD,
3326
3327 0x2D, 0x20,
3328 0x25, 0x20,
3329 0x05, 0x20,
3330 0x0D, 0x20,
3331
3332 0xB3, 0x68,
3333 0x97, 0x25,
3334 0x00, 0x80, 0x00, 0xE8,
3335
3336 0x33, 0xC0, 0x33, 0xAF,
3337 0x2F, 0xC0, 0x21, 0xC0,
3338
3339 0x16, 0x42, 0x56, 0x9F,
3340 0x3C, 0x27, 0x4F, 0xE9,
3341
3342 0x1E, 0x62, 0x57, 0x9F,
3343 0x00, 0x80, 0x00, 0xE8,
3344
3345 0x25, 0x21, 0x31, 0xB4,
3346 0x2D, 0x21, 0x1A, 0xB4,
3347
3348 0x3F, 0x2F, 0x5D, 0x9F,
3349 0x00, 0x80, 0x00, 0xE8,
3350
3351 0x33, 0x05,
3352 0x00, 0xE0,
3353 0x28, 0x19, 0x60, 0xEC,
3354
3355 0x0D, 0x44, 0x4C, 0xB6,
3356 0x05, 0x44, 0x54, 0xB6,
3357
3358 0x37, 0x0F, 0x5C, 0x9F,
3359 0x00, 0xE0,
3360 0x2F, 0x20,
3361
3362 0x23, 0x3B, 0x33, 0xAD,
3363 0x1E, 0x26, 0x1E, 0xDF,
3364
3365 0xA7, 0x1E, 0x4F, 0xE9,
3366 0x17, 0x26, 0x16, 0xDF,
3367
3368 0x2D, 0x20,
3369 0x00, 0xE0,
3370 0xA8, 0x3F, 0x4F, 0xE9,
3371
3372 0x2F, 0x2F, 0x1E, 0xAF,
3373 0x25, 0x20,
3374 0x00, 0xE0,
3375
3376 0xA4, 0x16, 0x4F, 0xE9,
3377 0x0F, 0xC0, 0x21, 0xC2,
3378
3379 0xA6, 0x80, 0x4F, 0xE9,
3380 0x1F, 0x62, 0x57, 0x9F,
3381
3382 0x0D, 0x20,
3383 0x05, 0x20,
3384 0x00, 0x80, 0x00, 0xE8,
3385
3386 0x3F, 0x2F, 0x5D, 0x9F,
3387 0x00, 0xE0,
3388 0x0F, 0x20,
3389
3390 0x17, 0x50, 0x56, 0x9F,
3391 0xA5, 0x37, 0x4F, 0xE9,
3392
3393 0x06, 0xC0, 0x21, 0xC4,
3394 0x0F, 0x17, 0x0F, 0xAF,
3395
3396 0x37, 0x0F, 0x5C, 0x9F,
3397 0x00, 0x80, 0x00, 0xE8,
3398
3399 0x2F, 0xC0, 0x44, 0xC6,
3400 0xA3, 0x80, 0x4F, 0xE9,
3401
3402 0x06, 0x20,
3403 0x00, 0xE0,
3404 0x1F, 0x26, 0x1F, 0xDF,
3405
3406 0x17, 0x26, 0x17, 0xDF,
3407 0x9D, 0x17, 0x4F, 0xE9,
3408
3409 0xA1, 0x1F, 0x4F, 0xE9,
3410 0xA2, 0x3F, 0x4F, 0xE9,
3411
3412 0x06, 0x06, 0x1F, 0xAF,
3413 0x00, 0xE0,
3414 0xAF, 0x20,
3415
3416 0x9E, 0x37, 0x4F, 0xE9,
3417 0x2F, 0x17, 0x2F, 0xAF,
3418
3419 0xA0, 0x80, 0x4F, 0xE9,
3420 0x00, 0x80, 0x00, 0xE8,
3421
3422 0x00, 0x80, 0x00, 0xE8,
3423 0x9C, 0x80, 0x4F, 0xE9,
3424
3425 0x00, 0x80, 0x00, 0xE8,
3426 0x57, 0x39, 0x20, 0xE9,
3427
3428 0x16, 0x28, 0x20, 0xE9,
3429 0x1D, 0x3B, 0x20, 0xE9,
3430
3431 0x1E, 0x2B, 0x20, 0xE9,
3432 0x2B, 0x32, 0x20, 0xE9,
3433
3434 0x1C, 0x23, 0x20, 0xE9,
3435 0x57, 0x36, 0x20, 0xE9,
3436
3437 0x00, 0x80, 0xA0, 0xE9,
3438 0x40, 0x40, 0xD8, 0xEC,
3439
3440 0xFF, 0x80, 0xC0, 0xE9,
3441 0x90, 0xE2,
3442 0x00, 0xE0,
3443
3444 0x68, 0xFF, 0x20, 0xEA,
3445 0x19, 0xC8, 0xC1, 0xCD,
3446
3447 0x1F, 0xD7, 0x18, 0xBD,
3448 0x3F, 0xD7, 0x22, 0xBD,
3449
3450 0x9F, 0x41, 0x49, 0xBD,
3451 0x00, 0x80, 0x00, 0xE8,
3452
3453 0x25, 0x41, 0x49, 0xBD,
3454 0x2D, 0x41, 0x51, 0xBD,
3455
3456 0x0D, 0x80, 0x07, 0xEA,
3457 0x00, 0x80, 0x00, 0xE8,
3458
3459 0x35, 0x40, 0x48, 0xBD,
3460 0x3D, 0x40, 0x50, 0xBD,
3461
3462 0x00, 0x80, 0x00, 0xE8,
3463 0x25, 0x30,
3464 0x2D, 0x30,
3465
3466 0x35, 0x30,
3467 0xB5, 0x30,
3468 0xBD, 0x30,
3469 0x3D, 0x30,
3470
3471 0x9C, 0xA7, 0x5B, 0x9F,
3472 0x00, 0x80, 0x00, 0xE8,
3473
3474 0x00, 0x80, 0x00, 0xE8,
3475 0x00, 0x80, 0x00, 0xE8,
3476
3477 0x00, 0x80, 0x00, 0xE8,
3478 0x00, 0x80, 0x00, 0xE8,
3479
3480 0x00, 0x80, 0x00, 0xE8,
3481 0x00, 0x80, 0x00, 0xE8,
3482
3483 0x00, 0x80, 0x00, 0xE8,
3484 0x00, 0x80, 0x00, 0xE8,
3485
3486 0x67, 0xFF, 0x0A, 0xEA,
3487 0x00, 0x80, 0x00, 0xE8,
3488
3489 0xC9, 0x41, 0xC8, 0xEC,
3490 0x42, 0xE1,
3491 0x00, 0xE0,
3492
3493 0x65, 0xFF, 0x20, 0xEA,
3494 0x00, 0x80, 0x00, 0xE8,
3495
3496 0x00, 0x80, 0x00, 0xE8,
3497 0x00, 0x80, 0x00, 0xE8,
3498
3499 0xC8, 0x40, 0xC0, 0xEC,
3500 0x00, 0x80, 0x00, 0xE8,
3501
3502 0x62, 0xFF, 0x20, 0xEA,
3503 0x00, 0x80, 0x00, 0xE8,
3504
3505 0x00, 0x80, 0x00, 0xE8,
3506 0x00, 0x80, 0x00, 0xE8,
3507
3508};
3509
3510static unsigned char warp_g200_tgzsaf[] = {
3511
3512 0x00, 0x80, 0x00, 0xE8,
3513 0x00, 0x80, 0x00, 0xE8,
3514
3515 0x00, 0x80, 0x00, 0xE8,
3516 0x00, 0x80, 0x00, 0xE8,
3517
3518 0x00, 0x80, 0x00, 0xE8,
3519 0x00, 0x80, 0x00, 0xE8,
3520
3521 0x00, 0x98, 0xA0, 0xE9,
3522 0x40, 0x40, 0xD8, 0xEC,
3523
3524 0xFF, 0x80, 0xC0, 0xE9,
3525 0x00, 0x80, 0x00, 0xE8,
3526
3527 0x1F, 0xD7, 0x18, 0xBD,
3528 0x3F, 0xD7, 0x22, 0xBD,
3529
3530 0x81, 0x04,
3531 0x89, 0x04,
3532 0x01, 0x04,
3533 0x09, 0x04,
3534
3535 0xC9, 0x41, 0xC0, 0xEC,
3536 0x11, 0x04,
3537 0x00, 0xE0,
3538
3539 0x41, 0xCC, 0x41, 0xCD,
3540 0x49, 0xCC, 0x49, 0xCD,
3541
3542 0xD1, 0x41, 0xC0, 0xEC,
3543 0x51, 0xCC, 0x51, 0xCD,
3544
3545 0x80, 0x04,
3546 0x10, 0x04,
3547 0x08, 0x04,
3548 0x00, 0xE0,
3549
3550 0x00, 0xCC, 0xC0, 0xCD,
3551 0xD1, 0x49, 0xC0, 0xEC,
3552
3553 0x8A, 0x1F, 0x20, 0xE9,
3554 0x8B, 0x3F, 0x20, 0xE9,
3555
3556 0x41, 0x3C, 0x41, 0xAD,
3557 0x49, 0x3C, 0x49, 0xAD,
3558
3559 0x10, 0xCC, 0x10, 0xCD,
3560 0x08, 0xCC, 0x08, 0xCD,
3561
3562 0xB9, 0x41, 0x49, 0xBB,
3563 0x1F, 0xF0, 0x41, 0xCD,
3564
3565 0x51, 0x3C, 0x51, 0xAD,
3566 0x00, 0x98, 0x80, 0xE9,
3567
3568 0x94, 0x80, 0x07, 0xEA,
3569 0x24, 0x1F, 0x20, 0xE9,
3570
3571 0x21, 0x45, 0x80, 0xE8,
3572 0x1A, 0x4D, 0x80, 0xE8,
3573
3574 0x31, 0x55, 0x80, 0xE8,
3575 0x00, 0x80, 0x00, 0xE8,
3576
3577 0x15, 0x41, 0x49, 0xBD,
3578 0x1D, 0x41, 0x51, 0xBD,
3579
3580 0x2E, 0x41, 0x2A, 0xB8,
3581 0x34, 0x53, 0xA0, 0xE8,
3582
3583 0x15, 0x30,
3584 0x1D, 0x30,
3585 0x58, 0xE3,
3586 0x00, 0xE0,
3587
3588 0xB5, 0x40, 0x48, 0xBD,
3589 0x3D, 0x40, 0x50, 0xBD,
3590
3591 0x24, 0x43, 0xA0, 0xE8,
3592 0x2C, 0x4B, 0xA0, 0xE8,
3593
3594 0x15, 0x72,
3595 0x09, 0xE3,
3596 0x00, 0xE0,
3597 0x1D, 0x72,
3598
3599 0x35, 0x30,
3600 0xB5, 0x30,
3601 0xBD, 0x30,
3602 0x3D, 0x30,
3603
3604 0x9C, 0x97, 0x57, 0x9F,
3605 0x00, 0x80, 0x00, 0xE8,
3606
3607 0x6C, 0x64, 0xC8, 0xEC,
3608 0x98, 0xE1,
3609 0xB5, 0x05,
3610
3611 0xBD, 0x05,
3612 0x2E, 0x30,
3613 0x32, 0xC0, 0xA0, 0xE8,
3614
3615 0x33, 0xC0, 0xA0, 0xE8,
3616 0x74, 0x64, 0xC8, 0xEC,
3617
3618 0x40, 0x3C, 0x40, 0xAD,
3619 0x32, 0x6A,
3620 0x2A, 0x30,
3621
3622 0x20, 0x73,
3623 0x33, 0x6A,
3624 0x00, 0xE0,
3625 0x28, 0x73,
3626
3627 0x1C, 0x72,
3628 0x83, 0xE2,
3629 0x80, 0x80, 0x15, 0xEA,
3630
3631 0xB8, 0x3D, 0x28, 0xDF,
3632 0x30, 0x35, 0x20, 0xDF,
3633
3634 0x40, 0x30,
3635 0x00, 0xE0,
3636 0xCC, 0xE2,
3637 0x64, 0x72,
3638
3639 0x25, 0x42, 0x52, 0xBF,
3640 0x2D, 0x42, 0x4A, 0xBF,
3641
3642 0x30, 0x2E, 0x30, 0xDF,
3643 0x38, 0x2E, 0x38, 0xDF,
3644
3645 0x18, 0x1D, 0x45, 0xE9,
3646 0x1E, 0x15, 0x45, 0xE9,
3647
3648 0x2B, 0x49, 0x51, 0xBD,
3649 0x00, 0xE0,
3650 0x1F, 0x73,
3651
3652 0x38, 0x38, 0x40, 0xAF,
3653 0x30, 0x30, 0x40, 0xAF,
3654
3655 0x24, 0x1F, 0x24, 0xDF,
3656 0x1D, 0x32, 0x20, 0xE9,
3657
3658 0x2C, 0x1F, 0x2C, 0xDF,
3659 0x1A, 0x33, 0x20, 0xE9,
3660
3661 0xB0, 0x10,
3662 0x08, 0xE3,
3663 0x40, 0x10,
3664 0xB8, 0x10,
3665
3666 0x26, 0xF0, 0x30, 0xCD,
3667 0x2F, 0xF0, 0x38, 0xCD,
3668
3669 0x2B, 0x80, 0x20, 0xE9,
3670 0x2A, 0x80, 0x20, 0xE9,
3671
3672 0xA6, 0x20,
3673 0x88, 0xE2,
3674 0x00, 0xE0,
3675 0xAF, 0x20,
3676
3677 0x28, 0x2A, 0x26, 0xAF,
3678 0x20, 0x2A, 0xC0, 0xAF,
3679
3680 0x34, 0x1F, 0x34, 0xDF,
3681 0x46, 0x24, 0x46, 0xDF,
3682
3683 0x28, 0x30, 0x80, 0xBF,
3684 0x20, 0x38, 0x80, 0xBF,
3685
3686 0x47, 0x24, 0x47, 0xDF,
3687 0x4E, 0x2C, 0x4E, 0xDF,
3688
3689 0x4F, 0x2C, 0x4F, 0xDF,
3690 0x56, 0x34, 0x56, 0xDF,
3691
3692 0x28, 0x15, 0x28, 0xDF,
3693 0x20, 0x1D, 0x20, 0xDF,
3694
3695 0x57, 0x34, 0x57, 0xDF,
3696 0x00, 0xE0,
3697 0x1D, 0x05,
3698
3699 0x04, 0x80, 0x10, 0xEA,
3700 0x89, 0xE2,
3701 0x2B, 0x30,
3702
3703 0x3F, 0xC1, 0x1D, 0xBD,
3704 0x00, 0x80, 0x00, 0xE8,
3705
3706 0x00, 0x80, 0x00, 0xE8,
3707 0x00, 0x80, 0x00, 0xE8,
3708
3709 0xA0, 0x68,
3710 0xBF, 0x25,
3711 0x00, 0x80, 0x00, 0xE8,
3712
3713 0x20, 0xC0, 0x20, 0xAF,
3714 0x28, 0x05,
3715 0x97, 0x74,
3716
3717 0x00, 0xE0,
3718 0x2A, 0x10,
3719 0x16, 0xC0, 0x20, 0xE9,
3720
3721 0x04, 0x80, 0x10, 0xEA,
3722 0x8C, 0xE2,
3723 0x95, 0x05,
3724
3725 0x28, 0xC1, 0x28, 0xAD,
3726 0x1F, 0xC1, 0x15, 0xBD,
3727
3728 0x00, 0x80, 0x00, 0xE8,
3729 0x00, 0x80, 0x00, 0xE8,
3730
3731 0xA8, 0x67,
3732 0x9F, 0x6B,
3733 0x00, 0x80, 0x00, 0xE8,
3734
3735 0x28, 0xC0, 0x28, 0xAD,
3736 0x1D, 0x25,
3737 0x20, 0x05,
3738
3739 0x28, 0x32, 0x80, 0xAD,
3740 0x40, 0x2A, 0x40, 0xBD,
3741
3742 0x1C, 0x80, 0x20, 0xE9,
3743 0x20, 0x33, 0x20, 0xAD,
3744
3745 0x20, 0x73,
3746 0x00, 0xE0,
3747 0xB6, 0x49, 0x51, 0xBB,
3748
3749 0x26, 0x2F, 0xB0, 0xE8,
3750 0x19, 0x20, 0x20, 0xE9,
3751
3752 0x35, 0x20, 0x35, 0xDF,
3753 0x3D, 0x20, 0x3D, 0xDF,
3754
3755 0x15, 0x20, 0x15, 0xDF,
3756 0x1D, 0x20, 0x1D, 0xDF,
3757
3758 0x26, 0xD0, 0x26, 0xCD,
3759 0x29, 0x49, 0x2A, 0xB8,
3760
3761 0x26, 0x40, 0x80, 0xBD,
3762 0x3B, 0x48, 0x50, 0xBD,
3763
3764 0x3E, 0x54, 0x57, 0x9F,
3765 0x00, 0xE0,
3766 0x82, 0xE1,
3767
3768 0x1E, 0xAF, 0x59, 0x9F,
3769 0x00, 0x80, 0x00, 0xE8,
3770
3771 0x26, 0x30,
3772 0x29, 0x30,
3773 0x48, 0x3C, 0x48, 0xAD,
3774
3775 0x2B, 0x72,
3776 0xC2, 0xE1,
3777 0x2C, 0xC0, 0x44, 0xC2,
3778
3779 0x05, 0x24, 0x34, 0xBF,
3780 0x0D, 0x24, 0x2C, 0xBF,
3781
3782 0x2D, 0x46, 0x4E, 0xBF,
3783 0x25, 0x46, 0x56, 0xBF,
3784
3785 0x20, 0x1D, 0x6F, 0x8F,
3786 0x32, 0x3E, 0x5F, 0xE9,
3787
3788 0x3E, 0x50, 0x56, 0x9F,
3789 0x00, 0xE0,
3790 0x3B, 0x30,
3791
3792 0x1E, 0x8F, 0x51, 0x9F,
3793 0x33, 0x1E, 0x5F, 0xE9,
3794
3795 0x05, 0x44, 0x54, 0xB2,
3796 0x0D, 0x44, 0x4C, 0xB2,
3797
3798 0x19, 0xC0, 0xB0, 0xE8,
3799 0x34, 0xC0, 0x44, 0xC4,
3800
3801 0x33, 0x73,
3802 0x00, 0xE0,
3803 0x3E, 0x62, 0x57, 0x9F,
3804
3805 0x1E, 0xAF, 0x59, 0x9F,
3806 0x00, 0xE0,
3807 0x0D, 0x20,
3808
3809 0x84, 0x3E, 0x58, 0xE9,
3810 0x28, 0x1D, 0x6F, 0x8F,
3811
3812 0x05, 0x20,
3813 0x00, 0xE0,
3814 0x85, 0x1E, 0x58, 0xE9,
3815
3816 0x9B, 0x3B, 0x33, 0xDF,
3817 0x20, 0x20, 0x42, 0xAF,
3818
3819 0x30, 0x42, 0x56, 0x9F,
3820 0x80, 0x3E, 0x57, 0xE9,
3821
3822 0x3F, 0x8F, 0x51, 0x9F,
3823 0x30, 0x80, 0x5F, 0xE9,
3824
3825 0x28, 0x28, 0x24, 0xAF,
3826 0x81, 0x1E, 0x57, 0xE9,
3827
3828 0x05, 0x47, 0x57, 0xBF,
3829 0x0D, 0x47, 0x4F, 0xBF,
3830
3831 0x88, 0x80, 0x58, 0xE9,
3832 0x1B, 0x29, 0x1B, 0xDF,
3833
3834 0x30, 0x1D, 0x6F, 0x8F,
3835 0x3A, 0x30, 0x4F, 0xE9,
3836
3837 0x1C, 0x30, 0x26, 0xDF,
3838 0x09, 0xE3,
3839 0x3B, 0x05,
3840
3841 0x3E, 0x50, 0x56, 0x9F,
3842 0x3B, 0x3F, 0x4F, 0xE9,
3843
3844 0x1E, 0x8F, 0x51, 0x9F,
3845 0x00, 0xE0,
3846 0xAC, 0x20,
3847
3848 0x2D, 0x44, 0x4C, 0xB4,
3849 0x2C, 0x1C, 0xC0, 0xAF,
3850
3851 0x25, 0x44, 0x54, 0xB4,
3852 0x00, 0xE0,
3853 0xC8, 0x30,
3854
3855 0x30, 0x46, 0x30, 0xAF,
3856 0x1B, 0x1B, 0x48, 0xAF,
3857
3858 0x00, 0xE0,
3859 0x25, 0x20,
3860 0x38, 0x2C, 0x4F, 0xE9,
3861
3862 0x86, 0x80, 0x57, 0xE9,
3863 0x38, 0x1D, 0x6F, 0x8F,
3864
3865 0x28, 0x74,
3866 0x00, 0xE0,
3867 0x0D, 0x44, 0x4C, 0xB0,
3868
3869 0x05, 0x44, 0x54, 0xB0,
3870 0x2D, 0x20,
3871 0x9B, 0x10,
3872
3873 0x82, 0x3E, 0x57, 0xE9,
3874 0x32, 0xF0, 0x1B, 0xCD,
3875
3876 0x1E, 0xBD, 0x59, 0x9F,
3877 0x83, 0x1E, 0x57, 0xE9,
3878
3879 0x38, 0x47, 0x38, 0xAF,
3880 0x34, 0x20,
3881 0x2A, 0x30,
3882
3883 0x00, 0xE0,
3884 0x0D, 0x20,
3885 0x32, 0x20,
3886 0x05, 0x20,
3887
3888 0x87, 0x80, 0x57, 0xE9,
3889 0x1F, 0x54, 0x57, 0x9F,
3890
3891 0x17, 0x42, 0x56, 0x9F,
3892 0x00, 0xE0,
3893 0x3B, 0x6A,
3894
3895 0x3F, 0x8F, 0x51, 0x9F,
3896 0x37, 0x1E, 0x4F, 0xE9,
3897
3898 0x37, 0x32, 0x2A, 0xAF,
3899 0x00, 0xE0,
3900 0x32, 0x00,
3901
3902 0x00, 0x80, 0x00, 0xE8,
3903 0x27, 0xC0, 0x44, 0xC0,
3904
3905 0x36, 0x1F, 0x4F, 0xE9,
3906 0x1F, 0x1F, 0x26, 0xDF,
3907
3908 0x37, 0x1B, 0x37, 0xBF,
3909 0x17, 0x26, 0x17, 0xDF,
3910
3911 0x3E, 0x17, 0x4F, 0xE9,
3912 0x3F, 0x3F, 0x4F, 0xE9,
3913
3914 0x34, 0x1F, 0x34, 0xAF,
3915 0x2B, 0x05,
3916 0xA7, 0x20,
3917
3918 0x33, 0x2B, 0x37, 0xDF,
3919 0x27, 0x17, 0xC0, 0xAF,
3920
3921 0x34, 0x80, 0x4F, 0xE9,
3922 0x00, 0x80, 0x00, 0xE8,
3923
3924 0x2D, 0x21, 0x1A, 0xB0,
3925 0x25, 0x21, 0x31, 0xB0,
3926
3927 0x0D, 0x21, 0x1A, 0xB2,
3928 0x05, 0x21, 0x31, 0xB2,
3929
3930 0x03, 0x80, 0x2A, 0xEA,
3931 0x17, 0xC1, 0x2B, 0xBD,
3932
3933 0x2D, 0x20,
3934 0x25, 0x20,
3935 0x05, 0x20,
3936 0x0D, 0x20,
3937
3938 0xB3, 0x68,
3939 0x97, 0x25,
3940 0x00, 0x80, 0x00, 0xE8,
3941
3942 0x33, 0xC0, 0x33, 0xAF,
3943 0x2F, 0xC0, 0x21, 0xC0,
3944
3945 0x16, 0x42, 0x56, 0x9F,
3946 0x3C, 0x27, 0x4F, 0xE9,
3947
3948 0x1E, 0x62, 0x57, 0x9F,
3949 0x00, 0x80, 0x00, 0xE8,
3950
3951 0x25, 0x21, 0x31, 0xB4,
3952 0x2D, 0x21, 0x1A, 0xB4,
3953
3954 0x3F, 0x2F, 0x5D, 0x9F,
3955 0x00, 0x80, 0x00, 0xE8,
3956
3957 0x33, 0x05,
3958 0x00, 0xE0,
3959 0x28, 0x19, 0x60, 0xEC,
3960
3961 0x0D, 0x21, 0x1A, 0xB6,
3962 0x05, 0x21, 0x31, 0xB6,
3963
3964 0x37, 0x0F, 0x5C, 0x9F,
3965 0x00, 0xE0,
3966 0x2F, 0x20,
3967
3968 0x23, 0x3B, 0x33, 0xAD,
3969 0x1E, 0x26, 0x1E, 0xDF,
3970
3971 0xA7, 0x1E, 0x4F, 0xE9,
3972 0x17, 0x26, 0x16, 0xDF,
3973
3974 0x2D, 0x20,
3975 0x00, 0xE0,
3976 0xA8, 0x3F, 0x4F, 0xE9,
3977
3978 0x2F, 0x2F, 0x1E, 0xAF,
3979 0x25, 0x20,
3980 0x00, 0xE0,
3981
3982 0xA4, 0x16, 0x4F, 0xE9,
3983 0x0F, 0xC0, 0x21, 0xC2,
3984
3985 0xA6, 0x80, 0x4F, 0xE9,
3986 0x1F, 0x62, 0x57, 0x9F,
3987
3988 0x0D, 0x20,
3989 0x05, 0x20,
3990 0x2F, 0xC0, 0x21, 0xC6,
3991
3992 0x2D, 0x44, 0x4C, 0xB6,
3993 0x25, 0x44, 0x54, 0xB6,
3994
3995 0x3F, 0x2F, 0x5D, 0x9F,
3996 0x00, 0xE0,
3997 0x0F, 0x20,
3998
3999 0x2D, 0x20,
4000 0x25, 0x20,
4001 0x07, 0xC0, 0x44, 0xC6,
4002
4003 0x17, 0x50, 0x56, 0x9F,
4004 0xA5, 0x37, 0x4F, 0xE9,
4005
4006 0x06, 0xC0, 0x21, 0xC4,
4007 0x0F, 0x17, 0x0F, 0xAF,
4008
4009 0x37, 0x0F, 0x5C, 0x9F,
4010 0x00, 0x80, 0x00, 0xE8,
4011
4012 0x1E, 0x62, 0x57, 0x9F,
4013 0x00, 0x80, 0x00, 0xE8,
4014
4015 0x3E, 0x3D, 0x5D, 0x9F,
4016 0x00, 0xE0,
4017 0x07, 0x20,
4018
4019 0x2F, 0x20,
4020 0x00, 0xE0,
4021 0xA3, 0x0F, 0x4F, 0xE9,
4022
4023 0x06, 0x20,
4024 0x00, 0xE0,
4025 0x1F, 0x26, 0x1F, 0xDF,
4026
4027 0x17, 0x26, 0x17, 0xDF,
4028 0xA1, 0x1F, 0x4F, 0xE9,
4029
4030 0x1E, 0x26, 0x1E, 0xDF,
4031 0x9D, 0x1E, 0x4F, 0xE9,
4032
4033 0x35, 0x17, 0x4F, 0xE9,
4034 0xA2, 0x3F, 0x4F, 0xE9,
4035
4036 0x06, 0x06, 0x1F, 0xAF,
4037 0x39, 0x37, 0x4F, 0xE9,
4038
4039 0x2F, 0x2F, 0x17, 0xAF,
4040 0x07, 0x07, 0x1E, 0xAF,
4041
4042 0xA0, 0x80, 0x4F, 0xE9,
4043 0x9E, 0x3E, 0x4F, 0xE9,
4044
4045 0x31, 0x80, 0x4F, 0xE9,
4046 0x9C, 0x80, 0x4F, 0xE9,
4047
4048 0x00, 0x80, 0x00, 0xE8,
4049 0x57, 0x39, 0x20, 0xE9,
4050
4051 0x16, 0x28, 0x20, 0xE9,
4052 0x1D, 0x3B, 0x20, 0xE9,
4053
4054 0x1E, 0x2B, 0x20, 0xE9,
4055 0x2B, 0x32, 0x20, 0xE9,
4056
4057 0x1C, 0x23, 0x20, 0xE9,
4058 0x57, 0x36, 0x20, 0xE9,
4059
4060 0x00, 0x80, 0xA0, 0xE9,
4061 0x40, 0x40, 0xD8, 0xEC,
4062
4063 0xFF, 0x80, 0xC0, 0xE9,
4064 0x90, 0xE2,
4065 0x00, 0xE0,
4066
4067 0x63, 0xFF, 0x20, 0xEA,
4068 0x19, 0xC8, 0xC1, 0xCD,
4069
4070 0x1F, 0xD7, 0x18, 0xBD,
4071 0x3F, 0xD7, 0x22, 0xBD,
4072
4073 0x9F, 0x41, 0x49, 0xBD,
4074 0x00, 0x80, 0x00, 0xE8,
4075
4076 0x25, 0x41, 0x49, 0xBD,
4077 0x2D, 0x41, 0x51, 0xBD,
4078
4079 0x0D, 0x80, 0x07, 0xEA,
4080 0x00, 0x80, 0x00, 0xE8,
4081
4082 0x35, 0x40, 0x48, 0xBD,
4083 0x3D, 0x40, 0x50, 0xBD,
4084
4085 0x00, 0x80, 0x00, 0xE8,
4086 0x25, 0x30,
4087 0x2D, 0x30,
4088
4089 0x35, 0x30,
4090 0xB5, 0x30,
4091 0xBD, 0x30,
4092 0x3D, 0x30,
4093
4094 0x9C, 0xA7, 0x5B, 0x9F,
4095 0x00, 0x80, 0x00, 0xE8,
4096
4097 0x00, 0x80, 0x00, 0xE8,
4098 0x00, 0x80, 0x00, 0xE8,
4099
4100 0x00, 0x80, 0x00, 0xE8,
4101 0x00, 0x80, 0x00, 0xE8,
4102
4103 0x00, 0x80, 0x00, 0xE8,
4104 0x00, 0x80, 0x00, 0xE8,
4105
4106 0x00, 0x80, 0x00, 0xE8,
4107 0x00, 0x80, 0x00, 0xE8,
4108
4109 0x62, 0xFF, 0x0A, 0xEA,
4110 0x00, 0x80, 0x00, 0xE8,
4111
4112 0xC9, 0x41, 0xC8, 0xEC,
4113 0x42, 0xE1,
4114 0x00, 0xE0,
4115
4116 0x60, 0xFF, 0x20, 0xEA,
4117 0x00, 0x80, 0x00, 0xE8,
4118
4119 0x00, 0x80, 0x00, 0xE8,
4120 0x00, 0x80, 0x00, 0xE8,
4121
4122 0xC8, 0x40, 0xC0, 0xEC,
4123 0x00, 0x80, 0x00, 0xE8,
4124
4125 0x5D, 0xFF, 0x20, 0xEA,
4126 0x00, 0x80, 0x00, 0xE8,
4127
4128 0x00, 0x80, 0x00, 0xE8,
4129 0x00, 0x80, 0x00, 0xE8,
4130
4131};
4132
4133static unsigned char warp_g200_tgzsf[] = {
4134
4135 0x00, 0x80, 0x00, 0xE8,
4136 0x00, 0x80, 0x00, 0xE8,
4137
4138 0x00, 0x80, 0x00, 0xE8,
4139 0x00, 0x80, 0x00, 0xE8,
4140
4141 0x00, 0x80, 0x00, 0xE8,
4142 0x00, 0x80, 0x00, 0xE8,
4143
4144 0x00, 0x80, 0x00, 0xE8,
4145 0x00, 0x80, 0x00, 0xE8,
4146
4147 0x00, 0x80, 0x00, 0xE8,
4148 0x00, 0x80, 0x00, 0xE8,
4149
4150 0x00, 0x80, 0x00, 0xE8,
4151 0x00, 0x80, 0x00, 0xE8,
4152
4153 0x00, 0x80, 0x00, 0xE8,
4154 0x00, 0x80, 0x00, 0xE8,
4155
4156 0x00, 0x80, 0x00, 0xE8,
4157 0x00, 0x80, 0x00, 0xE8,
4158
4159 0x00, 0x80, 0x00, 0xE8,
4160 0x00, 0x80, 0x00, 0xE8,
4161
4162 0x00, 0x80, 0x00, 0xE8,
4163 0x00, 0x80, 0x00, 0xE8,
4164
4165 0x00, 0x80, 0x00, 0xE8,
4166 0x00, 0x80, 0x00, 0xE8,
4167
4168 0x00, 0x80, 0x00, 0xE8,
4169 0x00, 0x80, 0x00, 0xE8,
4170
4171 0x00, 0x80, 0x00, 0xE8,
4172 0x00, 0x80, 0x00, 0xE8,
4173
4174 0x00, 0x98, 0xA0, 0xE9,
4175 0x40, 0x40, 0xD8, 0xEC,
4176
4177 0xFF, 0x80, 0xC0, 0xE9,
4178 0x00, 0x80, 0x00, 0xE8,
4179
4180 0x1F, 0xD7, 0x18, 0xBD,
4181 0x3F, 0xD7, 0x22, 0xBD,
4182
4183 0x81, 0x04,
4184 0x89, 0x04,
4185 0x01, 0x04,
4186 0x09, 0x04,
4187
4188 0xC9, 0x41, 0xC0, 0xEC,
4189 0x11, 0x04,
4190 0x00, 0xE0,
4191
4192 0x41, 0xCC, 0x41, 0xCD,
4193 0x49, 0xCC, 0x49, 0xCD,
4194
4195 0xD1, 0x41, 0xC0, 0xEC,
4196 0x51, 0xCC, 0x51, 0xCD,
4197
4198 0x80, 0x04,
4199 0x10, 0x04,
4200 0x08, 0x04,
4201 0x00, 0xE0,
4202
4203 0x00, 0xCC, 0xC0, 0xCD,
4204 0xD1, 0x49, 0xC0, 0xEC,
4205
4206 0x8A, 0x1F, 0x20, 0xE9,
4207 0x8B, 0x3F, 0x20, 0xE9,
4208
4209 0x41, 0x3C, 0x41, 0xAD,
4210 0x49, 0x3C, 0x49, 0xAD,
4211
4212 0x10, 0xCC, 0x10, 0xCD,
4213 0x08, 0xCC, 0x08, 0xCD,
4214
4215 0xB9, 0x41, 0x49, 0xBB,
4216 0x1F, 0xF0, 0x41, 0xCD,
4217
4218 0x51, 0x3C, 0x51, 0xAD,
4219 0x00, 0x98, 0x80, 0xE9,
4220
4221 0x8F, 0x80, 0x07, 0xEA,
4222 0x24, 0x1F, 0x20, 0xE9,
4223
4224 0x21, 0x45, 0x80, 0xE8,
4225 0x1A, 0x4D, 0x80, 0xE8,
4226
4227 0x31, 0x55, 0x80, 0xE8,
4228 0x00, 0x80, 0x00, 0xE8,
4229
4230 0x15, 0x41, 0x49, 0xBD,
4231 0x1D, 0x41, 0x51, 0xBD,
4232
4233 0x2E, 0x41, 0x2A, 0xB8,
4234 0x34, 0x53, 0xA0, 0xE8,
4235
4236 0x15, 0x30,
4237 0x1D, 0x30,
4238 0x58, 0xE3,
4239 0x00, 0xE0,
4240
4241 0xB5, 0x40, 0x48, 0xBD,
4242 0x3D, 0x40, 0x50, 0xBD,
4243
4244 0x24, 0x43, 0xA0, 0xE8,
4245 0x2C, 0x4B, 0xA0, 0xE8,
4246
4247 0x15, 0x72,
4248 0x09, 0xE3,
4249 0x00, 0xE0,
4250 0x1D, 0x72,
4251
4252 0x35, 0x30,
4253 0xB5, 0x30,
4254 0xBD, 0x30,
4255 0x3D, 0x30,
4256
4257 0x9C, 0x97, 0x57, 0x9F,
4258 0x00, 0x80, 0x00, 0xE8,
4259
4260 0x6C, 0x64, 0xC8, 0xEC,
4261 0x98, 0xE1,
4262 0xB5, 0x05,
4263
4264 0xBD, 0x05,
4265 0x2E, 0x30,
4266 0x32, 0xC0, 0xA0, 0xE8,
4267
4268 0x33, 0xC0, 0xA0, 0xE8,
4269 0x74, 0x64, 0xC8, 0xEC,
4270
4271 0x40, 0x3C, 0x40, 0xAD,
4272 0x32, 0x6A,
4273 0x2A, 0x30,
4274
4275 0x20, 0x73,
4276 0x33, 0x6A,
4277 0x00, 0xE0,
4278 0x28, 0x73,
4279
4280 0x1C, 0x72,
4281 0x83, 0xE2,
4282 0x7B, 0x80, 0x15, 0xEA,
4283
4284 0xB8, 0x3D, 0x28, 0xDF,
4285 0x30, 0x35, 0x20, 0xDF,
4286
4287 0x40, 0x30,
4288 0x00, 0xE0,
4289 0xCC, 0xE2,
4290 0x64, 0x72,
4291
4292 0x25, 0x42, 0x52, 0xBF,
4293 0x2D, 0x42, 0x4A, 0xBF,
4294
4295 0x30, 0x2E, 0x30, 0xDF,
4296 0x38, 0x2E, 0x38, 0xDF,
4297
4298 0x18, 0x1D, 0x45, 0xE9,
4299 0x1E, 0x15, 0x45, 0xE9,
4300
4301 0x2B, 0x49, 0x51, 0xBD,
4302 0x00, 0xE0,
4303 0x1F, 0x73,
4304
4305 0x38, 0x38, 0x40, 0xAF,
4306 0x30, 0x30, 0x40, 0xAF,
4307
4308 0x24, 0x1F, 0x24, 0xDF,
4309 0x1D, 0x32, 0x20, 0xE9,
4310
4311 0x2C, 0x1F, 0x2C, 0xDF,
4312 0x1A, 0x33, 0x20, 0xE9,
4313
4314 0xB0, 0x10,
4315 0x08, 0xE3,
4316 0x40, 0x10,
4317 0xB8, 0x10,
4318
4319 0x26, 0xF0, 0x30, 0xCD,
4320 0x2F, 0xF0, 0x38, 0xCD,
4321
4322 0x2B, 0x80, 0x20, 0xE9,
4323 0x2A, 0x80, 0x20, 0xE9,
4324
4325 0xA6, 0x20,
4326 0x88, 0xE2,
4327 0x00, 0xE0,
4328 0xAF, 0x20,
4329
4330 0x28, 0x2A, 0x26, 0xAF,
4331 0x20, 0x2A, 0xC0, 0xAF,
4332
4333 0x34, 0x1F, 0x34, 0xDF,
4334 0x46, 0x24, 0x46, 0xDF,
4335
4336 0x28, 0x30, 0x80, 0xBF,
4337 0x20, 0x38, 0x80, 0xBF,
4338
4339 0x47, 0x24, 0x47, 0xDF,
4340 0x4E, 0x2C, 0x4E, 0xDF,
4341
4342 0x4F, 0x2C, 0x4F, 0xDF,
4343 0x56, 0x34, 0x56, 0xDF,
4344
4345 0x28, 0x15, 0x28, 0xDF,
4346 0x20, 0x1D, 0x20, 0xDF,
4347
4348 0x57, 0x34, 0x57, 0xDF,
4349 0x00, 0xE0,
4350 0x1D, 0x05,
4351
4352 0x04, 0x80, 0x10, 0xEA,
4353 0x89, 0xE2,
4354 0x2B, 0x30,
4355
4356 0x3F, 0xC1, 0x1D, 0xBD,
4357 0x00, 0x80, 0x00, 0xE8,
4358
4359 0x00, 0x80, 0x00, 0xE8,
4360 0x00, 0x80, 0x00, 0xE8,
4361
4362 0xA0, 0x68,
4363 0xBF, 0x25,
4364 0x00, 0x80, 0x00, 0xE8,
4365
4366 0x20, 0xC0, 0x20, 0xAF,
4367 0x28, 0x05,
4368 0x97, 0x74,
4369
4370 0x00, 0xE0,
4371 0x2A, 0x10,
4372 0x16, 0xC0, 0x20, 0xE9,
4373
4374 0x04, 0x80, 0x10, 0xEA,
4375 0x8C, 0xE2,
4376 0x95, 0x05,
4377
4378 0x28, 0xC1, 0x28, 0xAD,
4379 0x1F, 0xC1, 0x15, 0xBD,
4380
4381 0x00, 0x80, 0x00, 0xE8,
4382 0x00, 0x80, 0x00, 0xE8,
4383
4384 0xA8, 0x67,
4385 0x9F, 0x6B,
4386 0x00, 0x80, 0x00, 0xE8,
4387
4388 0x28, 0xC0, 0x28, 0xAD,
4389 0x1D, 0x25,
4390 0x20, 0x05,
4391
4392 0x28, 0x32, 0x80, 0xAD,
4393 0x40, 0x2A, 0x40, 0xBD,
4394
4395 0x1C, 0x80, 0x20, 0xE9,
4396 0x20, 0x33, 0x20, 0xAD,
4397
4398 0x20, 0x73,
4399 0x00, 0xE0,
4400 0xB6, 0x49, 0x51, 0xBB,
4401
4402 0x26, 0x2F, 0xB0, 0xE8,
4403 0x19, 0x20, 0x20, 0xE9,
4404
4405 0x35, 0x20, 0x35, 0xDF,
4406 0x3D, 0x20, 0x3D, 0xDF,
4407
4408 0x15, 0x20, 0x15, 0xDF,
4409 0x1D, 0x20, 0x1D, 0xDF,
4410
4411 0x26, 0xD0, 0x26, 0xCD,
4412 0x29, 0x49, 0x2A, 0xB8,
4413
4414 0x26, 0x40, 0x80, 0xBD,
4415 0x3B, 0x48, 0x50, 0xBD,
4416
4417 0x3E, 0x54, 0x57, 0x9F,
4418 0x00, 0xE0,
4419 0x82, 0xE1,
4420
4421 0x1E, 0xAF, 0x59, 0x9F,
4422 0x00, 0x80, 0x00, 0xE8,
4423
4424 0x26, 0x30,
4425 0x29, 0x30,
4426 0x48, 0x3C, 0x48, 0xAD,
4427
4428 0x2B, 0x72,
4429 0xC2, 0xE1,
4430 0x2C, 0xC0, 0x44, 0xC2,
4431
4432 0x05, 0x24, 0x34, 0xBF,
4433 0x0D, 0x24, 0x2C, 0xBF,
4434
4435 0x2D, 0x46, 0x4E, 0xBF,
4436 0x25, 0x46, 0x56, 0xBF,
4437
4438 0x20, 0x1D, 0x6F, 0x8F,
4439 0x32, 0x3E, 0x5F, 0xE9,
4440
4441 0x3E, 0x50, 0x56, 0x9F,
4442 0x00, 0xE0,
4443 0x3B, 0x30,
4444
4445 0x1E, 0x8F, 0x51, 0x9F,
4446 0x33, 0x1E, 0x5F, 0xE9,
4447
4448 0x05, 0x44, 0x54, 0xB2,
4449 0x0D, 0x44, 0x4C, 0xB2,
4450
4451 0x19, 0xC0, 0xB0, 0xE8,
4452 0x34, 0xC0, 0x44, 0xC4,
4453
4454 0x33, 0x73,
4455 0x00, 0xE0,
4456 0x3E, 0x62, 0x57, 0x9F,
4457
4458 0x1E, 0xAF, 0x59, 0x9F,
4459 0x00, 0xE0,
4460 0x0D, 0x20,
4461
4462 0x84, 0x3E, 0x58, 0xE9,
4463 0x28, 0x1D, 0x6F, 0x8F,
4464
4465 0x05, 0x20,
4466 0x00, 0xE0,
4467 0x85, 0x1E, 0x58, 0xE9,
4468
4469 0x9B, 0x3B, 0x33, 0xDF,
4470 0x20, 0x20, 0x42, 0xAF,
4471
4472 0x30, 0x42, 0x56, 0x9F,
4473 0x80, 0x3E, 0x57, 0xE9,
4474
4475 0x3F, 0x8F, 0x51, 0x9F,
4476 0x30, 0x80, 0x5F, 0xE9,
4477
4478 0x28, 0x28, 0x24, 0xAF,
4479 0x81, 0x1E, 0x57, 0xE9,
4480
4481 0x05, 0x47, 0x57, 0xBF,
4482 0x0D, 0x47, 0x4F, 0xBF,
4483
4484 0x88, 0x80, 0x58, 0xE9,
4485 0x1B, 0x29, 0x1B, 0xDF,
4486
4487 0x30, 0x1D, 0x6F, 0x8F,
4488 0x3A, 0x30, 0x4F, 0xE9,
4489
4490 0x1C, 0x30, 0x26, 0xDF,
4491 0x09, 0xE3,
4492 0x3B, 0x05,
4493
4494 0x3E, 0x50, 0x56, 0x9F,
4495 0x3B, 0x3F, 0x4F, 0xE9,
4496
4497 0x1E, 0x8F, 0x51, 0x9F,
4498 0x00, 0xE0,
4499 0xAC, 0x20,
4500
4501 0x2D, 0x44, 0x4C, 0xB4,
4502 0x2C, 0x1C, 0xC0, 0xAF,
4503
4504 0x25, 0x44, 0x54, 0xB4,
4505 0x00, 0xE0,
4506 0xC8, 0x30,
4507
4508 0x30, 0x46, 0x30, 0xAF,
4509 0x1B, 0x1B, 0x48, 0xAF,
4510
4511 0x00, 0xE0,
4512 0x25, 0x20,
4513 0x38, 0x2C, 0x4F, 0xE9,
4514
4515 0x86, 0x80, 0x57, 0xE9,
4516 0x38, 0x1D, 0x6F, 0x8F,
4517
4518 0x28, 0x74,
4519 0x00, 0xE0,
4520 0x0D, 0x44, 0x4C, 0xB0,
4521
4522 0x05, 0x44, 0x54, 0xB0,
4523 0x2D, 0x20,
4524 0x9B, 0x10,
4525
4526 0x82, 0x3E, 0x57, 0xE9,
4527 0x32, 0xF0, 0x1B, 0xCD,
4528
4529 0x1E, 0xBD, 0x59, 0x9F,
4530 0x83, 0x1E, 0x57, 0xE9,
4531
4532 0x38, 0x47, 0x38, 0xAF,
4533 0x34, 0x20,
4534 0x2A, 0x30,
4535
4536 0x00, 0xE0,
4537 0x0D, 0x20,
4538 0x32, 0x20,
4539 0x05, 0x20,
4540
4541 0x87, 0x80, 0x57, 0xE9,
4542 0x1F, 0x54, 0x57, 0x9F,
4543
4544 0x17, 0x42, 0x56, 0x9F,
4545 0x00, 0xE0,
4546 0x3B, 0x6A,
4547
4548 0x3F, 0x8F, 0x51, 0x9F,
4549 0x37, 0x1E, 0x4F, 0xE9,
4550
4551 0x37, 0x32, 0x2A, 0xAF,
4552 0x00, 0xE0,
4553 0x32, 0x00,
4554
4555 0x00, 0x80, 0x00, 0xE8,
4556 0x27, 0xC0, 0x44, 0xC0,
4557
4558 0x36, 0x1F, 0x4F, 0xE9,
4559 0x1F, 0x1F, 0x26, 0xDF,
4560
4561 0x37, 0x1B, 0x37, 0xBF,
4562 0x17, 0x26, 0x17, 0xDF,
4563
4564 0x3E, 0x17, 0x4F, 0xE9,
4565 0x3F, 0x3F, 0x4F, 0xE9,
4566
4567 0x34, 0x1F, 0x34, 0xAF,
4568 0x2B, 0x05,
4569 0xA7, 0x20,
4570
4571 0x33, 0x2B, 0x37, 0xDF,
4572 0x27, 0x17, 0xC0, 0xAF,
4573
4574 0x34, 0x80, 0x4F, 0xE9,
4575 0x00, 0x80, 0x00, 0xE8,
4576
4577 0x2D, 0x21, 0x1A, 0xB0,
4578 0x25, 0x21, 0x31, 0xB0,
4579
4580 0x0D, 0x21, 0x1A, 0xB2,
4581 0x05, 0x21, 0x31, 0xB2,
4582
4583 0x03, 0x80, 0x2A, 0xEA,
4584 0x17, 0xC1, 0x2B, 0xBD,
4585
4586 0x2D, 0x20,
4587 0x25, 0x20,
4588 0x05, 0x20,
4589 0x0D, 0x20,
4590
4591 0xB3, 0x68,
4592 0x97, 0x25,
4593 0x00, 0x80, 0x00, 0xE8,
4594
4595 0x33, 0xC0, 0x33, 0xAF,
4596 0x2F, 0xC0, 0x21, 0xC0,
4597
4598 0x16, 0x42, 0x56, 0x9F,
4599 0x3C, 0x27, 0x4F, 0xE9,
4600
4601 0x1E, 0x62, 0x57, 0x9F,
4602 0x00, 0x80, 0x00, 0xE8,
4603
4604 0x25, 0x21, 0x31, 0xB4,
4605 0x2D, 0x21, 0x1A, 0xB4,
4606
4607 0x3F, 0x2F, 0x5D, 0x9F,
4608 0x00, 0x80, 0x00, 0xE8,
4609
4610 0x33, 0x05,
4611 0x00, 0xE0,
4612 0x28, 0x19, 0x60, 0xEC,
4613
4614 0x0D, 0x21, 0x1A, 0xB6,
4615 0x05, 0x21, 0x31, 0xB6,
4616
4617 0x37, 0x0F, 0x5C, 0x9F,
4618 0x00, 0xE0,
4619 0x2F, 0x20,
4620
4621 0x23, 0x3B, 0x33, 0xAD,
4622 0x1E, 0x26, 0x1E, 0xDF,
4623
4624 0xA7, 0x1E, 0x4F, 0xE9,
4625 0x17, 0x26, 0x16, 0xDF,
4626
4627 0x2D, 0x20,
4628 0x00, 0xE0,
4629 0xA8, 0x3F, 0x4F, 0xE9,
4630
4631 0x2F, 0x2F, 0x1E, 0xAF,
4632 0x25, 0x20,
4633 0x00, 0xE0,
4634
4635 0xA4, 0x16, 0x4F, 0xE9,
4636 0x0F, 0xC0, 0x21, 0xC2,
4637
4638 0xA6, 0x80, 0x4F, 0xE9,
4639 0x1F, 0x62, 0x57, 0x9F,
4640
4641 0x0D, 0x20,
4642 0x05, 0x20,
4643 0x2F, 0xC0, 0x21, 0xC6,
4644
4645 0x3F, 0x2F, 0x5D, 0x9F,
4646 0x00, 0xE0,
4647 0x0F, 0x20,
4648
4649 0x17, 0x50, 0x56, 0x9F,
4650 0xA5, 0x37, 0x4F, 0xE9,
4651
4652 0x06, 0xC0, 0x21, 0xC4,
4653 0x0F, 0x17, 0x0F, 0xAF,
4654
4655 0x37, 0x0F, 0x5C, 0x9F,
4656 0x00, 0x80, 0x00, 0xE8,
4657
4658 0x2F, 0x20,
4659 0x00, 0xE0,
4660 0xA3, 0x80, 0x4F, 0xE9,
4661
4662 0x06, 0x20,
4663 0x00, 0xE0,
4664 0x1F, 0x26, 0x1F, 0xDF,
4665
4666 0x17, 0x26, 0x17, 0xDF,
4667 0x35, 0x17, 0x4F, 0xE9,
4668
4669 0xA1, 0x1F, 0x4F, 0xE9,
4670 0xA2, 0x3F, 0x4F, 0xE9,
4671
4672 0x06, 0x06, 0x1F, 0xAF,
4673 0x39, 0x37, 0x4F, 0xE9,
4674
4675 0x2F, 0x2F, 0x17, 0xAF,
4676 0x00, 0x80, 0x00, 0xE8,
4677
4678 0xA0, 0x80, 0x4F, 0xE9,
4679 0x00, 0x80, 0x00, 0xE8,
4680
4681 0x31, 0x80, 0x4F, 0xE9,
4682 0x00, 0x80, 0x00, 0xE8,
4683
4684 0x00, 0x80, 0x00, 0xE8,
4685 0x57, 0x39, 0x20, 0xE9,
4686
4687 0x16, 0x28, 0x20, 0xE9,
4688 0x1D, 0x3B, 0x20, 0xE9,
4689
4690 0x1E, 0x2B, 0x20, 0xE9,
4691 0x2B, 0x32, 0x20, 0xE9,
4692
4693 0x1C, 0x23, 0x20, 0xE9,
4694 0x57, 0x36, 0x20, 0xE9,
4695
4696 0x00, 0x80, 0xA0, 0xE9,
4697 0x40, 0x40, 0xD8, 0xEC,
4698
4699 0xFF, 0x80, 0xC0, 0xE9,
4700 0x90, 0xE2,
4701 0x00, 0xE0,
4702
4703 0x68, 0xFF, 0x20, 0xEA,
4704 0x19, 0xC8, 0xC1, 0xCD,
4705
4706 0x1F, 0xD7, 0x18, 0xBD,
4707 0x3F, 0xD7, 0x22, 0xBD,
4708
4709 0x9F, 0x41, 0x49, 0xBD,
4710 0x00, 0x80, 0x00, 0xE8,
4711
4712 0x25, 0x41, 0x49, 0xBD,
4713 0x2D, 0x41, 0x51, 0xBD,
4714
4715 0x0D, 0x80, 0x07, 0xEA,
4716 0x00, 0x80, 0x00, 0xE8,
4717
4718 0x35, 0x40, 0x48, 0xBD,
4719 0x3D, 0x40, 0x50, 0xBD,
4720
4721 0x00, 0x80, 0x00, 0xE8,
4722 0x25, 0x30,
4723 0x2D, 0x30,
4724
4725 0x35, 0x30,
4726 0xB5, 0x30,
4727 0xBD, 0x30,
4728 0x3D, 0x30,
4729
4730 0x9C, 0xA7, 0x5B, 0x9F,
4731 0x00, 0x80, 0x00, 0xE8,
4732
4733 0x00, 0x80, 0x00, 0xE8,
4734 0x00, 0x80, 0x00, 0xE8,
4735
4736 0x00, 0x80, 0x00, 0xE8,
4737 0x00, 0x80, 0x00, 0xE8,
4738
4739 0x00, 0x80, 0x00, 0xE8,
4740 0x00, 0x80, 0x00, 0xE8,
4741
4742 0x00, 0x80, 0x00, 0xE8,
4743 0x00, 0x80, 0x00, 0xE8,
4744
4745 0x67, 0xFF, 0x0A, 0xEA,
4746 0x00, 0x80, 0x00, 0xE8,
4747
4748 0xC9, 0x41, 0xC8, 0xEC,
4749 0x42, 0xE1,
4750 0x00, 0xE0,
4751
4752 0x65, 0xFF, 0x20, 0xEA,
4753 0x00, 0x80, 0x00, 0xE8,
4754
4755 0x00, 0x80, 0x00, 0xE8,
4756 0x00, 0x80, 0x00, 0xE8,
4757
4758 0xC8, 0x40, 0xC0, 0xEC,
4759 0x00, 0x80, 0x00, 0xE8,
4760
4761 0x62, 0xFF, 0x20, 0xEA,
4762 0x00, 0x80, 0x00, 0xE8,
4763
4764 0x00, 0x80, 0x00, 0xE8,
4765 0x00, 0x80, 0x00, 0xE8,
4766
4767};
4768
4769static unsigned char warp_g400_t2gz[] = {
4770
4771 0x00, 0x8A, 0x98, 0xE9,
4772 0x00, 0x80, 0x00, 0xE8,
4773
4774 0x00, 0x80, 0xA0, 0xE9,
4775 0x00, 0x00, 0xD8, 0xEC,
4776
4777 0xFF, 0x80, 0xC0, 0xE9,
4778 0x00, 0x80, 0x00, 0xE8,
4779
4780 0x0A, 0x40, 0x50, 0xBF,
4781 0x2A, 0x40, 0x60, 0xBF,
4782
4783 0x32, 0x41, 0x51, 0xBF,
4784 0x3A, 0x41, 0x61, 0xBF,
4785
4786 0xC3, 0x6B,
4787 0xD3, 0x6B,
4788 0x00, 0x8A, 0x98, 0xE9,
4789
4790 0x73, 0x7B, 0xC8, 0xEC,
4791 0x96, 0xE2,
4792 0x41, 0x04,
4793
4794 0x7B, 0x43, 0xA0, 0xE8,
4795 0x73, 0x53, 0xA0, 0xE8,
4796
4797 0xAD, 0xEE, 0x23, 0x9F,
4798 0x00, 0xE0,
4799 0x51, 0x04,
4800
4801 0x90, 0xE2,
4802 0x61, 0x04,
4803 0x31, 0x46, 0xB1, 0xE8,
4804
4805 0x51, 0x41, 0xE0, 0xEC,
4806 0x39, 0x67, 0xB1, 0xE8,
4807
4808 0x00, 0x04,
4809 0x46, 0xE2,
4810 0x73, 0x63, 0xA0, 0xE8,
4811
4812 0x61, 0x41, 0xE0, 0xEC,
4813 0x31, 0x00,
4814 0x39, 0x00,
4815
4816 0x78, 0x80, 0x15, 0xEA,
4817 0x10, 0x04,
4818 0x20, 0x04,
4819
4820 0x61, 0x51, 0xE0, 0xEC,
4821 0x2F, 0x41, 0x60, 0xEA,
4822
4823 0x31, 0x20,
4824 0x39, 0x20,
4825 0x1F, 0x42, 0xA0, 0xE8,
4826
4827 0x2A, 0x42, 0x52, 0xBF,
4828 0x0F, 0x52, 0xA0, 0xE8,
4829
4830 0x1A, 0x42, 0x62, 0xBF,
4831 0x1E, 0x51, 0x60, 0xEA,
4832
4833 0x73, 0x7B, 0xC8, 0xEC,
4834 0x0E, 0x61, 0x60, 0xEA,
4835
4836 0x32, 0x40, 0x50, 0xBD,
4837 0x22, 0x40, 0x60, 0xBD,
4838
4839 0x12, 0x41, 0x51, 0xBD,
4840 0x3A, 0x41, 0x61, 0xBD,
4841
4842 0xBF, 0x2F, 0x0E, 0xBD,
4843 0x97, 0xE2,
4844 0x7B, 0x72,
4845
4846 0x32, 0x20,
4847 0x22, 0x20,
4848 0x12, 0x20,
4849 0x3A, 0x20,
4850
4851 0x35, 0x48, 0xB1, 0xE8,
4852 0x3D, 0x59, 0xB1, 0xE8,
4853
4854 0x46, 0x31, 0x46, 0xBF,
4855 0x56, 0x31, 0x56, 0xBF,
4856
4857 0xB3, 0xE2, 0x2D, 0x9F,
4858 0x00, 0x80, 0x00, 0xE8,
4859
4860 0x66, 0x31, 0x66, 0xBF,
4861 0x47, 0x39, 0x47, 0xBF,
4862
4863 0x57, 0x39, 0x57, 0xBF,
4864 0x67, 0x39, 0x67, 0xBF,
4865
4866 0x69, 0x80, 0x07, 0xEA,
4867 0x24, 0x41, 0x20, 0xE9,
4868
4869 0x35, 0x00,
4870 0x3D, 0x00,
4871 0x00, 0xE0,
4872 0x2D, 0x73,
4873
4874 0x33, 0x72,
4875 0x0C, 0xE3,
4876 0x8D, 0x2F, 0x1E, 0xBD,
4877
4878 0x43, 0x75, 0xF8, 0xEC,
4879 0x35, 0x20,
4880 0x3D, 0x20,
4881
4882 0x43, 0x43, 0x2D, 0xDF,
4883 0x53, 0x53, 0x2D, 0xDF,
4884
4885 0xAE, 0x1E, 0x0E, 0xBD,
4886 0x58, 0xE3,
4887 0x33, 0x66,
4888
4889 0x48, 0x35, 0x48, 0xBF,
4890 0x58, 0x35, 0x58, 0xBF,
4891
4892 0x68, 0x35, 0x68, 0xBF,
4893 0x49, 0x3D, 0x49, 0xBF,
4894
4895 0x59, 0x3D, 0x59, 0xBF,
4896 0x69, 0x3D, 0x69, 0xBF,
4897
4898 0x63, 0x63, 0x2D, 0xDF,
4899 0x4D, 0x7D, 0xF8, 0xEC,
4900
4901 0x59, 0xE3,
4902 0x00, 0xE0,
4903 0xB8, 0x38, 0x33, 0xBF,
4904
4905 0x2D, 0x73,
4906 0x30, 0x76,
4907 0x18, 0x3A, 0x41, 0xE9,
4908
4909 0x3F, 0x53, 0xA0, 0xE8,
4910 0x05, 0x80, 0x3D, 0xEA,
4911
4912 0x37, 0x43, 0xA0, 0xE8,
4913 0x3D, 0x63, 0xA0, 0xE8,
4914
4915 0x50, 0x70, 0xF8, 0xEC,
4916 0x2B, 0x50, 0x3C, 0xE9,
4917
4918 0x1F, 0x0F, 0xBC, 0xE8,
4919 0x00, 0x80, 0x00, 0xE8,
4920
4921 0x59, 0x78, 0xF8, 0xEC,
4922 0x00, 0x80, 0x00, 0xE8,
4923
4924 0x15, 0xC0, 0x20, 0xE9,
4925 0x15, 0xC0, 0x20, 0xE9,
4926
4927 0x15, 0xC0, 0x20, 0xE9,
4928 0x15, 0xC0, 0x20, 0xE9,
4929
4930 0x1E, 0x12, 0x41, 0xE9,
4931 0x1A, 0x22, 0x41, 0xE9,
4932
4933 0x46, 0x37, 0x46, 0xDF,
4934 0x56, 0x3F, 0x56, 0xDF,
4935
4936 0x2B, 0x40, 0x3D, 0xE9,
4937 0x66, 0x3D, 0x66, 0xDF,
4938
4939 0x1D, 0x32, 0x41, 0xE9,
4940 0x67, 0x3D, 0x67, 0xDF,
4941
4942 0x47, 0x37, 0x47, 0xDF,
4943 0x57, 0x3F, 0x57, 0xDF,
4944
4945 0x2A, 0x40, 0x20, 0xE9,
4946 0x59, 0x3F, 0x59, 0xDF,
4947
4948 0x16, 0x30, 0x20, 0xE9,
4949 0x69, 0x3D, 0x69, 0xDF,
4950
4951 0x48, 0x37, 0x48, 0xDF,
4952 0x58, 0x3F, 0x58, 0xDF,
4953
4954 0x12, 0x12, 0x2D, 0xDF,
4955 0x22, 0x22, 0x2D, 0xDF,
4956
4957 0x32, 0x32, 0x2D, 0xDF,
4958 0x3A, 0x3A, 0x2D, 0xDF,
4959
4960 0x68, 0x3D, 0x68, 0xDF,
4961 0x49, 0x37, 0x49, 0xDF,
4962
4963 0x3D, 0xCF, 0x74, 0xC0,
4964 0x37, 0xCF, 0x74, 0xC4,
4965
4966 0x31, 0x53, 0x2F, 0x9F,
4967 0x34, 0x80, 0x20, 0xE9,
4968
4969 0x39, 0xE5, 0x2C, 0x9F,
4970 0x3C, 0x3D, 0x20, 0xE9,
4971
4972 0x0A, 0x44, 0x54, 0xB0,
4973 0x02, 0x44, 0x64, 0xB0,
4974
4975 0x2A, 0x44, 0x54, 0xB2,
4976 0x1A, 0x44, 0x64, 0xB2,
4977
4978 0x25, 0x80, 0x3A, 0xEA,
4979 0x0A, 0x20,
4980 0x02, 0x20,
4981
4982 0x3D, 0xCF, 0x74, 0xC2,
4983 0x2A, 0x20,
4984 0x1A, 0x20,
4985
4986 0x30, 0x50, 0x2E, 0x9F,
4987 0x32, 0x31, 0x5F, 0xE9,
4988
4989 0x38, 0x21, 0x2C, 0x9F,
4990 0x33, 0x39, 0x5F, 0xE9,
4991
4992 0x31, 0x53, 0x2F, 0x9F,
4993 0x00, 0x80, 0x00, 0xE8,
4994
4995 0x2A, 0x44, 0x54, 0xB4,
4996 0x1A, 0x44, 0x64, 0xB4,
4997
4998 0x39, 0xE5, 0x2C, 0x9F,
4999 0x38, 0x3D, 0x20, 0xE9,
5000
5001 0x88, 0x73, 0x5E, 0xE9,
5002 0x2A, 0x20,
5003 0x1A, 0x20,
5004
5005 0x2A, 0x46, 0x56, 0xBF,
5006 0x1A, 0x46, 0x66, 0xBF,
5007
5008 0x31, 0x53, 0x2F, 0x9F,
5009 0x3E, 0x30, 0x4F, 0xE9,
5010
5011 0x39, 0xE5, 0x2C, 0x9F,
5012 0x3F, 0x38, 0x4F, 0xE9,
5013
5014 0x0A, 0x47, 0x57, 0xBF,
5015 0x02, 0x47, 0x67, 0xBF,
5016
5017 0x31, 0x53, 0x2F, 0x9F,
5018 0x3A, 0x31, 0x4F, 0xE9,
5019
5020 0x39, 0xE5, 0x2C, 0x9F,
5021 0x3B, 0x39, 0x4F, 0xE9,
5022
5023 0x2A, 0x43, 0x53, 0xBF,
5024 0x1A, 0x43, 0x63, 0xBF,
5025
5026 0x30, 0x50, 0x2E, 0x9F,
5027 0x36, 0x31, 0x4F, 0xE9,
5028
5029 0x38, 0x21, 0x2C, 0x9F,
5030 0x37, 0x39, 0x4F, 0xE9,
5031
5032 0x0A, 0x48, 0x58, 0xBF,
5033 0x02, 0x48, 0x68, 0xBF,
5034
5035 0x31, 0x53, 0x2F, 0x9F,
5036 0x80, 0x31, 0x57, 0xE9,
5037
5038 0x39, 0xE5, 0x2C, 0x9F,
5039 0x81, 0x39, 0x57, 0xE9,
5040
5041 0x2A, 0x49, 0x59, 0xBF,
5042 0x1A, 0x49, 0x69, 0xBF,
5043
5044 0x30, 0x50, 0x2E, 0x9F,
5045 0x82, 0x30, 0x57, 0xE9,
5046
5047 0x38, 0x21, 0x2C, 0x9F,
5048 0x83, 0x38, 0x57, 0xE9,
5049
5050 0x31, 0x53, 0x2F, 0x9F,
5051 0x84, 0x31, 0x5E, 0xE9,
5052
5053 0x39, 0xE5, 0x2C, 0x9F,
5054 0x85, 0x39, 0x5E, 0xE9,
5055
5056 0x86, 0x76, 0x57, 0xE9,
5057 0x8A, 0x36, 0x20, 0xE9,
5058
5059 0x87, 0x77, 0x57, 0xE9,
5060 0x8B, 0x3E, 0xBF, 0xEA,
5061
5062 0x80, 0x30, 0x57, 0xE9,
5063 0x81, 0x38, 0x57, 0xE9,
5064
5065 0x82, 0x31, 0x57, 0xE9,
5066 0x86, 0x78, 0x57, 0xE9,
5067
5068 0x83, 0x39, 0x57, 0xE9,
5069 0x87, 0x79, 0x57, 0xE9,
5070
5071 0x30, 0x1F, 0x5F, 0xE9,
5072 0x8A, 0x34, 0x20, 0xE9,
5073
5074 0x8B, 0x3C, 0x20, 0xE9,
5075 0x37, 0x50, 0x60, 0xBD,
5076
5077 0x57, 0x0D, 0x20, 0xE9,
5078 0x35, 0x51, 0x61, 0xBD,
5079
5080 0x2B, 0x50, 0x20, 0xE9,
5081 0x1D, 0x37, 0xE1, 0xEA,
5082
5083 0x1E, 0x35, 0xE1, 0xEA,
5084 0x00, 0xE0,
5085 0x0E, 0x77,
5086
5087 0x24, 0x51, 0x20, 0xE9,
5088 0x9F, 0xFF, 0x20, 0xEA,
5089
5090 0x16, 0x0E, 0x20, 0xE9,
5091 0x57, 0x2E, 0xBF, 0xEA,
5092
5093 0x0B, 0x46, 0xA0, 0xE8,
5094 0x1B, 0x56, 0xA0, 0xE8,
5095
5096 0x2B, 0x66, 0xA0, 0xE8,
5097 0x0C, 0x47, 0xA0, 0xE8,
5098
5099 0x1C, 0x57, 0xA0, 0xE8,
5100 0x2C, 0x67, 0xA0, 0xE8,
5101
5102 0x0B, 0x00,
5103 0x1B, 0x00,
5104 0x2B, 0x00,
5105 0x00, 0xE0,
5106
5107 0x0C, 0x00,
5108 0x1C, 0x00,
5109 0x2C, 0x00,
5110 0x00, 0xE0,
5111
5112 0x0B, 0x65,
5113 0x1B, 0x65,
5114 0x2B, 0x65,
5115 0x00, 0xE0,
5116
5117 0x0C, 0x65,
5118 0x1C, 0x65,
5119 0x2C, 0x65,
5120 0x00, 0xE0,
5121
5122 0x0B, 0x1B, 0x60, 0xEC,
5123 0x36, 0xD7, 0x36, 0xAD,
5124
5125 0x2B, 0x80, 0x60, 0xEC,
5126 0x0C, 0x1C, 0x60, 0xEC,
5127
5128 0x3E, 0xD7, 0x3E, 0xAD,
5129 0x2C, 0x80, 0x60, 0xEC,
5130
5131 0x0B, 0x2B, 0xDE, 0xE8,
5132 0x1B, 0x80, 0xDE, 0xE8,
5133
5134 0x36, 0x80, 0x36, 0xBD,
5135 0x3E, 0x80, 0x3E, 0xBD,
5136
5137 0x33, 0xD7, 0x0B, 0xBD,
5138 0x3B, 0xD7, 0x1B, 0xBD,
5139
5140 0x46, 0x80, 0x46, 0xCF,
5141 0x57, 0x80, 0x57, 0xCF,
5142
5143 0x66, 0x33, 0x66, 0xCF,
5144 0x47, 0x3B, 0x47, 0xCF,
5145
5146 0x56, 0x33, 0x56, 0xCF,
5147 0x67, 0x3B, 0x67, 0xCF,
5148
5149 0x0B, 0x48, 0xA0, 0xE8,
5150 0x1B, 0x58, 0xA0, 0xE8,
5151
5152 0x2B, 0x68, 0xA0, 0xE8,
5153 0x0C, 0x49, 0xA0, 0xE8,
5154
5155 0x1C, 0x59, 0xA0, 0xE8,
5156 0x2C, 0x69, 0xA0, 0xE8,
5157
5158 0x0B, 0x00,
5159 0x1B, 0x00,
5160 0x2B, 0x00,
5161 0x00, 0xE0,
5162
5163 0x0C, 0x00,
5164 0x1C, 0x00,
5165 0x2C, 0x00,
5166 0x00, 0xE0,
5167
5168 0x0B, 0x65,
5169 0x1B, 0x65,
5170 0x2B, 0x65,
5171 0x00, 0xE0,
5172
5173 0x0C, 0x65,
5174 0x1C, 0x65,
5175 0x2C, 0x65,
5176 0x00, 0xE0,
5177
5178 0x0B, 0x1B, 0x60, 0xEC,
5179 0x34, 0xD7, 0x34, 0xAD,
5180
5181 0x2B, 0x80, 0x60, 0xEC,
5182 0x0C, 0x1C, 0x60, 0xEC,
5183
5184 0x3C, 0xD7, 0x3C, 0xAD,
5185 0x2C, 0x80, 0x60, 0xEC,
5186
5187 0x0B, 0x2B, 0xDE, 0xE8,
5188 0x1B, 0x80, 0xDE, 0xE8,
5189
5190 0x34, 0x80, 0x34, 0xBD,
5191 0x3C, 0x80, 0x3C, 0xBD,
5192
5193 0x33, 0xD7, 0x0B, 0xBD,
5194 0x3B, 0xD7, 0x1B, 0xBD,
5195
5196 0x48, 0x80, 0x48, 0xCF,
5197 0x59, 0x80, 0x59, 0xCF,
5198
5199 0x68, 0x33, 0x68, 0xCF,
5200 0x49, 0x3B, 0x49, 0xCF,
5201
5202 0xBE, 0xFF, 0x20, 0xEA,
5203 0x00, 0x80, 0x00, 0xE8,
5204
5205 0x58, 0x33, 0x58, 0xCF,
5206 0x69, 0x3B, 0x69, 0xCF,
5207
5208 0x7D, 0xFF, 0x20, 0xEA,
5209 0x57, 0xC0, 0xBF, 0xEA,
5210
5211 0x00, 0x80, 0xA0, 0xE9,
5212 0x00, 0x00, 0xD8, 0xEC,
5213
5214};
5215
5216static unsigned char warp_g400_t2gza[] = {
5217
5218 0x00, 0x8A, 0x98, 0xE9,
5219 0x00, 0x80, 0x00, 0xE8,
5220
5221 0x00, 0x80, 0xA0, 0xE9,
5222 0x00, 0x00, 0xD8, 0xEC,
5223
5224 0xFF, 0x80, 0xC0, 0xE9,
5225 0x00, 0x80, 0x00, 0xE8,
5226
5227 0x0A, 0x40, 0x50, 0xBF,
5228 0x2A, 0x40, 0x60, 0xBF,
5229
5230 0x32, 0x41, 0x51, 0xBF,
5231 0x3A, 0x41, 0x61, 0xBF,
5232
5233 0xC3, 0x6B,
5234 0xD3, 0x6B,
5235 0x00, 0x8A, 0x98, 0xE9,
5236
5237 0x73, 0x7B, 0xC8, 0xEC,
5238 0x96, 0xE2,
5239 0x41, 0x04,
5240
5241 0x7B, 0x43, 0xA0, 0xE8,
5242 0x73, 0x53, 0xA0, 0xE8,
5243
5244 0xAD, 0xEE, 0x23, 0x9F,
5245 0x00, 0xE0,
5246 0x51, 0x04,
5247
5248 0x90, 0xE2,
5249 0x61, 0x04,
5250 0x31, 0x46, 0xB1, 0xE8,
5251
5252 0x51, 0x41, 0xE0, 0xEC,
5253 0x39, 0x67, 0xB1, 0xE8,
5254
5255 0x00, 0x04,
5256 0x46, 0xE2,
5257 0x73, 0x63, 0xA0, 0xE8,
5258
5259 0x61, 0x41, 0xE0, 0xEC,
5260 0x31, 0x00,
5261 0x39, 0x00,
5262
5263 0x7C, 0x80, 0x15, 0xEA,
5264 0x10, 0x04,
5265 0x20, 0x04,
5266
5267 0x61, 0x51, 0xE0, 0xEC,
5268 0x2F, 0x41, 0x60, 0xEA,
5269
5270 0x31, 0x20,
5271 0x39, 0x20,
5272 0x1F, 0x42, 0xA0, 0xE8,
5273
5274 0x2A, 0x42, 0x52, 0xBF,
5275 0x0F, 0x52, 0xA0, 0xE8,
5276
5277 0x1A, 0x42, 0x62, 0xBF,
5278 0x1E, 0x51, 0x60, 0xEA,
5279
5280 0x73, 0x7B, 0xC8, 0xEC,
5281 0x0E, 0x61, 0x60, 0xEA,
5282
5283 0x32, 0x40, 0x50, 0xBD,
5284 0x22, 0x40, 0x60, 0xBD,
5285
5286 0x12, 0x41, 0x51, 0xBD,
5287 0x3A, 0x41, 0x61, 0xBD,
5288
5289 0xBF, 0x2F, 0x0E, 0xBD,
5290 0x97, 0xE2,
5291 0x7B, 0x72,
5292
5293 0x32, 0x20,
5294 0x22, 0x20,
5295 0x12, 0x20,
5296 0x3A, 0x20,
5297
5298 0x35, 0x48, 0xB1, 0xE8,
5299 0x3D, 0x59, 0xB1, 0xE8,
5300
5301 0x46, 0x31, 0x46, 0xBF,
5302 0x56, 0x31, 0x56, 0xBF,
5303
5304 0xB3, 0xE2, 0x2D, 0x9F,
5305 0x00, 0x80, 0x00, 0xE8,
5306
5307 0x66, 0x31, 0x66, 0xBF,
5308 0x47, 0x39, 0x47, 0xBF,
5309
5310 0x57, 0x39, 0x57, 0xBF,
5311 0x67, 0x39, 0x67, 0xBF,
5312
5313 0x6D, 0x80, 0x07, 0xEA,
5314 0x24, 0x41, 0x20, 0xE9,
5315
5316 0x35, 0x00,
5317 0x3D, 0x00,
5318 0x00, 0xE0,
5319 0x2D, 0x73,
5320
5321 0x33, 0x72,
5322 0x0C, 0xE3,
5323 0x8D, 0x2F, 0x1E, 0xBD,
5324
5325 0x43, 0x75, 0xF8, 0xEC,
5326 0x35, 0x20,
5327 0x3D, 0x20,
5328
5329 0x43, 0x43, 0x2D, 0xDF,
5330 0x53, 0x53, 0x2D, 0xDF,
5331
5332 0xAE, 0x1E, 0x0E, 0xBD,
5333 0x58, 0xE3,
5334 0x33, 0x66,
5335
5336 0x48, 0x35, 0x48, 0xBF,
5337 0x58, 0x35, 0x58, 0xBF,
5338
5339 0x68, 0x35, 0x68, 0xBF,
5340 0x49, 0x3D, 0x49, 0xBF,
5341
5342 0x59, 0x3D, 0x59, 0xBF,
5343 0x69, 0x3D, 0x69, 0xBF,
5344
5345 0x63, 0x63, 0x2D, 0xDF,
5346 0x4D, 0x7D, 0xF8, 0xEC,
5347
5348 0x59, 0xE3,
5349 0x00, 0xE0,
5350 0xB8, 0x38, 0x33, 0xBF,
5351
5352 0x2D, 0x73,
5353 0x30, 0x76,
5354 0x18, 0x3A, 0x41, 0xE9,
5355
5356 0x3F, 0x53, 0xA0, 0xE8,
5357 0x05, 0x80, 0x3D, 0xEA,
5358
5359 0x37, 0x43, 0xA0, 0xE8,
5360 0x3D, 0x63, 0xA0, 0xE8,
5361
5362 0x50, 0x70, 0xF8, 0xEC,
5363 0x2B, 0x50, 0x3C, 0xE9,
5364
5365 0x1F, 0x0F, 0xBC, 0xE8,
5366 0x00, 0x80, 0x00, 0xE8,
5367
5368 0x59, 0x78, 0xF8, 0xEC,
5369 0x00, 0x80, 0x00, 0xE8,
5370
5371 0x15, 0xC0, 0x20, 0xE9,
5372 0x15, 0xC0, 0x20, 0xE9,
5373
5374 0x15, 0xC0, 0x20, 0xE9,
5375 0x15, 0xC0, 0x20, 0xE9,
5376
5377 0x1E, 0x12, 0x41, 0xE9,
5378 0x1A, 0x22, 0x41, 0xE9,
5379
5380 0x46, 0x37, 0x46, 0xDF,
5381 0x56, 0x3F, 0x56, 0xDF,
5382
5383 0x2B, 0x40, 0x3D, 0xE9,
5384 0x66, 0x3D, 0x66, 0xDF,
5385
5386 0x1D, 0x32, 0x41, 0xE9,
5387 0x67, 0x3D, 0x67, 0xDF,
5388
5389 0x47, 0x37, 0x47, 0xDF,
5390 0x57, 0x3F, 0x57, 0xDF,
5391
5392 0x2A, 0x40, 0x20, 0xE9,
5393 0x59, 0x3F, 0x59, 0xDF,
5394
5395 0x16, 0x30, 0x20, 0xE9,
5396 0x69, 0x3D, 0x69, 0xDF,
5397
5398 0x48, 0x37, 0x48, 0xDF,
5399 0x58, 0x3F, 0x58, 0xDF,
5400
5401 0x12, 0x12, 0x2D, 0xDF,
5402 0x22, 0x22, 0x2D, 0xDF,
5403
5404 0x32, 0x32, 0x2D, 0xDF,
5405 0x3A, 0x3A, 0x2D, 0xDF,
5406
5407 0x68, 0x3D, 0x68, 0xDF,
5408 0x49, 0x37, 0x49, 0xDF,
5409
5410 0x3D, 0xCF, 0x74, 0xC0,
5411 0x37, 0xCF, 0x74, 0xC4,
5412
5413 0x31, 0x53, 0x2F, 0x9F,
5414 0x34, 0x80, 0x20, 0xE9,
5415
5416 0x39, 0xE5, 0x2C, 0x9F,
5417 0x3C, 0x3D, 0x20, 0xE9,
5418
5419 0x0A, 0x44, 0x54, 0xB0,
5420 0x02, 0x44, 0x64, 0xB0,
5421
5422 0x2A, 0x44, 0x54, 0xB2,
5423 0x1A, 0x44, 0x64, 0xB2,
5424
5425 0x29, 0x80, 0x3A, 0xEA,
5426 0x0A, 0x20,
5427 0x02, 0x20,
5428
5429 0x0F, 0xCF, 0x74, 0xC6,
5430 0x3D, 0xCF, 0x74, 0xC2,
5431
5432 0x88, 0x73, 0x5E, 0xE9,
5433 0x2A, 0x20,
5434 0x1A, 0x20,
5435
5436 0x30, 0x50, 0x2E, 0x9F,
5437 0x32, 0x31, 0x5F, 0xE9,
5438
5439 0x38, 0x21, 0x2C, 0x9F,
5440 0x33, 0x39, 0x5F, 0xE9,
5441
5442 0x31, 0x53, 0x2F, 0x9F,
5443 0x9C, 0x0F, 0x20, 0xE9,
5444
5445 0x0A, 0x44, 0x54, 0xB4,
5446 0x02, 0x44, 0x64, 0xB4,
5447
5448 0x2A, 0x44, 0x54, 0xB6,
5449 0x1A, 0x44, 0x64, 0xB6,
5450
5451 0x39, 0xE5, 0x2C, 0x9F,
5452 0x38, 0x3D, 0x20, 0xE9,
5453
5454 0x0A, 0x20,
5455 0x02, 0x20,
5456 0x2A, 0x20,
5457 0x1A, 0x20,
5458
5459 0x0A, 0x47, 0x57, 0xBF,
5460 0x02, 0x47, 0x67, 0xBF,
5461
5462 0x30, 0x50, 0x2E, 0x9F,
5463 0x3E, 0x30, 0x4F, 0xE9,
5464
5465 0x38, 0x21, 0x2C, 0x9F,
5466 0x3F, 0x38, 0x4F, 0xE9,
5467
5468 0x2A, 0x46, 0x56, 0xBF,
5469 0x1A, 0x46, 0x66, 0xBF,
5470
5471 0x31, 0x53, 0x2F, 0x9F,
5472 0x3A, 0x31, 0x4F, 0xE9,
5473
5474 0x39, 0xE5, 0x2C, 0x9F,
5475 0x3B, 0x39, 0x4F, 0xE9,
5476
5477 0x31, 0x53, 0x2F, 0x9F,
5478 0x36, 0x30, 0x4F, 0xE9,
5479
5480 0x39, 0xE5, 0x2C, 0x9F,
5481 0x37, 0x38, 0x4F, 0xE9,
5482
5483 0x2A, 0x43, 0x53, 0xBF,
5484 0x1A, 0x43, 0x63, 0xBF,
5485
5486 0x30, 0x50, 0x2E, 0x9F,
5487 0x9D, 0x31, 0x4F, 0xE9,
5488
5489 0x38, 0x21, 0x2C, 0x9F,
5490 0x9E, 0x39, 0x4F, 0xE9,
5491
5492 0x0A, 0x48, 0x58, 0xBF,
5493 0x02, 0x48, 0x68, 0xBF,
5494
5495 0x31, 0x53, 0x2F, 0x9F,
5496 0x80, 0x31, 0x57, 0xE9,
5497
5498 0x39, 0xE5, 0x2C, 0x9F,
5499 0x81, 0x39, 0x57, 0xE9,
5500
5501 0x2A, 0x49, 0x59, 0xBF,
5502 0x1A, 0x49, 0x69, 0xBF,
5503
5504 0x30, 0x50, 0x2E, 0x9F,
5505 0x82, 0x30, 0x57, 0xE9,
5506
5507 0x38, 0x21, 0x2C, 0x9F,
5508 0x83, 0x38, 0x57, 0xE9,
5509
5510 0x31, 0x53, 0x2F, 0x9F,
5511 0x84, 0x31, 0x5E, 0xE9,
5512
5513 0x39, 0xE5, 0x2C, 0x9F,
5514 0x85, 0x39, 0x5E, 0xE9,
5515
5516 0x86, 0x76, 0x57, 0xE9,
5517 0x8A, 0x36, 0x20, 0xE9,
5518
5519 0x87, 0x77, 0x57, 0xE9,
5520 0x8B, 0x3E, 0xBF, 0xEA,
5521
5522 0x80, 0x30, 0x57, 0xE9,
5523 0x81, 0x38, 0x57, 0xE9,
5524
5525 0x82, 0x31, 0x57, 0xE9,
5526 0x86, 0x78, 0x57, 0xE9,
5527
5528 0x83, 0x39, 0x57, 0xE9,
5529 0x87, 0x79, 0x57, 0xE9,
5530
5531 0x30, 0x1F, 0x5F, 0xE9,
5532 0x8A, 0x34, 0x20, 0xE9,
5533
5534 0x8B, 0x3C, 0x20, 0xE9,
5535 0x37, 0x50, 0x60, 0xBD,
5536
5537 0x57, 0x0D, 0x20, 0xE9,
5538 0x35, 0x51, 0x61, 0xBD,
5539
5540 0x2B, 0x50, 0x20, 0xE9,
5541 0x1D, 0x37, 0xE1, 0xEA,
5542
5543 0x1E, 0x35, 0xE1, 0xEA,
5544 0x00, 0xE0,
5545 0x0E, 0x77,
5546
5547 0x24, 0x51, 0x20, 0xE9,
5548 0x9B, 0xFF, 0x20, 0xEA,
5549
5550 0x16, 0x0E, 0x20, 0xE9,
5551 0x57, 0x2E, 0xBF, 0xEA,
5552
5553 0x0B, 0x46, 0xA0, 0xE8,
5554 0x1B, 0x56, 0xA0, 0xE8,
5555
5556 0x2B, 0x66, 0xA0, 0xE8,
5557 0x0C, 0x47, 0xA0, 0xE8,
5558
5559 0x1C, 0x57, 0xA0, 0xE8,
5560 0x2C, 0x67, 0xA0, 0xE8,
5561
5562 0x0B, 0x00,
5563 0x1B, 0x00,
5564 0x2B, 0x00,
5565 0x00, 0xE0,
5566
5567 0x0C, 0x00,
5568 0x1C, 0x00,
5569 0x2C, 0x00,
5570 0x00, 0xE0,
5571
5572 0x0B, 0x65,
5573 0x1B, 0x65,
5574 0x2B, 0x65,
5575 0x00, 0xE0,
5576
5577 0x0C, 0x65,
5578 0x1C, 0x65,
5579 0x2C, 0x65,
5580 0x00, 0xE0,
5581
5582 0x0B, 0x1B, 0x60, 0xEC,
5583 0x36, 0xD7, 0x36, 0xAD,
5584
5585 0x2B, 0x80, 0x60, 0xEC,
5586 0x0C, 0x1C, 0x60, 0xEC,
5587
5588 0x3E, 0xD7, 0x3E, 0xAD,
5589 0x2C, 0x80, 0x60, 0xEC,
5590
5591 0x0B, 0x2B, 0xDE, 0xE8,
5592 0x1B, 0x80, 0xDE, 0xE8,
5593
5594 0x36, 0x80, 0x36, 0xBD,
5595 0x3E, 0x80, 0x3E, 0xBD,
5596
5597 0x33, 0xD7, 0x0B, 0xBD,
5598 0x3B, 0xD7, 0x1B, 0xBD,
5599
5600 0x46, 0x80, 0x46, 0xCF,
5601 0x57, 0x80, 0x57, 0xCF,
5602
5603 0x66, 0x33, 0x66, 0xCF,
5604 0x47, 0x3B, 0x47, 0xCF,
5605
5606 0x56, 0x33, 0x56, 0xCF,
5607 0x67, 0x3B, 0x67, 0xCF,
5608
5609 0x0B, 0x48, 0xA0, 0xE8,
5610 0x1B, 0x58, 0xA0, 0xE8,
5611
5612 0x2B, 0x68, 0xA0, 0xE8,
5613 0x0C, 0x49, 0xA0, 0xE8,
5614
5615 0x1C, 0x59, 0xA0, 0xE8,
5616 0x2C, 0x69, 0xA0, 0xE8,
5617
5618 0x0B, 0x00,
5619 0x1B, 0x00,
5620 0x2B, 0x00,
5621 0x00, 0xE0,
5622
5623 0x0C, 0x00,
5624 0x1C, 0x00,
5625 0x2C, 0x00,
5626 0x00, 0xE0,
5627
5628 0x0B, 0x65,
5629 0x1B, 0x65,
5630 0x2B, 0x65,
5631 0x00, 0xE0,
5632
5633 0x0C, 0x65,
5634 0x1C, 0x65,
5635 0x2C, 0x65,
5636 0x00, 0xE0,
5637
5638 0x0B, 0x1B, 0x60, 0xEC,
5639 0x34, 0xD7, 0x34, 0xAD,
5640
5641 0x2B, 0x80, 0x60, 0xEC,
5642 0x0C, 0x1C, 0x60, 0xEC,
5643
5644 0x3C, 0xD7, 0x3C, 0xAD,
5645 0x2C, 0x80, 0x60, 0xEC,
5646
5647 0x0B, 0x2B, 0xDE, 0xE8,
5648 0x1B, 0x80, 0xDE, 0xE8,
5649
5650 0x34, 0x80, 0x34, 0xBD,
5651 0x3C, 0x80, 0x3C, 0xBD,
5652
5653 0x33, 0xD7, 0x0B, 0xBD,
5654 0x3B, 0xD7, 0x1B, 0xBD,
5655
5656 0x48, 0x80, 0x48, 0xCF,
5657 0x59, 0x80, 0x59, 0xCF,
5658
5659 0x68, 0x33, 0x68, 0xCF,
5660 0x49, 0x3B, 0x49, 0xCF,
5661
5662 0xBA, 0xFF, 0x20, 0xEA,
5663 0x00, 0x80, 0x00, 0xE8,
5664
5665 0x58, 0x33, 0x58, 0xCF,
5666 0x69, 0x3B, 0x69, 0xCF,
5667
5668 0x79, 0xFF, 0x20, 0xEA,
5669 0x57, 0xC0, 0xBF, 0xEA,
5670
5671 0x00, 0x80, 0xA0, 0xE9,
5672 0x00, 0x00, 0xD8, 0xEC,
5673
5674};
5675
5676static unsigned char warp_g400_t2gzaf[] = {
5677
5678 0x00, 0x8A, 0x98, 0xE9,
5679 0x00, 0x80, 0x00, 0xE8,
5680
5681 0x00, 0x80, 0xA0, 0xE9,
5682 0x00, 0x00, 0xD8, 0xEC,
5683
5684 0xFF, 0x80, 0xC0, 0xE9,
5685 0x00, 0x80, 0x00, 0xE8,
5686
5687 0x0A, 0x40, 0x50, 0xBF,
5688 0x2A, 0x40, 0x60, 0xBF,
5689
5690 0x32, 0x41, 0x51, 0xBF,
5691 0x3A, 0x41, 0x61, 0xBF,
5692
5693 0xC3, 0x6B,
5694 0xD3, 0x6B,
5695 0x00, 0x8A, 0x98, 0xE9,
5696
5697 0x73, 0x7B, 0xC8, 0xEC,
5698 0x96, 0xE2,
5699 0x41, 0x04,
5700
5701 0x7B, 0x43, 0xA0, 0xE8,
5702 0x73, 0x53, 0xA0, 0xE8,
5703
5704 0xAD, 0xEE, 0x23, 0x9F,
5705 0x00, 0xE0,
5706 0x51, 0x04,
5707
5708 0x90, 0xE2,
5709 0x61, 0x04,
5710 0x31, 0x46, 0xB1, 0xE8,
5711
5712 0x51, 0x41, 0xE0, 0xEC,
5713 0x39, 0x67, 0xB1, 0xE8,
5714
5715 0x00, 0x04,
5716 0x46, 0xE2,
5717 0x73, 0x63, 0xA0, 0xE8,
5718
5719 0x61, 0x41, 0xE0, 0xEC,
5720 0x31, 0x00,
5721 0x39, 0x00,
5722
5723 0x81, 0x80, 0x15, 0xEA,
5724 0x10, 0x04,
5725 0x20, 0x04,
5726
5727 0x61, 0x51, 0xE0, 0xEC,
5728 0x2F, 0x41, 0x60, 0xEA,
5729
5730 0x31, 0x20,
5731 0x39, 0x20,
5732 0x1F, 0x42, 0xA0, 0xE8,
5733
5734 0x2A, 0x42, 0x52, 0xBF,
5735 0x0F, 0x52, 0xA0, 0xE8,
5736
5737 0x1A, 0x42, 0x62, 0xBF,
5738 0x1E, 0x51, 0x60, 0xEA,
5739
5740 0x73, 0x7B, 0xC8, 0xEC,
5741 0x0E, 0x61, 0x60, 0xEA,
5742
5743 0x32, 0x40, 0x50, 0xBD,
5744 0x22, 0x40, 0x60, 0xBD,
5745
5746 0x12, 0x41, 0x51, 0xBD,
5747 0x3A, 0x41, 0x61, 0xBD,
5748
5749 0xBF, 0x2F, 0x0E, 0xBD,
5750 0x97, 0xE2,
5751 0x7B, 0x72,
5752
5753 0x32, 0x20,
5754 0x22, 0x20,
5755 0x12, 0x20,
5756 0x3A, 0x20,
5757
5758 0x35, 0x48, 0xB1, 0xE8,
5759 0x3D, 0x59, 0xB1, 0xE8,
5760
5761 0x46, 0x31, 0x46, 0xBF,
5762 0x56, 0x31, 0x56, 0xBF,
5763
5764 0xB3, 0xE2, 0x2D, 0x9F,
5765 0x00, 0x80, 0x00, 0xE8,
5766
5767 0x66, 0x31, 0x66, 0xBF,
5768 0x47, 0x39, 0x47, 0xBF,
5769
5770 0x57, 0x39, 0x57, 0xBF,
5771 0x67, 0x39, 0x67, 0xBF,
5772
5773 0x72, 0x80, 0x07, 0xEA,
5774 0x24, 0x41, 0x20, 0xE9,
5775
5776 0x35, 0x00,
5777 0x3D, 0x00,
5778 0x00, 0xE0,
5779 0x2D, 0x73,
5780
5781 0x33, 0x72,
5782 0x0C, 0xE3,
5783 0x8D, 0x2F, 0x1E, 0xBD,
5784
5785 0x43, 0x75, 0xF8, 0xEC,
5786 0x35, 0x20,
5787 0x3D, 0x20,
5788
5789 0x43, 0x43, 0x2D, 0xDF,
5790 0x53, 0x53, 0x2D, 0xDF,
5791
5792 0xAE, 0x1E, 0x0E, 0xBD,
5793 0x58, 0xE3,
5794 0x33, 0x66,
5795
5796 0x48, 0x35, 0x48, 0xBF,
5797 0x58, 0x35, 0x58, 0xBF,
5798
5799 0x68, 0x35, 0x68, 0xBF,
5800 0x49, 0x3D, 0x49, 0xBF,
5801
5802 0x59, 0x3D, 0x59, 0xBF,
5803 0x69, 0x3D, 0x69, 0xBF,
5804
5805 0x63, 0x63, 0x2D, 0xDF,
5806 0x4D, 0x7D, 0xF8, 0xEC,
5807
5808 0x59, 0xE3,
5809 0x00, 0xE0,
5810 0xB8, 0x38, 0x33, 0xBF,
5811
5812 0x2D, 0x73,
5813 0x30, 0x76,
5814 0x18, 0x3A, 0x41, 0xE9,
5815
5816 0x3F, 0x53, 0xA0, 0xE8,
5817 0x05, 0x80, 0x3D, 0xEA,
5818
5819 0x37, 0x43, 0xA0, 0xE8,
5820 0x3D, 0x63, 0xA0, 0xE8,
5821
5822 0x50, 0x70, 0xF8, 0xEC,
5823 0x2B, 0x50, 0x3C, 0xE9,
5824
5825 0x1F, 0x0F, 0xBC, 0xE8,
5826 0x00, 0x80, 0x00, 0xE8,
5827
5828 0x59, 0x78, 0xF8, 0xEC,
5829 0x00, 0x80, 0x00, 0xE8,
5830
5831 0x15, 0xC0, 0x20, 0xE9,
5832 0x15, 0xC0, 0x20, 0xE9,
5833
5834 0x15, 0xC0, 0x20, 0xE9,
5835 0x15, 0xC0, 0x20, 0xE9,
5836
5837 0x1E, 0x12, 0x41, 0xE9,
5838 0x1A, 0x22, 0x41, 0xE9,
5839
5840 0x46, 0x37, 0x46, 0xDF,
5841 0x56, 0x3F, 0x56, 0xDF,
5842
5843 0x2B, 0x40, 0x3D, 0xE9,
5844 0x66, 0x3D, 0x66, 0xDF,
5845
5846 0x1D, 0x32, 0x41, 0xE9,
5847 0x67, 0x3D, 0x67, 0xDF,
5848
5849 0x47, 0x37, 0x47, 0xDF,
5850 0x57, 0x3F, 0x57, 0xDF,
5851
5852 0x2A, 0x40, 0x20, 0xE9,
5853 0x59, 0x3F, 0x59, 0xDF,
5854
5855 0x16, 0x30, 0x20, 0xE9,
5856 0x69, 0x3D, 0x69, 0xDF,
5857
5858 0x48, 0x37, 0x48, 0xDF,
5859 0x58, 0x3F, 0x58, 0xDF,
5860
5861 0x12, 0x12, 0x2D, 0xDF,
5862 0x22, 0x22, 0x2D, 0xDF,
5863
5864 0x32, 0x32, 0x2D, 0xDF,
5865 0x3A, 0x3A, 0x2D, 0xDF,
5866
5867 0x68, 0x3D, 0x68, 0xDF,
5868 0x49, 0x37, 0x49, 0xDF,
5869
5870 0x3D, 0xCF, 0x74, 0xC0,
5871 0x37, 0xCF, 0x74, 0xC4,
5872
5873 0x0A, 0x44, 0x54, 0xB0,
5874 0x02, 0x44, 0x64, 0xB0,
5875
5876 0x31, 0x53, 0x2F, 0x9F,
5877 0x34, 0x37, 0x20, 0xE9,
5878
5879 0x39, 0xE5, 0x2C, 0x9F,
5880 0x3C, 0x3D, 0x20, 0xE9,
5881
5882 0x2A, 0x44, 0x54, 0xB2,
5883 0x1A, 0x44, 0x64, 0xB2,
5884
5885 0x2E, 0x80, 0x3A, 0xEA,
5886 0x0A, 0x20,
5887 0x02, 0x20,
5888
5889 0x88, 0x73, 0x5E, 0xE9,
5890 0x2A, 0x20,
5891 0x1A, 0x20,
5892
5893 0x3D, 0xCF, 0x74, 0xC2,
5894 0x0F, 0xCF, 0x74, 0xC6,
5895
5896 0x30, 0x50, 0x2E, 0x9F,
5897 0x32, 0x31, 0x5F, 0xE9,
5898
5899 0x38, 0x21, 0x2C, 0x9F,
5900 0x33, 0x39, 0x5F, 0xE9,
5901
5902 0x31, 0x53, 0x2F, 0x9F,
5903 0x9C, 0x0F, 0x20, 0xE9,
5904
5905 0x0A, 0x44, 0x54, 0xB4,
5906 0x02, 0x44, 0x64, 0xB4,
5907
5908 0x2A, 0x44, 0x54, 0xB6,
5909 0x1A, 0x44, 0x64, 0xB6,
5910
5911 0x39, 0xE5, 0x2C, 0x9F,
5912 0x38, 0x3D, 0x20, 0xE9,
5913
5914 0x0A, 0x20,
5915 0x02, 0x20,
5916 0x2A, 0x20,
5917 0x1A, 0x20,
5918
5919 0x3D, 0xCF, 0x75, 0xC6,
5920 0x00, 0x80, 0x00, 0xE8,
5921
5922 0x30, 0x50, 0x2E, 0x9F,
5923 0x3E, 0x30, 0x4F, 0xE9,
5924
5925 0x38, 0x21, 0x2C, 0x9F,
5926 0x3F, 0x38, 0x4F, 0xE9,
5927
5928 0x0A, 0x45, 0x55, 0xB6,
5929 0x02, 0x45, 0x65, 0xB6,
5930
5931 0x31, 0x53, 0x2F, 0x9F,
5932 0x3A, 0x31, 0x4F, 0xE9,
5933
5934 0x39, 0xE5, 0x2C, 0x9F,
5935 0x3B, 0x39, 0x4F, 0xE9,
5936
5937 0x31, 0x3D, 0x20, 0xE9,
5938 0x0A, 0x20,
5939 0x02, 0x20,
5940
5941 0x2A, 0x46, 0x56, 0xBF,
5942 0x1A, 0x46, 0x66, 0xBF,
5943
5944 0x0A, 0x47, 0x57, 0xBF,
5945 0x02, 0x47, 0x67, 0xBF,
5946
5947 0x30, 0x50, 0x2E, 0x9F,
5948 0x36, 0x30, 0x4F, 0xE9,
5949
5950 0x38, 0x21, 0x2C, 0x9F,
5951 0x37, 0x38, 0x4F, 0xE9,
5952
5953 0x31, 0x53, 0x2F, 0x9F,
5954 0x9D, 0x31, 0x4F, 0xE9,
5955
5956 0x39, 0xE5, 0x2C, 0x9F,
5957 0x9E, 0x39, 0x4F, 0xE9,
5958
5959 0x2A, 0x43, 0x53, 0xBF,
5960 0x1A, 0x43, 0x63, 0xBF,
5961
5962 0x30, 0x50, 0x2E, 0x9F,
5963 0x35, 0x30, 0x4F, 0xE9,
5964
5965 0x38, 0x21, 0x2C, 0x9F,
5966 0x39, 0x38, 0x4F, 0xE9,
5967
5968 0x0A, 0x48, 0x58, 0xBF,
5969 0x02, 0x48, 0x68, 0xBF,
5970
5971 0x31, 0x53, 0x2F, 0x9F,
5972 0x80, 0x31, 0x57, 0xE9,
5973
5974 0x39, 0xE5, 0x2C, 0x9F,
5975 0x81, 0x39, 0x57, 0xE9,
5976
5977 0x2A, 0x49, 0x59, 0xBF,
5978 0x1A, 0x49, 0x69, 0xBF,
5979
5980 0x30, 0x50, 0x2E, 0x9F,
5981 0x82, 0x30, 0x57, 0xE9,
5982
5983 0x38, 0x21, 0x2C, 0x9F,
5984 0x83, 0x38, 0x57, 0xE9,
5985
5986 0x31, 0x53, 0x2F, 0x9F,
5987 0x84, 0x31, 0x5E, 0xE9,
5988
5989 0x39, 0xE5, 0x2C, 0x9F,
5990 0x85, 0x39, 0x5E, 0xE9,
5991
5992 0x86, 0x76, 0x57, 0xE9,
5993 0x8A, 0x36, 0x20, 0xE9,
5994
5995 0x87, 0x77, 0x57, 0xE9,
5996 0x8B, 0x3E, 0xBF, 0xEA,
5997
5998 0x80, 0x30, 0x57, 0xE9,
5999 0x81, 0x38, 0x57, 0xE9,
6000
6001 0x82, 0x31, 0x57, 0xE9,
6002 0x86, 0x78, 0x57, 0xE9,
6003
6004 0x83, 0x39, 0x57, 0xE9,
6005 0x87, 0x79, 0x57, 0xE9,
6006
6007 0x30, 0x1F, 0x5F, 0xE9,
6008 0x8A, 0x34, 0x20, 0xE9,
6009
6010 0x8B, 0x3C, 0x20, 0xE9,
6011 0x37, 0x50, 0x60, 0xBD,
6012
6013 0x57, 0x0D, 0x20, 0xE9,
6014 0x35, 0x51, 0x61, 0xBD,
6015
6016 0x2B, 0x50, 0x20, 0xE9,
6017 0x1D, 0x37, 0xE1, 0xEA,
6018
6019 0x1E, 0x35, 0xE1, 0xEA,
6020 0x00, 0xE0,
6021 0x0E, 0x77,
6022
6023 0x24, 0x51, 0x20, 0xE9,
6024 0x96, 0xFF, 0x20, 0xEA,
6025
6026 0x16, 0x0E, 0x20, 0xE9,
6027 0x57, 0x2E, 0xBF, 0xEA,
6028
6029 0x0B, 0x46, 0xA0, 0xE8,
6030 0x1B, 0x56, 0xA0, 0xE8,
6031
6032 0x2B, 0x66, 0xA0, 0xE8,
6033 0x0C, 0x47, 0xA0, 0xE8,
6034
6035 0x1C, 0x57, 0xA0, 0xE8,
6036 0x2C, 0x67, 0xA0, 0xE8,
6037
6038 0x0B, 0x00,
6039 0x1B, 0x00,
6040 0x2B, 0x00,
6041 0x00, 0xE0,
6042
6043 0x0C, 0x00,
6044 0x1C, 0x00,
6045 0x2C, 0x00,
6046 0x00, 0xE0,
6047
6048 0x0B, 0x65,
6049 0x1B, 0x65,
6050 0x2B, 0x65,
6051 0x00, 0xE0,
6052
6053 0x0C, 0x65,
6054 0x1C, 0x65,
6055 0x2C, 0x65,
6056 0x00, 0xE0,
6057
6058 0x0B, 0x1B, 0x60, 0xEC,
6059 0x36, 0xD7, 0x36, 0xAD,
6060
6061 0x2B, 0x80, 0x60, 0xEC,
6062 0x0C, 0x1C, 0x60, 0xEC,
6063
6064 0x3E, 0xD7, 0x3E, 0xAD,
6065 0x2C, 0x80, 0x60, 0xEC,
6066
6067 0x0B, 0x2B, 0xDE, 0xE8,
6068 0x1B, 0x80, 0xDE, 0xE8,
6069
6070 0x36, 0x80, 0x36, 0xBD,
6071 0x3E, 0x80, 0x3E, 0xBD,
6072
6073 0x33, 0xD7, 0x0B, 0xBD,
6074 0x3B, 0xD7, 0x1B, 0xBD,
6075
6076 0x46, 0x80, 0x46, 0xCF,
6077 0x57, 0x80, 0x57, 0xCF,
6078
6079 0x66, 0x33, 0x66, 0xCF,
6080 0x47, 0x3B, 0x47, 0xCF,
6081
6082 0x56, 0x33, 0x56, 0xCF,
6083 0x67, 0x3B, 0x67, 0xCF,
6084
6085 0x0B, 0x48, 0xA0, 0xE8,
6086 0x1B, 0x58, 0xA0, 0xE8,
6087
6088 0x2B, 0x68, 0xA0, 0xE8,
6089 0x0C, 0x49, 0xA0, 0xE8,
6090
6091 0x1C, 0x59, 0xA0, 0xE8,
6092 0x2C, 0x69, 0xA0, 0xE8,
6093
6094 0x0B, 0x00,
6095 0x1B, 0x00,
6096 0x2B, 0x00,
6097 0x00, 0xE0,
6098
6099 0x0C, 0x00,
6100 0x1C, 0x00,
6101 0x2C, 0x00,
6102 0x00, 0xE0,
6103
6104 0x0B, 0x65,
6105 0x1B, 0x65,
6106 0x2B, 0x65,
6107 0x00, 0xE0,
6108
6109 0x0C, 0x65,
6110 0x1C, 0x65,
6111 0x2C, 0x65,
6112 0x00, 0xE0,
6113
6114 0x0B, 0x1B, 0x60, 0xEC,
6115 0x34, 0xD7, 0x34, 0xAD,
6116
6117 0x2B, 0x80, 0x60, 0xEC,
6118 0x0C, 0x1C, 0x60, 0xEC,
6119
6120 0x3C, 0xD7, 0x3C, 0xAD,
6121 0x2C, 0x80, 0x60, 0xEC,
6122
6123 0x0B, 0x2B, 0xDE, 0xE8,
6124 0x1B, 0x80, 0xDE, 0xE8,
6125
6126 0x34, 0x80, 0x34, 0xBD,
6127 0x3C, 0x80, 0x3C, 0xBD,
6128
6129 0x33, 0xD7, 0x0B, 0xBD,
6130 0x3B, 0xD7, 0x1B, 0xBD,
6131
6132 0x48, 0x80, 0x48, 0xCF,
6133 0x59, 0x80, 0x59, 0xCF,
6134
6135 0x68, 0x33, 0x68, 0xCF,
6136 0x49, 0x3B, 0x49, 0xCF,
6137
6138 0xB5, 0xFF, 0x20, 0xEA,
6139 0x00, 0x80, 0x00, 0xE8,
6140
6141 0x58, 0x33, 0x58, 0xCF,
6142 0x69, 0x3B, 0x69, 0xCF,
6143
6144 0x74, 0xFF, 0x20, 0xEA,
6145 0x57, 0xC0, 0xBF, 0xEA,
6146
6147 0x00, 0x80, 0xA0, 0xE9,
6148 0x00, 0x00, 0xD8, 0xEC,
6149
6150};
6151
6152static unsigned char warp_g400_t2gzf[] = {
6153
6154 0x00, 0x8A, 0x98, 0xE9,
6155 0x00, 0x80, 0x00, 0xE8,
6156
6157 0x00, 0x80, 0xA0, 0xE9,
6158 0x00, 0x00, 0xD8, 0xEC,
6159
6160 0xFF, 0x80, 0xC0, 0xE9,
6161 0x00, 0x80, 0x00, 0xE8,
6162
6163 0x0A, 0x40, 0x50, 0xBF,
6164 0x2A, 0x40, 0x60, 0xBF,
6165
6166 0x32, 0x41, 0x51, 0xBF,
6167 0x3A, 0x41, 0x61, 0xBF,
6168
6169 0xC3, 0x6B,
6170 0xD3, 0x6B,
6171 0x00, 0x8A, 0x98, 0xE9,
6172
6173 0x73, 0x7B, 0xC8, 0xEC,
6174 0x96, 0xE2,
6175 0x41, 0x04,
6176
6177 0x7B, 0x43, 0xA0, 0xE8,
6178 0x73, 0x53, 0xA0, 0xE8,
6179
6180 0xAD, 0xEE, 0x23, 0x9F,
6181 0x00, 0xE0,
6182 0x51, 0x04,
6183
6184 0x90, 0xE2,
6185 0x61, 0x04,
6186 0x31, 0x46, 0xB1, 0xE8,
6187
6188 0x51, 0x41, 0xE0, 0xEC,
6189 0x39, 0x67, 0xB1, 0xE8,
6190
6191 0x00, 0x04,
6192 0x46, 0xE2,
6193 0x73, 0x63, 0xA0, 0xE8,
6194
6195 0x61, 0x41, 0xE0, 0xEC,
6196 0x31, 0x00,
6197 0x39, 0x00,
6198
6199 0x7D, 0x80, 0x15, 0xEA,
6200 0x10, 0x04,
6201 0x20, 0x04,
6202
6203 0x61, 0x51, 0xE0, 0xEC,
6204 0x2F, 0x41, 0x60, 0xEA,
6205
6206 0x31, 0x20,
6207 0x39, 0x20,
6208 0x1F, 0x42, 0xA0, 0xE8,
6209
6210 0x2A, 0x42, 0x52, 0xBF,
6211 0x0F, 0x52, 0xA0, 0xE8,
6212
6213 0x1A, 0x42, 0x62, 0xBF,
6214 0x1E, 0x51, 0x60, 0xEA,
6215
6216 0x73, 0x7B, 0xC8, 0xEC,
6217 0x0E, 0x61, 0x60, 0xEA,
6218
6219 0x32, 0x40, 0x50, 0xBD,
6220 0x22, 0x40, 0x60, 0xBD,
6221
6222 0x12, 0x41, 0x51, 0xBD,
6223 0x3A, 0x41, 0x61, 0xBD,
6224
6225 0xBF, 0x2F, 0x0E, 0xBD,
6226 0x97, 0xE2,
6227 0x7B, 0x72,
6228
6229 0x32, 0x20,
6230 0x22, 0x20,
6231 0x12, 0x20,
6232 0x3A, 0x20,
6233
6234 0x35, 0x48, 0xB1, 0xE8,
6235 0x3D, 0x59, 0xB1, 0xE8,
6236
6237 0x46, 0x31, 0x46, 0xBF,
6238 0x56, 0x31, 0x56, 0xBF,
6239
6240 0xB3, 0xE2, 0x2D, 0x9F,
6241 0x00, 0x80, 0x00, 0xE8,
6242
6243 0x66, 0x31, 0x66, 0xBF,
6244 0x47, 0x39, 0x47, 0xBF,
6245
6246 0x57, 0x39, 0x57, 0xBF,
6247 0x67, 0x39, 0x67, 0xBF,
6248
6249 0x6E, 0x80, 0x07, 0xEA,
6250 0x24, 0x41, 0x20, 0xE9,
6251
6252 0x35, 0x00,
6253 0x3D, 0x00,
6254 0x00, 0xE0,
6255 0x2D, 0x73,
6256
6257 0x33, 0x72,
6258 0x0C, 0xE3,
6259 0x8D, 0x2F, 0x1E, 0xBD,
6260
6261 0x43, 0x75, 0xF8, 0xEC,
6262 0x35, 0x20,
6263 0x3D, 0x20,
6264
6265 0x43, 0x43, 0x2D, 0xDF,
6266 0x53, 0x53, 0x2D, 0xDF,
6267
6268 0xAE, 0x1E, 0x0E, 0xBD,
6269 0x58, 0xE3,
6270 0x33, 0x66,
6271
6272 0x48, 0x35, 0x48, 0xBF,
6273 0x58, 0x35, 0x58, 0xBF,
6274
6275 0x68, 0x35, 0x68, 0xBF,
6276 0x49, 0x3D, 0x49, 0xBF,
6277
6278 0x59, 0x3D, 0x59, 0xBF,
6279 0x69, 0x3D, 0x69, 0xBF,
6280
6281 0x63, 0x63, 0x2D, 0xDF,
6282 0x4D, 0x7D, 0xF8, 0xEC,
6283
6284 0x59, 0xE3,
6285 0x00, 0xE0,
6286 0xB8, 0x38, 0x33, 0xBF,
6287
6288 0x2D, 0x73,
6289 0x30, 0x76,
6290 0x18, 0x3A, 0x41, 0xE9,
6291
6292 0x3F, 0x53, 0xA0, 0xE8,
6293 0x05, 0x80, 0x3D, 0xEA,
6294
6295 0x37, 0x43, 0xA0, 0xE8,
6296 0x3D, 0x63, 0xA0, 0xE8,
6297
6298 0x50, 0x70, 0xF8, 0xEC,
6299 0x2B, 0x50, 0x3C, 0xE9,
6300
6301 0x1F, 0x0F, 0xBC, 0xE8,
6302 0x00, 0x80, 0x00, 0xE8,
6303
6304 0x59, 0x78, 0xF8, 0xEC,
6305 0x00, 0x80, 0x00, 0xE8,
6306
6307 0x15, 0xC0, 0x20, 0xE9,
6308 0x15, 0xC0, 0x20, 0xE9,
6309
6310 0x15, 0xC0, 0x20, 0xE9,
6311 0x15, 0xC0, 0x20, 0xE9,
6312
6313 0x1E, 0x12, 0x41, 0xE9,
6314 0x1A, 0x22, 0x41, 0xE9,
6315
6316 0x46, 0x37, 0x46, 0xDF,
6317 0x56, 0x3F, 0x56, 0xDF,
6318
6319 0x2B, 0x40, 0x3D, 0xE9,
6320 0x66, 0x3D, 0x66, 0xDF,
6321
6322 0x1D, 0x32, 0x41, 0xE9,
6323 0x67, 0x3D, 0x67, 0xDF,
6324
6325 0x47, 0x37, 0x47, 0xDF,
6326 0x57, 0x3F, 0x57, 0xDF,
6327
6328 0x2A, 0x40, 0x20, 0xE9,
6329 0x59, 0x3F, 0x59, 0xDF,
6330
6331 0x16, 0x30, 0x20, 0xE9,
6332 0x69, 0x3D, 0x69, 0xDF,
6333
6334 0x48, 0x37, 0x48, 0xDF,
6335 0x58, 0x3F, 0x58, 0xDF,
6336
6337 0x12, 0x12, 0x2D, 0xDF,
6338 0x22, 0x22, 0x2D, 0xDF,
6339
6340 0x32, 0x32, 0x2D, 0xDF,
6341 0x3A, 0x3A, 0x2D, 0xDF,
6342
6343 0x68, 0x3D, 0x68, 0xDF,
6344 0x49, 0x37, 0x49, 0xDF,
6345
6346 0x3D, 0xCF, 0x74, 0xC0,
6347 0x37, 0xCF, 0x74, 0xC4,
6348
6349 0x39, 0xE5, 0x2C, 0x9F,
6350 0x34, 0x80, 0x20, 0xE9,
6351
6352 0x31, 0x53, 0x2F, 0x9F,
6353 0x00, 0x80, 0x00, 0xE8,
6354
6355 0x88, 0x73, 0x5E, 0xE9,
6356 0x00, 0x80, 0x00, 0xE8,
6357
6358 0x0F, 0xCF, 0x75, 0xC6,
6359 0x3C, 0x3D, 0x20, 0xE9,
6360
6361 0x0A, 0x44, 0x54, 0xB0,
6362 0x02, 0x44, 0x64, 0xB0,
6363
6364 0x2A, 0x44, 0x54, 0xB2,
6365 0x1A, 0x44, 0x64, 0xB2,
6366
6367 0x28, 0x80, 0x3A, 0xEA,
6368 0x0A, 0x20,
6369 0x02, 0x20,
6370
6371 0x3D, 0xCF, 0x74, 0xC2,
6372 0x2A, 0x20,
6373 0x1A, 0x20,
6374
6375 0x30, 0x50, 0x2E, 0x9F,
6376 0x32, 0x31, 0x5F, 0xE9,
6377
6378 0x38, 0x21, 0x2C, 0x9F,
6379 0x33, 0x39, 0x5F, 0xE9,
6380
6381 0x31, 0x53, 0x2F, 0x9F,
6382 0x31, 0x0F, 0x20, 0xE9,
6383
6384 0x0A, 0x44, 0x54, 0xB4,
6385 0x02, 0x44, 0x64, 0xB4,
6386
6387 0x2A, 0x45, 0x55, 0xB6,
6388 0x1A, 0x45, 0x65, 0xB6,
6389
6390 0x39, 0xE5, 0x2C, 0x9F,
6391 0x38, 0x3D, 0x20, 0xE9,
6392
6393 0x0A, 0x20,
6394 0x02, 0x20,
6395 0x2A, 0x20,
6396 0x1A, 0x20,
6397
6398 0x0A, 0x47, 0x57, 0xBF,
6399 0x02, 0x47, 0x67, 0xBF,
6400
6401 0x30, 0x50, 0x2E, 0x9F,
6402 0x3E, 0x30, 0x4F, 0xE9,
6403
6404 0x38, 0x21, 0x2C, 0x9F,
6405 0x3F, 0x38, 0x4F, 0xE9,
6406
6407 0x2A, 0x46, 0x56, 0xBF,
6408 0x1A, 0x46, 0x66, 0xBF,
6409
6410 0x31, 0x53, 0x2F, 0x9F,
6411 0x3A, 0x31, 0x4F, 0xE9,
6412
6413 0x39, 0xE5, 0x2C, 0x9F,
6414 0x3B, 0x39, 0x4F, 0xE9,
6415
6416 0x31, 0x53, 0x2F, 0x9F,
6417 0x36, 0x30, 0x4F, 0xE9,
6418
6419 0x39, 0xE5, 0x2C, 0x9F,
6420 0x37, 0x38, 0x4F, 0xE9,
6421
6422 0x2A, 0x43, 0x53, 0xBF,
6423 0x1A, 0x43, 0x63, 0xBF,
6424
6425 0x30, 0x50, 0x2E, 0x9F,
6426 0x35, 0x31, 0x4F, 0xE9,
6427
6428 0x38, 0x21, 0x2C, 0x9F,
6429 0x39, 0x39, 0x4F, 0xE9,
6430
6431 0x0A, 0x48, 0x58, 0xBF,
6432 0x02, 0x48, 0x68, 0xBF,
6433
6434 0x31, 0x53, 0x2F, 0x9F,
6435 0x80, 0x31, 0x57, 0xE9,
6436
6437 0x39, 0xE5, 0x2C, 0x9F,
6438 0x81, 0x39, 0x57, 0xE9,
6439
6440 0x2A, 0x49, 0x59, 0xBF,
6441 0x1A, 0x49, 0x69, 0xBF,
6442
6443 0x30, 0x50, 0x2E, 0x9F,
6444 0x82, 0x30, 0x57, 0xE9,
6445
6446 0x38, 0x21, 0x2C, 0x9F,
6447 0x83, 0x38, 0x57, 0xE9,
6448
6449 0x31, 0x53, 0x2F, 0x9F,
6450 0x84, 0x31, 0x5E, 0xE9,
6451
6452 0x39, 0xE5, 0x2C, 0x9F,
6453 0x85, 0x39, 0x5E, 0xE9,
6454
6455 0x86, 0x76, 0x57, 0xE9,
6456 0x8A, 0x36, 0x20, 0xE9,
6457
6458 0x87, 0x77, 0x57, 0xE9,
6459 0x8B, 0x3E, 0xBF, 0xEA,
6460
6461 0x80, 0x30, 0x57, 0xE9,
6462 0x81, 0x38, 0x57, 0xE9,
6463
6464 0x82, 0x31, 0x57, 0xE9,
6465 0x86, 0x78, 0x57, 0xE9,
6466
6467 0x83, 0x39, 0x57, 0xE9,
6468 0x87, 0x79, 0x57, 0xE9,
6469
6470 0x30, 0x1F, 0x5F, 0xE9,
6471 0x8A, 0x34, 0x20, 0xE9,
6472
6473 0x8B, 0x3C, 0x20, 0xE9,
6474 0x37, 0x50, 0x60, 0xBD,
6475
6476 0x57, 0x0D, 0x20, 0xE9,
6477 0x35, 0x51, 0x61, 0xBD,
6478
6479 0x2B, 0x50, 0x20, 0xE9,
6480 0x1D, 0x37, 0xE1, 0xEA,
6481
6482 0x1E, 0x35, 0xE1, 0xEA,
6483 0x00, 0xE0,
6484 0x0E, 0x77,
6485
6486 0x24, 0x51, 0x20, 0xE9,
6487 0x9A, 0xFF, 0x20, 0xEA,
6488
6489 0x16, 0x0E, 0x20, 0xE9,
6490 0x57, 0x2E, 0xBF, 0xEA,
6491
6492 0x0B, 0x46, 0xA0, 0xE8,
6493 0x1B, 0x56, 0xA0, 0xE8,
6494
6495 0x2B, 0x66, 0xA0, 0xE8,
6496 0x0C, 0x47, 0xA0, 0xE8,
6497
6498 0x1C, 0x57, 0xA0, 0xE8,
6499 0x2C, 0x67, 0xA0, 0xE8,
6500
6501 0x0B, 0x00,
6502 0x1B, 0x00,
6503 0x2B, 0x00,
6504 0x00, 0xE0,
6505
6506 0x0C, 0x00,
6507 0x1C, 0x00,
6508 0x2C, 0x00,
6509 0x00, 0xE0,
6510
6511 0x0B, 0x65,
6512 0x1B, 0x65,
6513 0x2B, 0x65,
6514 0x00, 0xE0,
6515
6516 0x0C, 0x65,
6517 0x1C, 0x65,
6518 0x2C, 0x65,
6519 0x00, 0xE0,
6520
6521 0x0B, 0x1B, 0x60, 0xEC,
6522 0x36, 0xD7, 0x36, 0xAD,
6523
6524 0x2B, 0x80, 0x60, 0xEC,
6525 0x0C, 0x1C, 0x60, 0xEC,
6526
6527 0x3E, 0xD7, 0x3E, 0xAD,
6528 0x2C, 0x80, 0x60, 0xEC,
6529
6530 0x0B, 0x2B, 0xDE, 0xE8,
6531 0x1B, 0x80, 0xDE, 0xE8,
6532
6533 0x36, 0x80, 0x36, 0xBD,
6534 0x3E, 0x80, 0x3E, 0xBD,
6535
6536 0x33, 0xD7, 0x0B, 0xBD,
6537 0x3B, 0xD7, 0x1B, 0xBD,
6538
6539 0x46, 0x80, 0x46, 0xCF,
6540 0x57, 0x80, 0x57, 0xCF,
6541
6542 0x66, 0x33, 0x66, 0xCF,
6543 0x47, 0x3B, 0x47, 0xCF,
6544
6545 0x56, 0x33, 0x56, 0xCF,
6546 0x67, 0x3B, 0x67, 0xCF,
6547
6548 0x0B, 0x48, 0xA0, 0xE8,
6549 0x1B, 0x58, 0xA0, 0xE8,
6550
6551 0x2B, 0x68, 0xA0, 0xE8,
6552 0x0C, 0x49, 0xA0, 0xE8,
6553
6554 0x1C, 0x59, 0xA0, 0xE8,
6555 0x2C, 0x69, 0xA0, 0xE8,
6556
6557 0x0B, 0x00,
6558 0x1B, 0x00,
6559 0x2B, 0x00,
6560 0x00, 0xE0,
6561
6562 0x0C, 0x00,
6563 0x1C, 0x00,
6564 0x2C, 0x00,
6565 0x00, 0xE0,
6566
6567 0x0B, 0x65,
6568 0x1B, 0x65,
6569 0x2B, 0x65,
6570 0x00, 0xE0,
6571
6572 0x0C, 0x65,
6573 0x1C, 0x65,
6574 0x2C, 0x65,
6575 0x00, 0xE0,
6576
6577 0x0B, 0x1B, 0x60, 0xEC,
6578 0x34, 0xD7, 0x34, 0xAD,
6579
6580 0x2B, 0x80, 0x60, 0xEC,
6581 0x0C, 0x1C, 0x60, 0xEC,
6582
6583 0x3C, 0xD7, 0x3C, 0xAD,
6584 0x2C, 0x80, 0x60, 0xEC,
6585
6586 0x0B, 0x2B, 0xDE, 0xE8,
6587 0x1B, 0x80, 0xDE, 0xE8,
6588
6589 0x34, 0x80, 0x34, 0xBD,
6590 0x3C, 0x80, 0x3C, 0xBD,
6591
6592 0x33, 0xD7, 0x0B, 0xBD,
6593 0x3B, 0xD7, 0x1B, 0xBD,
6594
6595 0x48, 0x80, 0x48, 0xCF,
6596 0x59, 0x80, 0x59, 0xCF,
6597
6598 0x68, 0x33, 0x68, 0xCF,
6599 0x49, 0x3B, 0x49, 0xCF,
6600
6601 0xBB, 0xFF, 0x20, 0xEA,
6602 0x00, 0x80, 0x00, 0xE8,
6603
6604 0x58, 0x33, 0x58, 0xCF,
6605 0x69, 0x3B, 0x69, 0xCF,
6606
6607 0x78, 0xFF, 0x20, 0xEA,
6608 0x57, 0xC0, 0xBF, 0xEA,
6609
6610 0x00, 0x80, 0xA0, 0xE9,
6611 0x00, 0x00, 0xD8, 0xEC,
6612
6613};
6614
6615static unsigned char warp_g400_t2gzs[] = {
6616
6617 0x00, 0x8A, 0x98, 0xE9,
6618 0x00, 0x80, 0x00, 0xE8,
6619
6620 0x00, 0x80, 0xA0, 0xE9,
6621 0x00, 0x00, 0xD8, 0xEC,
6622
6623 0xFF, 0x80, 0xC0, 0xE9,
6624 0x00, 0x80, 0x00, 0xE8,
6625
6626 0x0A, 0x40, 0x50, 0xBF,
6627 0x2A, 0x40, 0x60, 0xBF,
6628
6629 0x32, 0x41, 0x51, 0xBF,
6630 0x3A, 0x41, 0x61, 0xBF,
6631
6632 0xC3, 0x6B,
6633 0xD3, 0x6B,
6634 0x00, 0x8A, 0x98, 0xE9,
6635
6636 0x73, 0x7B, 0xC8, 0xEC,
6637 0x96, 0xE2,
6638 0x41, 0x04,
6639
6640 0x7B, 0x43, 0xA0, 0xE8,
6641 0x73, 0x53, 0xA0, 0xE8,
6642
6643 0xAD, 0xEE, 0x23, 0x9F,
6644 0x00, 0xE0,
6645 0x51, 0x04,
6646
6647 0x90, 0xE2,
6648 0x61, 0x04,
6649 0x31, 0x46, 0xB1, 0xE8,
6650
6651 0x51, 0x41, 0xE0, 0xEC,
6652 0x39, 0x67, 0xB1, 0xE8,
6653
6654 0x00, 0x04,
6655 0x46, 0xE2,
6656 0x73, 0x63, 0xA0, 0xE8,
6657
6658 0x61, 0x41, 0xE0, 0xEC,
6659 0x31, 0x00,
6660 0x39, 0x00,
6661
6662 0x85, 0x80, 0x15, 0xEA,
6663 0x10, 0x04,
6664 0x20, 0x04,
6665
6666 0x61, 0x51, 0xE0, 0xEC,
6667 0x2F, 0x41, 0x60, 0xEA,
6668
6669 0x31, 0x20,
6670 0x39, 0x20,
6671 0x1F, 0x42, 0xA0, 0xE8,
6672
6673 0x2A, 0x42, 0x52, 0xBF,
6674 0x0F, 0x52, 0xA0, 0xE8,
6675
6676 0x1A, 0x42, 0x62, 0xBF,
6677 0x1E, 0x51, 0x60, 0xEA,
6678
6679 0x73, 0x7B, 0xC8, 0xEC,
6680 0x0E, 0x61, 0x60, 0xEA,
6681
6682 0x32, 0x40, 0x50, 0xBD,
6683 0x22, 0x40, 0x60, 0xBD,
6684
6685 0x12, 0x41, 0x51, 0xBD,
6686 0x3A, 0x41, 0x61, 0xBD,
6687
6688 0xBF, 0x2F, 0x0E, 0xBD,
6689 0x97, 0xE2,
6690 0x7B, 0x72,
6691
6692 0x32, 0x20,
6693 0x22, 0x20,
6694 0x12, 0x20,
6695 0x3A, 0x20,
6696
6697 0x35, 0x48, 0xB1, 0xE8,
6698 0x3D, 0x59, 0xB1, 0xE8,
6699
6700 0x46, 0x31, 0x46, 0xBF,
6701 0x56, 0x31, 0x56, 0xBF,
6702
6703 0xB3, 0xE2, 0x2D, 0x9F,
6704 0x00, 0x80, 0x00, 0xE8,
6705
6706 0x66, 0x31, 0x66, 0xBF,
6707 0x47, 0x39, 0x47, 0xBF,
6708
6709 0x57, 0x39, 0x57, 0xBF,
6710 0x67, 0x39, 0x67, 0xBF,
6711
6712 0x76, 0x80, 0x07, 0xEA,
6713 0x24, 0x41, 0x20, 0xE9,
6714
6715 0x35, 0x00,
6716 0x3D, 0x00,
6717 0x00, 0xE0,
6718 0x2D, 0x73,
6719
6720 0x33, 0x72,
6721 0x0C, 0xE3,
6722 0x8D, 0x2F, 0x1E, 0xBD,
6723
6724 0x43, 0x75, 0xF8, 0xEC,
6725 0x35, 0x20,
6726 0x3D, 0x20,
6727
6728 0x43, 0x43, 0x2D, 0xDF,
6729 0x53, 0x53, 0x2D, 0xDF,
6730
6731 0xAE, 0x1E, 0x0E, 0xBD,
6732 0x58, 0xE3,
6733 0x33, 0x66,
6734
6735 0x48, 0x35, 0x48, 0xBF,
6736 0x58, 0x35, 0x58, 0xBF,
6737
6738 0x68, 0x35, 0x68, 0xBF,
6739 0x49, 0x3D, 0x49, 0xBF,
6740
6741 0x59, 0x3D, 0x59, 0xBF,
6742 0x69, 0x3D, 0x69, 0xBF,
6743
6744 0x63, 0x63, 0x2D, 0xDF,
6745 0x4D, 0x7D, 0xF8, 0xEC,
6746
6747 0x59, 0xE3,
6748 0x00, 0xE0,
6749 0xB8, 0x38, 0x33, 0xBF,
6750
6751 0x2D, 0x73,
6752 0x30, 0x76,
6753 0x18, 0x3A, 0x41, 0xE9,
6754
6755 0x3F, 0x53, 0xA0, 0xE8,
6756 0x05, 0x80, 0x3D, 0xEA,
6757
6758 0x37, 0x43, 0xA0, 0xE8,
6759 0x3D, 0x63, 0xA0, 0xE8,
6760
6761 0x50, 0x70, 0xF8, 0xEC,
6762 0x2B, 0x50, 0x3C, 0xE9,
6763
6764 0x1F, 0x0F, 0xBC, 0xE8,
6765 0x00, 0x80, 0x00, 0xE8,
6766
6767 0x59, 0x78, 0xF8, 0xEC,
6768 0x00, 0x80, 0x00, 0xE8,
6769
6770 0x15, 0xC0, 0x20, 0xE9,
6771 0x15, 0xC0, 0x20, 0xE9,
6772
6773 0x15, 0xC0, 0x20, 0xE9,
6774 0x15, 0xC0, 0x20, 0xE9,
6775
6776 0x1E, 0x12, 0x41, 0xE9,
6777 0x1A, 0x22, 0x41, 0xE9,
6778
6779 0x46, 0x37, 0x46, 0xDF,
6780 0x56, 0x3F, 0x56, 0xDF,
6781
6782 0x2B, 0x40, 0x3D, 0xE9,
6783 0x66, 0x3D, 0x66, 0xDF,
6784
6785 0x1D, 0x32, 0x41, 0xE9,
6786 0x67, 0x3D, 0x67, 0xDF,
6787
6788 0x47, 0x37, 0x47, 0xDF,
6789 0x57, 0x3F, 0x57, 0xDF,
6790
6791 0x2A, 0x40, 0x20, 0xE9,
6792 0x59, 0x3F, 0x59, 0xDF,
6793
6794 0x16, 0x30, 0x20, 0xE9,
6795 0x69, 0x3D, 0x69, 0xDF,
6796
6797 0x48, 0x37, 0x48, 0xDF,
6798 0x58, 0x3F, 0x58, 0xDF,
6799
6800 0x68, 0x3D, 0x68, 0xDF,
6801 0x49, 0x37, 0x49, 0xDF,
6802
6803 0x32, 0x32, 0x2D, 0xDF,
6804 0x22, 0x22, 0x2D, 0xDF,
6805
6806 0x12, 0x12, 0x2D, 0xDF,
6807 0x3A, 0x3A, 0x2D, 0xDF,
6808
6809 0x0F, 0xCF, 0x74, 0xC2,
6810 0x37, 0xCF, 0x74, 0xC4,
6811
6812 0x0A, 0x44, 0x54, 0xB0,
6813 0x02, 0x44, 0x64, 0xB0,
6814
6815 0x3D, 0xCF, 0x74, 0xC0,
6816 0x34, 0x37, 0x20, 0xE9,
6817
6818 0x31, 0x53, 0x2F, 0x9F,
6819 0x38, 0x0F, 0x20, 0xE9,
6820
6821 0x39, 0xE5, 0x2C, 0x9F,
6822 0x3C, 0x3D, 0x20, 0xE9,
6823
6824 0x2A, 0x44, 0x54, 0xB2,
6825 0x1A, 0x44, 0x64, 0xB2,
6826
6827 0x31, 0x80, 0x3A, 0xEA,
6828 0x0A, 0x20,
6829 0x02, 0x20,
6830
6831 0x0F, 0xCF, 0x75, 0xC0,
6832 0x2A, 0x20,
6833 0x1A, 0x20,
6834
6835 0x30, 0x50, 0x2E, 0x9F,
6836 0x32, 0x31, 0x5F, 0xE9,
6837
6838 0x38, 0x21, 0x2C, 0x9F,
6839 0x33, 0x39, 0x5F, 0xE9,
6840
6841 0x3D, 0xCF, 0x75, 0xC2,
6842 0x37, 0xCF, 0x75, 0xC4,
6843
6844 0x31, 0x53, 0x2F, 0x9F,
6845 0xA6, 0x0F, 0x20, 0xE9,
6846
6847 0x39, 0xE5, 0x2C, 0x9F,
6848 0xA3, 0x3D, 0x20, 0xE9,
6849
6850 0x2A, 0x44, 0x54, 0xB4,
6851 0x1A, 0x44, 0x64, 0xB4,
6852
6853 0x0A, 0x45, 0x55, 0xB0,
6854 0x02, 0x45, 0x65, 0xB0,
6855
6856 0x88, 0x73, 0x5E, 0xE9,
6857 0x2A, 0x20,
6858 0x1A, 0x20,
6859
6860 0xA0, 0x37, 0x20, 0xE9,
6861 0x0A, 0x20,
6862 0x02, 0x20,
6863
6864 0x31, 0x53, 0x2F, 0x9F,
6865 0x3E, 0x30, 0x4F, 0xE9,
6866
6867 0x39, 0xE5, 0x2C, 0x9F,
6868 0x3F, 0x38, 0x4F, 0xE9,
6869
6870 0x30, 0x50, 0x2E, 0x9F,
6871 0x3A, 0x31, 0x4F, 0xE9,
6872
6873 0x2A, 0x45, 0x55, 0xB2,
6874 0x1A, 0x45, 0x65, 0xB2,
6875
6876 0x0A, 0x45, 0x55, 0xB4,
6877 0x02, 0x45, 0x65, 0xB4,
6878
6879 0x38, 0x21, 0x2C, 0x9F,
6880 0x3B, 0x39, 0x4F, 0xE9,
6881
6882 0x2A, 0x20,
6883 0x1A, 0x20,
6884 0x0A, 0x20,
6885 0x02, 0x20,
6886
6887 0x2A, 0x46, 0x56, 0xBF,
6888 0x1A, 0x46, 0x66, 0xBF,
6889
6890 0x31, 0x53, 0x2F, 0x9F,
6891 0x36, 0x31, 0x4F, 0xE9,
6892
6893 0x39, 0xE5, 0x2C, 0x9F,
6894 0x37, 0x39, 0x4F, 0xE9,
6895
6896 0x30, 0x50, 0x2E, 0x9F,
6897 0xA7, 0x30, 0x4F, 0xE9,
6898
6899 0x38, 0x21, 0x2C, 0x9F,
6900 0xA8, 0x38, 0x4F, 0xE9,
6901
6902 0x0A, 0x47, 0x57, 0xBF,
6903 0x02, 0x47, 0x67, 0xBF,
6904
6905 0x31, 0x53, 0x2F, 0x9F,
6906 0xA4, 0x31, 0x4F, 0xE9,
6907
6908 0x39, 0xE5, 0x2C, 0x9F,
6909 0xA5, 0x39, 0x4F, 0xE9,
6910
6911 0x2A, 0x43, 0x53, 0xBF,
6912 0x1A, 0x43, 0x63, 0xBF,
6913
6914 0x30, 0x50, 0x2E, 0x9F,
6915 0xA1, 0x30, 0x4F, 0xE9,
6916
6917 0x38, 0x21, 0x2C, 0x9F,
6918 0xA2, 0x38, 0x4F, 0xE9,
6919
6920 0x0A, 0x48, 0x58, 0xBF,
6921 0x02, 0x48, 0x68, 0xBF,
6922
6923 0x31, 0x53, 0x2F, 0x9F,
6924 0x80, 0x31, 0x57, 0xE9,
6925
6926 0x39, 0xE5, 0x2C, 0x9F,
6927 0x81, 0x39, 0x57, 0xE9,
6928
6929 0x2A, 0x49, 0x59, 0xBF,
6930 0x1A, 0x49, 0x69, 0xBF,
6931
6932 0x30, 0x50, 0x2E, 0x9F,
6933 0x82, 0x30, 0x57, 0xE9,
6934
6935 0x38, 0x21, 0x2C, 0x9F,
6936 0x83, 0x38, 0x57, 0xE9,
6937
6938 0x31, 0x53, 0x2F, 0x9F,
6939 0x84, 0x31, 0x5E, 0xE9,
6940
6941 0x39, 0xE5, 0x2C, 0x9F,
6942 0x85, 0x39, 0x5E, 0xE9,
6943
6944 0x86, 0x76, 0x57, 0xE9,
6945 0x8A, 0x36, 0x20, 0xE9,
6946
6947 0x87, 0x77, 0x57, 0xE9,
6948 0x8B, 0x3E, 0xBF, 0xEA,
6949
6950 0x80, 0x30, 0x57, 0xE9,
6951 0x81, 0x38, 0x57, 0xE9,
6952
6953 0x82, 0x31, 0x57, 0xE9,
6954 0x86, 0x78, 0x57, 0xE9,
6955
6956 0x83, 0x39, 0x57, 0xE9,
6957 0x87, 0x79, 0x57, 0xE9,
6958
6959 0x30, 0x1F, 0x5F, 0xE9,
6960 0x8A, 0x34, 0x20, 0xE9,
6961
6962 0x8B, 0x3C, 0x20, 0xE9,
6963 0x37, 0x50, 0x60, 0xBD,
6964
6965 0x57, 0x0D, 0x20, 0xE9,
6966 0x35, 0x51, 0x61, 0xBD,
6967
6968 0x2B, 0x50, 0x20, 0xE9,
6969 0x1D, 0x37, 0xE1, 0xEA,
6970
6971 0x1E, 0x35, 0xE1, 0xEA,
6972 0x00, 0xE0,
6973 0x0E, 0x77,
6974
6975 0x24, 0x51, 0x20, 0xE9,
6976 0x92, 0xFF, 0x20, 0xEA,
6977
6978 0x16, 0x0E, 0x20, 0xE9,
6979 0x57, 0x2E, 0xBF, 0xEA,
6980
6981 0x0B, 0x46, 0xA0, 0xE8,
6982 0x1B, 0x56, 0xA0, 0xE8,
6983
6984 0x2B, 0x66, 0xA0, 0xE8,
6985 0x0C, 0x47, 0xA0, 0xE8,
6986
6987 0x1C, 0x57, 0xA0, 0xE8,
6988 0x2C, 0x67, 0xA0, 0xE8,
6989
6990 0x0B, 0x00,
6991 0x1B, 0x00,
6992 0x2B, 0x00,
6993 0x00, 0xE0,
6994
6995 0x0C, 0x00,
6996 0x1C, 0x00,
6997 0x2C, 0x00,
6998 0x00, 0xE0,
6999
7000 0x0B, 0x65,
7001 0x1B, 0x65,
7002 0x2B, 0x65,
7003 0x00, 0xE0,
7004
7005 0x0C, 0x65,
7006 0x1C, 0x65,
7007 0x2C, 0x65,
7008 0x00, 0xE0,
7009
7010 0x0B, 0x1B, 0x60, 0xEC,
7011 0x36, 0xD7, 0x36, 0xAD,
7012
7013 0x2B, 0x80, 0x60, 0xEC,
7014 0x0C, 0x1C, 0x60, 0xEC,
7015
7016 0x3E, 0xD7, 0x3E, 0xAD,
7017 0x2C, 0x80, 0x60, 0xEC,
7018
7019 0x0B, 0x2B, 0xDE, 0xE8,
7020 0x1B, 0x80, 0xDE, 0xE8,
7021
7022 0x36, 0x80, 0x36, 0xBD,
7023 0x3E, 0x80, 0x3E, 0xBD,
7024
7025 0x33, 0xD7, 0x0B, 0xBD,
7026 0x3B, 0xD7, 0x1B, 0xBD,
7027
7028 0x46, 0x80, 0x46, 0xCF,
7029 0x57, 0x80, 0x57, 0xCF,
7030
7031 0x66, 0x33, 0x66, 0xCF,
7032 0x47, 0x3B, 0x47, 0xCF,
7033
7034 0x56, 0x33, 0x56, 0xCF,
7035 0x67, 0x3B, 0x67, 0xCF,
7036
7037 0x0B, 0x48, 0xA0, 0xE8,
7038 0x1B, 0x58, 0xA0, 0xE8,
7039
7040 0x2B, 0x68, 0xA0, 0xE8,
7041 0x0C, 0x49, 0xA0, 0xE8,
7042
7043 0x1C, 0x59, 0xA0, 0xE8,
7044 0x2C, 0x69, 0xA0, 0xE8,
7045
7046 0x0B, 0x00,
7047 0x1B, 0x00,
7048 0x2B, 0x00,
7049 0x00, 0xE0,
7050
7051 0x0C, 0x00,
7052 0x1C, 0x00,
7053 0x2C, 0x00,
7054 0x00, 0xE0,
7055
7056 0x0B, 0x65,
7057 0x1B, 0x65,
7058 0x2B, 0x65,
7059 0x00, 0xE0,
7060
7061 0x0C, 0x65,
7062 0x1C, 0x65,
7063 0x2C, 0x65,
7064 0x00, 0xE0,
7065
7066 0x0B, 0x1B, 0x60, 0xEC,
7067 0x34, 0xD7, 0x34, 0xAD,
7068
7069 0x2B, 0x80, 0x60, 0xEC,
7070 0x0C, 0x1C, 0x60, 0xEC,
7071
7072 0x3C, 0xD7, 0x3C, 0xAD,
7073 0x2C, 0x80, 0x60, 0xEC,
7074
7075 0x0B, 0x2B, 0xDE, 0xE8,
7076 0x1B, 0x80, 0xDE, 0xE8,
7077
7078 0x34, 0x80, 0x34, 0xBD,
7079 0x3C, 0x80, 0x3C, 0xBD,
7080
7081 0x33, 0xD7, 0x0B, 0xBD,
7082 0x3B, 0xD7, 0x1B, 0xBD,
7083
7084 0x48, 0x80, 0x48, 0xCF,
7085 0x59, 0x80, 0x59, 0xCF,
7086
7087 0x68, 0x33, 0x68, 0xCF,
7088 0x49, 0x3B, 0x49, 0xCF,
7089
7090 0xB2, 0xFF, 0x20, 0xEA,
7091 0x00, 0x80, 0x00, 0xE8,
7092
7093 0x58, 0x33, 0x58, 0xCF,
7094 0x69, 0x3B, 0x69, 0xCF,
7095
7096 0x70, 0xFF, 0x20, 0xEA,
7097 0x57, 0xC0, 0xBF, 0xEA,
7098
7099 0x00, 0x80, 0xA0, 0xE9,
7100 0x00, 0x00, 0xD8, 0xEC,
7101
7102};
7103
7104static unsigned char warp_g400_t2gzsa[] = {
7105
7106 0x00, 0x8A, 0x98, 0xE9,
7107 0x00, 0x80, 0x00, 0xE8,
7108
7109 0x00, 0x80, 0xA0, 0xE9,
7110 0x00, 0x00, 0xD8, 0xEC,
7111
7112 0xFF, 0x80, 0xC0, 0xE9,
7113 0x00, 0x80, 0x00, 0xE8,
7114
7115 0x0A, 0x40, 0x50, 0xBF,
7116 0x2A, 0x40, 0x60, 0xBF,
7117
7118 0x32, 0x41, 0x51, 0xBF,
7119 0x3A, 0x41, 0x61, 0xBF,
7120
7121 0xC3, 0x6B,
7122 0xD3, 0x6B,
7123 0x00, 0x8A, 0x98, 0xE9,
7124
7125 0x73, 0x7B, 0xC8, 0xEC,
7126 0x96, 0xE2,
7127 0x41, 0x04,
7128
7129 0x7B, 0x43, 0xA0, 0xE8,
7130 0x73, 0x53, 0xA0, 0xE8,
7131
7132 0xAD, 0xEE, 0x23, 0x9F,
7133 0x00, 0xE0,
7134 0x51, 0x04,
7135
7136 0x90, 0xE2,
7137 0x61, 0x04,
7138 0x31, 0x46, 0xB1, 0xE8,
7139
7140 0x51, 0x41, 0xE0, 0xEC,
7141 0x39, 0x67, 0xB1, 0xE8,
7142
7143 0x00, 0x04,
7144 0x46, 0xE2,
7145 0x73, 0x63, 0xA0, 0xE8,
7146
7147 0x61, 0x41, 0xE0, 0xEC,
7148 0x31, 0x00,
7149 0x39, 0x00,
7150
7151 0x8A, 0x80, 0x15, 0xEA,
7152 0x10, 0x04,
7153 0x20, 0x04,
7154
7155 0x61, 0x51, 0xE0, 0xEC,
7156 0x2F, 0x41, 0x60, 0xEA,
7157
7158 0x31, 0x20,
7159 0x39, 0x20,
7160 0x1F, 0x42, 0xA0, 0xE8,
7161
7162 0x2A, 0x42, 0x52, 0xBF,
7163 0x0F, 0x52, 0xA0, 0xE8,
7164
7165 0x1A, 0x42, 0x62, 0xBF,
7166 0x1E, 0x51, 0x60, 0xEA,
7167
7168 0x73, 0x7B, 0xC8, 0xEC,
7169 0x0E, 0x61, 0x60, 0xEA,
7170
7171 0x32, 0x40, 0x50, 0xBD,
7172 0x22, 0x40, 0x60, 0xBD,
7173
7174 0x12, 0x41, 0x51, 0xBD,
7175 0x3A, 0x41, 0x61, 0xBD,
7176
7177 0xBF, 0x2F, 0x0E, 0xBD,
7178 0x97, 0xE2,
7179 0x7B, 0x72,
7180
7181 0x32, 0x20,
7182 0x22, 0x20,
7183 0x12, 0x20,
7184 0x3A, 0x20,
7185
7186 0x35, 0x48, 0xB1, 0xE8,
7187 0x3D, 0x59, 0xB1, 0xE8,
7188
7189 0x46, 0x31, 0x46, 0xBF,
7190 0x56, 0x31, 0x56, 0xBF,
7191
7192 0xB3, 0xE2, 0x2D, 0x9F,
7193 0x00, 0x80, 0x00, 0xE8,
7194
7195 0x66, 0x31, 0x66, 0xBF,
7196 0x47, 0x39, 0x47, 0xBF,
7197
7198 0x57, 0x39, 0x57, 0xBF,
7199 0x67, 0x39, 0x67, 0xBF,
7200
7201 0x7B, 0x80, 0x07, 0xEA,
7202 0x24, 0x41, 0x20, 0xE9,
7203
7204 0x35, 0x00,
7205 0x3D, 0x00,
7206 0x00, 0xE0,
7207 0x2D, 0x73,
7208
7209 0x33, 0x72,
7210 0x0C, 0xE3,
7211 0x8D, 0x2F, 0x1E, 0xBD,
7212
7213 0x43, 0x75, 0xF8, 0xEC,
7214 0x35, 0x20,
7215 0x3D, 0x20,
7216
7217 0x43, 0x43, 0x2D, 0xDF,
7218 0x53, 0x53, 0x2D, 0xDF,
7219
7220 0xAE, 0x1E, 0x0E, 0xBD,
7221 0x58, 0xE3,
7222 0x33, 0x66,
7223
7224 0x48, 0x35, 0x48, 0xBF,
7225 0x58, 0x35, 0x58, 0xBF,
7226
7227 0x68, 0x35, 0x68, 0xBF,
7228 0x49, 0x3D, 0x49, 0xBF,
7229
7230 0x59, 0x3D, 0x59, 0xBF,
7231 0x69, 0x3D, 0x69, 0xBF,
7232
7233 0x63, 0x63, 0x2D, 0xDF,
7234 0x4D, 0x7D, 0xF8, 0xEC,
7235
7236 0x59, 0xE3,
7237 0x00, 0xE0,
7238 0xB8, 0x38, 0x33, 0xBF,
7239
7240 0x2D, 0x73,
7241 0x30, 0x76,
7242 0x18, 0x3A, 0x41, 0xE9,
7243
7244 0x3F, 0x53, 0xA0, 0xE8,
7245 0x05, 0x80, 0x3D, 0xEA,
7246
7247 0x37, 0x43, 0xA0, 0xE8,
7248 0x3D, 0x63, 0xA0, 0xE8,
7249
7250 0x50, 0x70, 0xF8, 0xEC,
7251 0x2B, 0x50, 0x3C, 0xE9,
7252
7253 0x1F, 0x0F, 0xBC, 0xE8,
7254 0x00, 0x80, 0x00, 0xE8,
7255
7256 0x59, 0x78, 0xF8, 0xEC,
7257 0x00, 0x80, 0x00, 0xE8,
7258
7259 0x15, 0xC0, 0x20, 0xE9,
7260 0x15, 0xC0, 0x20, 0xE9,
7261
7262 0x15, 0xC0, 0x20, 0xE9,
7263 0x15, 0xC0, 0x20, 0xE9,
7264
7265 0x1E, 0x12, 0x41, 0xE9,
7266 0x1A, 0x22, 0x41, 0xE9,
7267
7268 0x46, 0x37, 0x46, 0xDF,
7269 0x56, 0x3F, 0x56, 0xDF,
7270
7271 0x2B, 0x40, 0x3D, 0xE9,
7272 0x66, 0x3D, 0x66, 0xDF,
7273
7274 0x1D, 0x32, 0x41, 0xE9,
7275 0x67, 0x3D, 0x67, 0xDF,
7276
7277 0x47, 0x37, 0x47, 0xDF,
7278 0x57, 0x3F, 0x57, 0xDF,
7279
7280 0x2A, 0x40, 0x20, 0xE9,
7281 0x59, 0x3F, 0x59, 0xDF,
7282
7283 0x16, 0x30, 0x20, 0xE9,
7284 0x69, 0x3D, 0x69, 0xDF,
7285
7286 0x48, 0x37, 0x48, 0xDF,
7287 0x58, 0x3F, 0x58, 0xDF,
7288
7289 0x68, 0x3D, 0x68, 0xDF,
7290 0x49, 0x37, 0x49, 0xDF,
7291
7292 0x32, 0x32, 0x2D, 0xDF,
7293 0x22, 0x22, 0x2D, 0xDF,
7294
7295 0x12, 0x12, 0x2D, 0xDF,
7296 0x3A, 0x3A, 0x2D, 0xDF,
7297
7298 0x0F, 0xCF, 0x74, 0xC2,
7299 0x37, 0xCF, 0x74, 0xC4,
7300
7301 0x0A, 0x44, 0x54, 0xB0,
7302 0x02, 0x44, 0x64, 0xB0,
7303
7304 0x3D, 0xCF, 0x74, 0xC0,
7305 0x34, 0x37, 0x20, 0xE9,
7306
7307 0x31, 0x53, 0x2F, 0x9F,
7308 0x38, 0x0F, 0x20, 0xE9,
7309
7310 0x39, 0xE5, 0x2C, 0x9F,
7311 0x3C, 0x3D, 0x20, 0xE9,
7312
7313 0x2A, 0x44, 0x54, 0xB2,
7314 0x1A, 0x44, 0x64, 0xB2,
7315
7316 0x36, 0x80, 0x3A, 0xEA,
7317 0x0A, 0x20,
7318 0x02, 0x20,
7319
7320 0x0F, 0xCF, 0x75, 0xC0,
7321 0x2A, 0x20,
7322 0x1A, 0x20,
7323
7324 0x30, 0x50, 0x2E, 0x9F,
7325 0x32, 0x31, 0x5F, 0xE9,
7326
7327 0x38, 0x21, 0x2C, 0x9F,
7328 0x33, 0x39, 0x5F, 0xE9,
7329
7330 0x3D, 0xCF, 0x75, 0xC2,
7331 0x37, 0xCF, 0x75, 0xC4,
7332
7333 0x31, 0x53, 0x2F, 0x9F,
7334 0xA6, 0x0F, 0x20, 0xE9,
7335
7336 0x39, 0xE5, 0x2C, 0x9F,
7337 0xA3, 0x3D, 0x20, 0xE9,
7338
7339 0x2A, 0x44, 0x54, 0xB4,
7340 0x1A, 0x44, 0x64, 0xB4,
7341
7342 0x0A, 0x45, 0x55, 0xB0,
7343 0x02, 0x45, 0x65, 0xB0,
7344
7345 0x88, 0x73, 0x5E, 0xE9,
7346 0x2A, 0x20,
7347 0x1A, 0x20,
7348
7349 0xA0, 0x37, 0x20, 0xE9,
7350 0x0A, 0x20,
7351 0x02, 0x20,
7352
7353 0x31, 0x53, 0x2F, 0x9F,
7354 0x3E, 0x30, 0x4F, 0xE9,
7355
7356 0x39, 0xE5, 0x2C, 0x9F,
7357 0x3F, 0x38, 0x4F, 0xE9,
7358
7359 0x30, 0x50, 0x2E, 0x9F,
7360 0x3A, 0x31, 0x4F, 0xE9,
7361
7362 0x38, 0x21, 0x2C, 0x9F,
7363 0x3B, 0x39, 0x4F, 0xE9,
7364
7365 0x2A, 0x45, 0x55, 0xB2,
7366 0x1A, 0x45, 0x65, 0xB2,
7367
7368 0x0A, 0x45, 0x55, 0xB4,
7369 0x02, 0x45, 0x65, 0xB4,
7370
7371 0x0F, 0xCF, 0x74, 0xC6,
7372 0x2A, 0x20,
7373 0x1A, 0x20,
7374
7375 0xA7, 0x30, 0x4F, 0xE9,
7376 0x0A, 0x20,
7377 0x02, 0x20,
7378
7379 0x31, 0x53, 0x2F, 0x9F,
7380 0x9C, 0x0F, 0x20, 0xE9,
7381
7382 0x39, 0xE5, 0x2C, 0x9F,
7383 0xA8, 0x38, 0x4F, 0xE9,
7384
7385 0x2A, 0x44, 0x54, 0xB6,
7386 0x1A, 0x44, 0x64, 0xB6,
7387
7388 0x30, 0x50, 0x2E, 0x9F,
7389 0x36, 0x31, 0x4F, 0xE9,
7390
7391 0x38, 0x21, 0x2C, 0x9F,
7392 0x37, 0x39, 0x4F, 0xE9,
7393
7394 0x00, 0x80, 0x00, 0xE8,
7395 0x2A, 0x20,
7396 0x1A, 0x20,
7397
7398 0x2A, 0x46, 0x56, 0xBF,
7399 0x1A, 0x46, 0x66, 0xBF,
7400
7401 0x31, 0x53, 0x2F, 0x9F,
7402 0xA4, 0x31, 0x4F, 0xE9,
7403
7404 0x39, 0xE5, 0x2C, 0x9F,
7405 0xA5, 0x39, 0x4F, 0xE9,
7406
7407 0x0A, 0x47, 0x57, 0xBF,
7408 0x02, 0x47, 0x67, 0xBF,
7409
7410 0x31, 0x53, 0x2F, 0x9F,
7411 0xA1, 0x30, 0x4F, 0xE9,
7412
7413 0x39, 0xE5, 0x2C, 0x9F,
7414 0xA2, 0x38, 0x4F, 0xE9,
7415
7416 0x2A, 0x43, 0x53, 0xBF,
7417 0x1A, 0x43, 0x63, 0xBF,
7418
7419 0x30, 0x50, 0x2E, 0x9F,
7420 0x9D, 0x31, 0x4F, 0xE9,
7421
7422 0x38, 0x21, 0x2C, 0x9F,
7423 0x9E, 0x39, 0x4F, 0xE9,
7424
7425 0x0A, 0x48, 0x58, 0xBF,
7426 0x02, 0x48, 0x68, 0xBF,
7427
7428 0x31, 0x53, 0x2F, 0x9F,
7429 0x80, 0x31, 0x57, 0xE9,
7430
7431 0x39, 0xE5, 0x2C, 0x9F,
7432 0x81, 0x39, 0x57, 0xE9,
7433
7434 0x2A, 0x49, 0x59, 0xBF,
7435 0x1A, 0x49, 0x69, 0xBF,
7436
7437 0x30, 0x50, 0x2E, 0x9F,
7438 0x82, 0x30, 0x57, 0xE9,
7439
7440 0x38, 0x21, 0x2C, 0x9F,
7441 0x83, 0x38, 0x57, 0xE9,
7442
7443 0x31, 0x53, 0x2F, 0x9F,
7444 0x84, 0x31, 0x5E, 0xE9,
7445
7446 0x39, 0xE5, 0x2C, 0x9F,
7447 0x85, 0x39, 0x5E, 0xE9,
7448
7449 0x86, 0x76, 0x57, 0xE9,
7450 0x8A, 0x36, 0x20, 0xE9,
7451
7452 0x87, 0x77, 0x57, 0xE9,
7453 0x8B, 0x3E, 0xBF, 0xEA,
7454
7455 0x80, 0x30, 0x57, 0xE9,
7456 0x81, 0x38, 0x57, 0xE9,
7457
7458 0x82, 0x31, 0x57, 0xE9,
7459 0x86, 0x78, 0x57, 0xE9,
7460
7461 0x83, 0x39, 0x57, 0xE9,
7462 0x87, 0x79, 0x57, 0xE9,
7463
7464 0x30, 0x1F, 0x5F, 0xE9,
7465 0x8A, 0x34, 0x20, 0xE9,
7466
7467 0x8B, 0x3C, 0x20, 0xE9,
7468 0x37, 0x50, 0x60, 0xBD,
7469
7470 0x57, 0x0D, 0x20, 0xE9,
7471 0x35, 0x51, 0x61, 0xBD,
7472
7473 0x2B, 0x50, 0x20, 0xE9,
7474 0x1D, 0x37, 0xE1, 0xEA,
7475
7476 0x1E, 0x35, 0xE1, 0xEA,
7477 0x00, 0xE0,
7478 0x0E, 0x77,
7479
7480 0x24, 0x51, 0x20, 0xE9,
7481 0x8D, 0xFF, 0x20, 0xEA,
7482
7483 0x16, 0x0E, 0x20, 0xE9,
7484 0x57, 0x2E, 0xBF, 0xEA,
7485
7486 0x0B, 0x46, 0xA0, 0xE8,
7487 0x1B, 0x56, 0xA0, 0xE8,
7488
7489 0x2B, 0x66, 0xA0, 0xE8,
7490 0x0C, 0x47, 0xA0, 0xE8,
7491
7492 0x1C, 0x57, 0xA0, 0xE8,
7493 0x2C, 0x67, 0xA0, 0xE8,
7494
7495 0x0B, 0x00,
7496 0x1B, 0x00,
7497 0x2B, 0x00,
7498 0x00, 0xE0,
7499
7500 0x0C, 0x00,
7501 0x1C, 0x00,
7502 0x2C, 0x00,
7503 0x00, 0xE0,
7504
7505 0x0B, 0x65,
7506 0x1B, 0x65,
7507 0x2B, 0x65,
7508 0x00, 0xE0,
7509
7510 0x0C, 0x65,
7511 0x1C, 0x65,
7512 0x2C, 0x65,
7513 0x00, 0xE0,
7514
7515 0x0B, 0x1B, 0x60, 0xEC,
7516 0x36, 0xD7, 0x36, 0xAD,
7517
7518 0x2B, 0x80, 0x60, 0xEC,
7519 0x0C, 0x1C, 0x60, 0xEC,
7520
7521 0x3E, 0xD7, 0x3E, 0xAD,
7522 0x2C, 0x80, 0x60, 0xEC,
7523
7524 0x0B, 0x2B, 0xDE, 0xE8,
7525 0x1B, 0x80, 0xDE, 0xE8,
7526
7527 0x36, 0x80, 0x36, 0xBD,
7528 0x3E, 0x80, 0x3E, 0xBD,
7529
7530 0x33, 0xD7, 0x0B, 0xBD,
7531 0x3B, 0xD7, 0x1B, 0xBD,
7532
7533 0x46, 0x80, 0x46, 0xCF,
7534 0x57, 0x80, 0x57, 0xCF,
7535
7536 0x66, 0x33, 0x66, 0xCF,
7537 0x47, 0x3B, 0x47, 0xCF,
7538
7539 0x56, 0x33, 0x56, 0xCF,
7540 0x67, 0x3B, 0x67, 0xCF,
7541
7542 0x0B, 0x48, 0xA0, 0xE8,
7543 0x1B, 0x58, 0xA0, 0xE8,
7544
7545 0x2B, 0x68, 0xA0, 0xE8,
7546 0x0C, 0x49, 0xA0, 0xE8,
7547
7548 0x1C, 0x59, 0xA0, 0xE8,
7549 0x2C, 0x69, 0xA0, 0xE8,
7550
7551 0x0B, 0x00,
7552 0x1B, 0x00,
7553 0x2B, 0x00,
7554 0x00, 0xE0,
7555
7556 0x0C, 0x00,
7557 0x1C, 0x00,
7558 0x2C, 0x00,
7559 0x00, 0xE0,
7560
7561 0x0B, 0x65,
7562 0x1B, 0x65,
7563 0x2B, 0x65,
7564 0x00, 0xE0,
7565
7566 0x0C, 0x65,
7567 0x1C, 0x65,
7568 0x2C, 0x65,
7569 0x00, 0xE0,
7570
7571 0x0B, 0x1B, 0x60, 0xEC,
7572 0x34, 0xD7, 0x34, 0xAD,
7573
7574 0x2B, 0x80, 0x60, 0xEC,
7575 0x0C, 0x1C, 0x60, 0xEC,
7576
7577 0x3C, 0xD7, 0x3C, 0xAD,
7578 0x2C, 0x80, 0x60, 0xEC,
7579
7580 0x0B, 0x2B, 0xDE, 0xE8,
7581 0x1B, 0x80, 0xDE, 0xE8,
7582
7583 0x34, 0x80, 0x34, 0xBD,
7584 0x3C, 0x80, 0x3C, 0xBD,
7585
7586 0x33, 0xD7, 0x0B, 0xBD,
7587 0x3B, 0xD7, 0x1B, 0xBD,
7588
7589 0x48, 0x80, 0x48, 0xCF,
7590 0x59, 0x80, 0x59, 0xCF,
7591
7592 0x68, 0x33, 0x68, 0xCF,
7593 0x49, 0x3B, 0x49, 0xCF,
7594
7595 0xAD, 0xFF, 0x20, 0xEA,
7596 0x00, 0x80, 0x00, 0xE8,
7597
7598 0x58, 0x33, 0x58, 0xCF,
7599 0x69, 0x3B, 0x69, 0xCF,
7600
7601 0x6B, 0xFF, 0x20, 0xEA,
7602 0x57, 0xC0, 0xBF, 0xEA,
7603
7604 0x00, 0x80, 0xA0, 0xE9,
7605 0x00, 0x00, 0xD8, 0xEC,
7606
7607};
7608
7609static unsigned char warp_g400_t2gzsaf[] = {
7610
7611 0x00, 0x8A, 0x98, 0xE9,
7612 0x00, 0x80, 0x00, 0xE8,
7613
7614 0x00, 0x80, 0xA0, 0xE9,
7615 0x00, 0x00, 0xD8, 0xEC,
7616
7617 0xFF, 0x80, 0xC0, 0xE9,
7618 0x00, 0x80, 0x00, 0xE8,
7619
7620 0x0A, 0x40, 0x50, 0xBF,
7621 0x2A, 0x40, 0x60, 0xBF,
7622
7623 0x32, 0x41, 0x51, 0xBF,
7624 0x3A, 0x41, 0x61, 0xBF,
7625
7626 0xC3, 0x6B,
7627 0xD3, 0x6B,
7628 0x00, 0x8A, 0x98, 0xE9,
7629
7630 0x73, 0x7B, 0xC8, 0xEC,
7631 0x96, 0xE2,
7632 0x41, 0x04,
7633
7634 0x7B, 0x43, 0xA0, 0xE8,
7635 0x73, 0x53, 0xA0, 0xE8,
7636
7637 0xAD, 0xEE, 0x23, 0x9F,
7638 0x00, 0xE0,
7639 0x51, 0x04,
7640
7641 0x90, 0xE2,
7642 0x61, 0x04,
7643 0x31, 0x46, 0xB1, 0xE8,
7644
7645 0x51, 0x41, 0xE0, 0xEC,
7646 0x39, 0x67, 0xB1, 0xE8,
7647
7648 0x00, 0x04,
7649 0x46, 0xE2,
7650 0x73, 0x63, 0xA0, 0xE8,
7651
7652 0x61, 0x41, 0xE0, 0xEC,
7653 0x31, 0x00,
7654 0x39, 0x00,
7655
7656 0x8E, 0x80, 0x15, 0xEA,
7657 0x10, 0x04,
7658 0x20, 0x04,
7659
7660 0x61, 0x51, 0xE0, 0xEC,
7661 0x2F, 0x41, 0x60, 0xEA,
7662
7663 0x31, 0x20,
7664 0x39, 0x20,
7665 0x1F, 0x42, 0xA0, 0xE8,
7666
7667 0x2A, 0x42, 0x52, 0xBF,
7668 0x0F, 0x52, 0xA0, 0xE8,
7669
7670 0x1A, 0x42, 0x62, 0xBF,
7671 0x1E, 0x51, 0x60, 0xEA,
7672
7673 0x73, 0x7B, 0xC8, 0xEC,
7674 0x0E, 0x61, 0x60, 0xEA,
7675
7676 0x32, 0x40, 0x50, 0xBD,
7677 0x22, 0x40, 0x60, 0xBD,
7678
7679 0x12, 0x41, 0x51, 0xBD,
7680 0x3A, 0x41, 0x61, 0xBD,
7681
7682 0xBF, 0x2F, 0x0E, 0xBD,
7683 0x97, 0xE2,
7684 0x7B, 0x72,
7685
7686 0x32, 0x20,
7687 0x22, 0x20,
7688 0x12, 0x20,
7689 0x3A, 0x20,
7690
7691 0x35, 0x48, 0xB1, 0xE8,
7692 0x3D, 0x59, 0xB1, 0xE8,
7693
7694 0x46, 0x31, 0x46, 0xBF,
7695 0x56, 0x31, 0x56, 0xBF,
7696
7697 0xB3, 0xE2, 0x2D, 0x9F,
7698 0x00, 0x80, 0x00, 0xE8,
7699
7700 0x66, 0x31, 0x66, 0xBF,
7701 0x47, 0x39, 0x47, 0xBF,
7702
7703 0x57, 0x39, 0x57, 0xBF,
7704 0x67, 0x39, 0x67, 0xBF,
7705
7706 0x7F, 0x80, 0x07, 0xEA,
7707 0x24, 0x41, 0x20, 0xE9,
7708
7709 0x35, 0x00,
7710 0x3D, 0x00,
7711 0x00, 0xE0,
7712 0x2D, 0x73,
7713
7714 0x33, 0x72,
7715 0x0C, 0xE3,
7716 0x8D, 0x2F, 0x1E, 0xBD,
7717
7718 0x43, 0x75, 0xF8, 0xEC,
7719 0x35, 0x20,
7720 0x3D, 0x20,
7721
7722 0x43, 0x43, 0x2D, 0xDF,
7723 0x53, 0x53, 0x2D, 0xDF,
7724
7725 0xAE, 0x1E, 0x0E, 0xBD,
7726 0x58, 0xE3,
7727 0x33, 0x66,
7728
7729 0x48, 0x35, 0x48, 0xBF,
7730 0x58, 0x35, 0x58, 0xBF,
7731
7732 0x68, 0x35, 0x68, 0xBF,
7733 0x49, 0x3D, 0x49, 0xBF,
7734
7735 0x59, 0x3D, 0x59, 0xBF,
7736 0x69, 0x3D, 0x69, 0xBF,
7737
7738 0x63, 0x63, 0x2D, 0xDF,
7739 0x4D, 0x7D, 0xF8, 0xEC,
7740
7741 0x59, 0xE3,
7742 0x00, 0xE0,
7743 0xB8, 0x38, 0x33, 0xBF,
7744
7745 0x2D, 0x73,
7746 0x30, 0x76,
7747 0x18, 0x3A, 0x41, 0xE9,
7748
7749 0x3F, 0x53, 0xA0, 0xE8,
7750 0x05, 0x80, 0x3D, 0xEA,
7751
7752 0x37, 0x43, 0xA0, 0xE8,
7753 0x3D, 0x63, 0xA0, 0xE8,
7754
7755 0x50, 0x70, 0xF8, 0xEC,
7756 0x2B, 0x50, 0x3C, 0xE9,
7757
7758 0x1F, 0x0F, 0xBC, 0xE8,
7759 0x00, 0x80, 0x00, 0xE8,
7760
7761 0x59, 0x78, 0xF8, 0xEC,
7762 0x00, 0x80, 0x00, 0xE8,
7763
7764 0x15, 0xC0, 0x20, 0xE9,
7765 0x15, 0xC0, 0x20, 0xE9,
7766
7767 0x15, 0xC0, 0x20, 0xE9,
7768 0x15, 0xC0, 0x20, 0xE9,
7769
7770 0x1E, 0x12, 0x41, 0xE9,
7771 0x1A, 0x22, 0x41, 0xE9,
7772
7773 0x46, 0x37, 0x46, 0xDF,
7774 0x56, 0x3F, 0x56, 0xDF,
7775
7776 0x2B, 0x40, 0x3D, 0xE9,
7777 0x66, 0x3D, 0x66, 0xDF,
7778
7779 0x1D, 0x32, 0x41, 0xE9,
7780 0x67, 0x3D, 0x67, 0xDF,
7781
7782 0x47, 0x37, 0x47, 0xDF,
7783 0x57, 0x3F, 0x57, 0xDF,
7784
7785 0x2A, 0x40, 0x20, 0xE9,
7786 0x59, 0x3F, 0x59, 0xDF,
7787
7788 0x16, 0x30, 0x20, 0xE9,
7789 0x69, 0x3D, 0x69, 0xDF,
7790
7791 0x48, 0x37, 0x48, 0xDF,
7792 0x58, 0x3F, 0x58, 0xDF,
7793
7794 0x68, 0x3D, 0x68, 0xDF,
7795 0x49, 0x37, 0x49, 0xDF,
7796
7797 0x32, 0x32, 0x2D, 0xDF,
7798 0x22, 0x22, 0x2D, 0xDF,
7799
7800 0x12, 0x12, 0x2D, 0xDF,
7801 0x3A, 0x3A, 0x2D, 0xDF,
7802
7803 0x0F, 0xCF, 0x74, 0xC2,
7804 0x37, 0xCF, 0x74, 0xC4,
7805
7806 0x0A, 0x44, 0x54, 0xB0,
7807 0x02, 0x44, 0x64, 0xB0,
7808
7809 0x3D, 0xCF, 0x74, 0xC0,
7810 0x34, 0x37, 0x20, 0xE9,
7811
7812 0x31, 0x53, 0x2F, 0x9F,
7813 0x38, 0x0F, 0x20, 0xE9,
7814
7815 0x39, 0xE5, 0x2C, 0x9F,
7816 0x3C, 0x3D, 0x20, 0xE9,
7817
7818 0x2A, 0x44, 0x54, 0xB2,
7819 0x1A, 0x44, 0x64, 0xB2,
7820
7821 0x3A, 0x80, 0x3A, 0xEA,
7822 0x0A, 0x20,
7823 0x02, 0x20,
7824
7825 0x0F, 0xCF, 0x75, 0xC0,
7826 0x2A, 0x20,
7827 0x1A, 0x20,
7828
7829 0x30, 0x50, 0x2E, 0x9F,
7830 0x32, 0x31, 0x5F, 0xE9,
7831
7832 0x38, 0x21, 0x2C, 0x9F,
7833 0x33, 0x39, 0x5F, 0xE9,
7834
7835 0x3D, 0xCF, 0x75, 0xC2,
7836 0x37, 0xCF, 0x75, 0xC4,
7837
7838 0x31, 0x53, 0x2F, 0x9F,
7839 0xA6, 0x0F, 0x20, 0xE9,
7840
7841 0x39, 0xE5, 0x2C, 0x9F,
7842 0xA3, 0x3D, 0x20, 0xE9,
7843
7844 0x2A, 0x44, 0x54, 0xB4,
7845 0x1A, 0x44, 0x64, 0xB4,
7846
7847 0x0A, 0x45, 0x55, 0xB0,
7848 0x02, 0x45, 0x65, 0xB0,
7849
7850 0x88, 0x73, 0x5E, 0xE9,
7851 0x2A, 0x20,
7852 0x1A, 0x20,
7853
7854 0xA0, 0x37, 0x20, 0xE9,
7855 0x0A, 0x20,
7856 0x02, 0x20,
7857
7858 0x31, 0x53, 0x2F, 0x9F,
7859 0x3E, 0x30, 0x4F, 0xE9,
7860
7861 0x39, 0xE5, 0x2C, 0x9F,
7862 0x3F, 0x38, 0x4F, 0xE9,
7863
7864 0x30, 0x50, 0x2E, 0x9F,
7865 0x3A, 0x31, 0x4F, 0xE9,
7866
7867 0x38, 0x21, 0x2C, 0x9F,
7868 0x3B, 0x39, 0x4F, 0xE9,
7869
7870 0x2A, 0x45, 0x55, 0xB2,
7871 0x1A, 0x45, 0x65, 0xB2,
7872
7873 0x0A, 0x45, 0x55, 0xB4,
7874 0x02, 0x45, 0x65, 0xB4,
7875
7876 0x0F, 0xCF, 0x74, 0xC6,
7877 0x2A, 0x20,
7878 0x1A, 0x20,
7879
7880 0xA7, 0x30, 0x4F, 0xE9,
7881 0x0A, 0x20,
7882 0x02, 0x20,
7883
7884 0x31, 0x53, 0x2F, 0x9F,
7885 0x9C, 0x0F, 0x20, 0xE9,
7886
7887 0x39, 0xE5, 0x2C, 0x9F,
7888 0xA8, 0x38, 0x4F, 0xE9,
7889
7890 0x2A, 0x44, 0x54, 0xB6,
7891 0x1A, 0x44, 0x64, 0xB6,
7892
7893 0x30, 0x50, 0x2E, 0x9F,
7894 0x36, 0x31, 0x4F, 0xE9,
7895
7896 0x38, 0x21, 0x2C, 0x9F,
7897 0x37, 0x39, 0x4F, 0xE9,
7898
7899 0x0A, 0x45, 0x55, 0xB6,
7900 0x02, 0x45, 0x65, 0xB6,
7901
7902 0x3D, 0xCF, 0x75, 0xC6,
7903 0x2A, 0x20,
7904 0x1A, 0x20,
7905
7906 0x2A, 0x46, 0x56, 0xBF,
7907 0x1A, 0x46, 0x66, 0xBF,
7908
7909 0x31, 0x53, 0x2F, 0x9F,
7910 0xA4, 0x31, 0x4F, 0xE9,
7911
7912 0x39, 0xE5, 0x2C, 0x9F,
7913 0xA5, 0x39, 0x4F, 0xE9,
7914
7915 0x31, 0x3D, 0x20, 0xE9,
7916 0x0A, 0x20,
7917 0x02, 0x20,
7918
7919 0x0A, 0x47, 0x57, 0xBF,
7920 0x02, 0x47, 0x67, 0xBF,
7921
7922 0x30, 0x50, 0x2E, 0x9F,
7923 0xA1, 0x30, 0x4F, 0xE9,
7924
7925 0x38, 0x21, 0x2C, 0x9F,
7926 0xA2, 0x38, 0x4F, 0xE9,
7927
7928 0x31, 0x53, 0x2F, 0x9F,
7929 0x9D, 0x31, 0x4F, 0xE9,
7930
7931 0x39, 0xE5, 0x2C, 0x9F,
7932 0x9E, 0x39, 0x4F, 0xE9,
7933
7934 0x2A, 0x43, 0x53, 0xBF,
7935 0x1A, 0x43, 0x63, 0xBF,
7936
7937 0x30, 0x50, 0x2E, 0x9F,
7938 0x35, 0x30, 0x4F, 0xE9,
7939
7940 0x38, 0x21, 0x2C, 0x9F,
7941 0x39, 0x38, 0x4F, 0xE9,
7942
7943 0x0A, 0x48, 0x58, 0xBF,
7944 0x02, 0x48, 0x68, 0xBF,
7945
7946 0x31, 0x53, 0x2F, 0x9F,
7947 0x80, 0x31, 0x57, 0xE9,
7948
7949 0x39, 0xE5, 0x2C, 0x9F,
7950 0x81, 0x39, 0x57, 0xE9,
7951
7952 0x2A, 0x49, 0x59, 0xBF,
7953 0x1A, 0x49, 0x69, 0xBF,
7954
7955 0x30, 0x50, 0x2E, 0x9F,
7956 0x82, 0x30, 0x57, 0xE9,
7957
7958 0x38, 0x21, 0x2C, 0x9F,
7959 0x83, 0x38, 0x57, 0xE9,
7960
7961 0x31, 0x53, 0x2F, 0x9F,
7962 0x84, 0x31, 0x5E, 0xE9,
7963
7964 0x39, 0xE5, 0x2C, 0x9F,
7965 0x85, 0x39, 0x5E, 0xE9,
7966
7967 0x86, 0x76, 0x57, 0xE9,
7968 0x8A, 0x36, 0x20, 0xE9,
7969
7970 0x87, 0x77, 0x57, 0xE9,
7971 0x8B, 0x3E, 0xBF, 0xEA,
7972
7973 0x80, 0x30, 0x57, 0xE9,
7974 0x81, 0x38, 0x57, 0xE9,
7975
7976 0x82, 0x31, 0x57, 0xE9,
7977 0x86, 0x78, 0x57, 0xE9,
7978
7979 0x83, 0x39, 0x57, 0xE9,
7980 0x87, 0x79, 0x57, 0xE9,
7981
7982 0x30, 0x1F, 0x5F, 0xE9,
7983 0x8A, 0x34, 0x20, 0xE9,
7984
7985 0x8B, 0x3C, 0x20, 0xE9,
7986 0x37, 0x50, 0x60, 0xBD,
7987
7988 0x57, 0x0D, 0x20, 0xE9,
7989 0x35, 0x51, 0x61, 0xBD,
7990
7991 0x2B, 0x50, 0x20, 0xE9,
7992 0x1D, 0x37, 0xE1, 0xEA,
7993
7994 0x1E, 0x35, 0xE1, 0xEA,
7995 0x00, 0xE0,
7996 0x0E, 0x77,
7997
7998 0x24, 0x51, 0x20, 0xE9,
7999 0x89, 0xFF, 0x20, 0xEA,
8000
8001 0x16, 0x0E, 0x20, 0xE9,
8002 0x57, 0x2E, 0xBF, 0xEA,
8003
8004 0x0B, 0x46, 0xA0, 0xE8,
8005 0x1B, 0x56, 0xA0, 0xE8,
8006
8007 0x2B, 0x66, 0xA0, 0xE8,
8008 0x0C, 0x47, 0xA0, 0xE8,
8009
8010 0x1C, 0x57, 0xA0, 0xE8,
8011 0x2C, 0x67, 0xA0, 0xE8,
8012
8013 0x0B, 0x00,
8014 0x1B, 0x00,
8015 0x2B, 0x00,
8016 0x00, 0xE0,
8017
8018 0x0C, 0x00,
8019 0x1C, 0x00,
8020 0x2C, 0x00,
8021 0x00, 0xE0,
8022
8023 0x0B, 0x65,
8024 0x1B, 0x65,
8025 0x2B, 0x65,
8026 0x00, 0xE0,
8027
8028 0x0C, 0x65,
8029 0x1C, 0x65,
8030 0x2C, 0x65,
8031 0x00, 0xE0,
8032
8033 0x0B, 0x1B, 0x60, 0xEC,
8034 0x36, 0xD7, 0x36, 0xAD,
8035
8036 0x2B, 0x80, 0x60, 0xEC,
8037 0x0C, 0x1C, 0x60, 0xEC,
8038
8039 0x3E, 0xD7, 0x3E, 0xAD,
8040 0x2C, 0x80, 0x60, 0xEC,
8041
8042 0x0B, 0x2B, 0xDE, 0xE8,
8043 0x1B, 0x80, 0xDE, 0xE8,
8044
8045 0x36, 0x80, 0x36, 0xBD,
8046 0x3E, 0x80, 0x3E, 0xBD,
8047
8048 0x33, 0xD7, 0x0B, 0xBD,
8049 0x3B, 0xD7, 0x1B, 0xBD,
8050
8051 0x46, 0x80, 0x46, 0xCF,
8052 0x57, 0x80, 0x57, 0xCF,
8053
8054 0x66, 0x33, 0x66, 0xCF,
8055 0x47, 0x3B, 0x47, 0xCF,
8056
8057 0x56, 0x33, 0x56, 0xCF,
8058 0x67, 0x3B, 0x67, 0xCF,
8059
8060 0x0B, 0x48, 0xA0, 0xE8,
8061 0x1B, 0x58, 0xA0, 0xE8,
8062
8063 0x2B, 0x68, 0xA0, 0xE8,
8064 0x0C, 0x49, 0xA0, 0xE8,
8065
8066 0x1C, 0x59, 0xA0, 0xE8,
8067 0x2C, 0x69, 0xA0, 0xE8,
8068
8069 0x0B, 0x00,
8070 0x1B, 0x00,
8071 0x2B, 0x00,
8072 0x00, 0xE0,
8073
8074 0x0C, 0x00,
8075 0x1C, 0x00,
8076 0x2C, 0x00,
8077 0x00, 0xE0,
8078
8079 0x0B, 0x65,
8080 0x1B, 0x65,
8081 0x2B, 0x65,
8082 0x00, 0xE0,
8083
8084 0x0C, 0x65,
8085 0x1C, 0x65,
8086 0x2C, 0x65,
8087 0x00, 0xE0,
8088
8089 0x0B, 0x1B, 0x60, 0xEC,
8090 0x34, 0xD7, 0x34, 0xAD,
8091
8092 0x2B, 0x80, 0x60, 0xEC,
8093 0x0C, 0x1C, 0x60, 0xEC,
8094
8095 0x3C, 0xD7, 0x3C, 0xAD,
8096 0x2C, 0x80, 0x60, 0xEC,
8097
8098 0x0B, 0x2B, 0xDE, 0xE8,
8099 0x1B, 0x80, 0xDE, 0xE8,
8100
8101 0x34, 0x80, 0x34, 0xBD,
8102 0x3C, 0x80, 0x3C, 0xBD,
8103
8104 0x33, 0xD7, 0x0B, 0xBD,
8105 0x3B, 0xD7, 0x1B, 0xBD,
8106
8107 0x48, 0x80, 0x48, 0xCF,
8108 0x59, 0x80, 0x59, 0xCF,
8109
8110 0x68, 0x33, 0x68, 0xCF,
8111 0x49, 0x3B, 0x49, 0xCF,
8112
8113 0xA9, 0xFF, 0x20, 0xEA,
8114 0x00, 0x80, 0x00, 0xE8,
8115
8116 0x58, 0x33, 0x58, 0xCF,
8117 0x69, 0x3B, 0x69, 0xCF,
8118
8119 0x67, 0xFF, 0x20, 0xEA,
8120 0x57, 0xC0, 0xBF, 0xEA,
8121
8122 0x00, 0x80, 0xA0, 0xE9,
8123 0x00, 0x00, 0xD8, 0xEC,
8124
8125};
8126
8127static unsigned char warp_g400_t2gzsf[] = {
8128
8129 0x00, 0x8A, 0x98, 0xE9,
8130 0x00, 0x80, 0x00, 0xE8,
8131
8132 0x00, 0x80, 0xA0, 0xE9,
8133 0x00, 0x00, 0xD8, 0xEC,
8134
8135 0xFF, 0x80, 0xC0, 0xE9,
8136 0x00, 0x80, 0x00, 0xE8,
8137
8138 0x0A, 0x40, 0x50, 0xBF,
8139 0x2A, 0x40, 0x60, 0xBF,
8140
8141 0x32, 0x41, 0x51, 0xBF,
8142 0x3A, 0x41, 0x61, 0xBF,
8143
8144 0xC3, 0x6B,
8145 0xD3, 0x6B,
8146 0x00, 0x8A, 0x98, 0xE9,
8147
8148 0x73, 0x7B, 0xC8, 0xEC,
8149 0x96, 0xE2,
8150 0x41, 0x04,
8151
8152 0x7B, 0x43, 0xA0, 0xE8,
8153 0x73, 0x53, 0xA0, 0xE8,
8154
8155 0xAD, 0xEE, 0x23, 0x9F,
8156 0x00, 0xE0,
8157 0x51, 0x04,
8158
8159 0x90, 0xE2,
8160 0x61, 0x04,
8161 0x31, 0x46, 0xB1, 0xE8,
8162
8163 0x51, 0x41, 0xE0, 0xEC,
8164 0x39, 0x67, 0xB1, 0xE8,
8165
8166 0x00, 0x04,
8167 0x46, 0xE2,
8168 0x73, 0x63, 0xA0, 0xE8,
8169
8170 0x61, 0x41, 0xE0, 0xEC,
8171 0x31, 0x00,
8172 0x39, 0x00,
8173
8174 0x8A, 0x80, 0x15, 0xEA,
8175 0x10, 0x04,
8176 0x20, 0x04,
8177
8178 0x61, 0x51, 0xE0, 0xEC,
8179 0x2F, 0x41, 0x60, 0xEA,
8180
8181 0x31, 0x20,
8182 0x39, 0x20,
8183 0x1F, 0x42, 0xA0, 0xE8,
8184
8185 0x2A, 0x42, 0x52, 0xBF,
8186 0x0F, 0x52, 0xA0, 0xE8,
8187
8188 0x1A, 0x42, 0x62, 0xBF,
8189 0x1E, 0x51, 0x60, 0xEA,
8190
8191 0x73, 0x7B, 0xC8, 0xEC,
8192 0x0E, 0x61, 0x60, 0xEA,
8193
8194 0x32, 0x40, 0x50, 0xBD,
8195 0x22, 0x40, 0x60, 0xBD,
8196
8197 0x12, 0x41, 0x51, 0xBD,
8198 0x3A, 0x41, 0x61, 0xBD,
8199
8200 0xBF, 0x2F, 0x0E, 0xBD,
8201 0x97, 0xE2,
8202 0x7B, 0x72,
8203
8204 0x32, 0x20,
8205 0x22, 0x20,
8206 0x12, 0x20,
8207 0x3A, 0x20,
8208
8209 0x35, 0x48, 0xB1, 0xE8,
8210 0x3D, 0x59, 0xB1, 0xE8,
8211
8212 0x46, 0x31, 0x46, 0xBF,
8213 0x56, 0x31, 0x56, 0xBF,
8214
8215 0xB3, 0xE2, 0x2D, 0x9F,
8216 0x00, 0x80, 0x00, 0xE8,
8217
8218 0x66, 0x31, 0x66, 0xBF,
8219 0x47, 0x39, 0x47, 0xBF,
8220
8221 0x57, 0x39, 0x57, 0xBF,
8222 0x67, 0x39, 0x67, 0xBF,
8223
8224 0x7B, 0x80, 0x07, 0xEA,
8225 0x24, 0x41, 0x20, 0xE9,
8226
8227 0x35, 0x00,
8228 0x3D, 0x00,
8229 0x00, 0xE0,
8230 0x2D, 0x73,
8231
8232 0x33, 0x72,
8233 0x0C, 0xE3,
8234 0x8D, 0x2F, 0x1E, 0xBD,
8235
8236 0x43, 0x75, 0xF8, 0xEC,
8237 0x35, 0x20,
8238 0x3D, 0x20,
8239
8240 0x43, 0x43, 0x2D, 0xDF,
8241 0x53, 0x53, 0x2D, 0xDF,
8242
8243 0xAE, 0x1E, 0x0E, 0xBD,
8244 0x58, 0xE3,
8245 0x33, 0x66,
8246
8247 0x48, 0x35, 0x48, 0xBF,
8248 0x58, 0x35, 0x58, 0xBF,
8249
8250 0x68, 0x35, 0x68, 0xBF,
8251 0x49, 0x3D, 0x49, 0xBF,
8252
8253 0x59, 0x3D, 0x59, 0xBF,
8254 0x69, 0x3D, 0x69, 0xBF,
8255
8256 0x63, 0x63, 0x2D, 0xDF,
8257 0x4D, 0x7D, 0xF8, 0xEC,
8258
8259 0x59, 0xE3,
8260 0x00, 0xE0,
8261 0xB8, 0x38, 0x33, 0xBF,
8262
8263 0x2D, 0x73,
8264 0x30, 0x76,
8265 0x18, 0x3A, 0x41, 0xE9,
8266
8267 0x3F, 0x53, 0xA0, 0xE8,
8268 0x05, 0x80, 0x3D, 0xEA,
8269
8270 0x37, 0x43, 0xA0, 0xE8,
8271 0x3D, 0x63, 0xA0, 0xE8,
8272
8273 0x50, 0x70, 0xF8, 0xEC,
8274 0x2B, 0x50, 0x3C, 0xE9,
8275
8276 0x1F, 0x0F, 0xBC, 0xE8,
8277 0x00, 0x80, 0x00, 0xE8,
8278
8279 0x59, 0x78, 0xF8, 0xEC,
8280 0x00, 0x80, 0x00, 0xE8,
8281
8282 0x15, 0xC0, 0x20, 0xE9,
8283 0x15, 0xC0, 0x20, 0xE9,
8284
8285 0x15, 0xC0, 0x20, 0xE9,
8286 0x15, 0xC0, 0x20, 0xE9,
8287
8288 0x1E, 0x12, 0x41, 0xE9,
8289 0x1A, 0x22, 0x41, 0xE9,
8290
8291 0x46, 0x37, 0x46, 0xDF,
8292 0x56, 0x3F, 0x56, 0xDF,
8293
8294 0x2B, 0x40, 0x3D, 0xE9,
8295 0x66, 0x3D, 0x66, 0xDF,
8296
8297 0x1D, 0x32, 0x41, 0xE9,
8298 0x67, 0x3D, 0x67, 0xDF,
8299
8300 0x47, 0x37, 0x47, 0xDF,
8301 0x57, 0x3F, 0x57, 0xDF,
8302
8303 0x2A, 0x40, 0x20, 0xE9,
8304 0x59, 0x3F, 0x59, 0xDF,
8305
8306 0x16, 0x30, 0x20, 0xE9,
8307 0x69, 0x3D, 0x69, 0xDF,
8308
8309 0x48, 0x37, 0x48, 0xDF,
8310 0x58, 0x3F, 0x58, 0xDF,
8311
8312 0x68, 0x3D, 0x68, 0xDF,
8313 0x49, 0x37, 0x49, 0xDF,
8314
8315 0x32, 0x32, 0x2D, 0xDF,
8316 0x22, 0x22, 0x2D, 0xDF,
8317
8318 0x12, 0x12, 0x2D, 0xDF,
8319 0x3A, 0x3A, 0x2D, 0xDF,
8320
8321 0x0F, 0xCF, 0x74, 0xC2,
8322 0x37, 0xCF, 0x74, 0xC4,
8323
8324 0x0A, 0x44, 0x54, 0xB0,
8325 0x02, 0x44, 0x64, 0xB0,
8326
8327 0x3D, 0xCF, 0x74, 0xC0,
8328 0x34, 0x37, 0x20, 0xE9,
8329
8330 0x31, 0x53, 0x2F, 0x9F,
8331 0x38, 0x0F, 0x20, 0xE9,
8332
8333 0x39, 0xE5, 0x2C, 0x9F,
8334 0x3C, 0x3D, 0x20, 0xE9,
8335
8336 0x2A, 0x44, 0x54, 0xB2,
8337 0x1A, 0x44, 0x64, 0xB2,
8338
8339 0x36, 0x80, 0x3A, 0xEA,
8340 0x0A, 0x20,
8341 0x02, 0x20,
8342
8343 0x0F, 0xCF, 0x75, 0xC0,
8344 0x2A, 0x20,
8345 0x1A, 0x20,
8346
8347 0x30, 0x50, 0x2E, 0x9F,
8348 0x32, 0x31, 0x5F, 0xE9,
8349
8350 0x38, 0x21, 0x2C, 0x9F,
8351 0x33, 0x39, 0x5F, 0xE9,
8352
8353 0x3D, 0xCF, 0x75, 0xC2,
8354 0x37, 0xCF, 0x75, 0xC4,
8355
8356 0x31, 0x53, 0x2F, 0x9F,
8357 0xA6, 0x0F, 0x20, 0xE9,
8358
8359 0x39, 0xE5, 0x2C, 0x9F,
8360 0xA3, 0x3D, 0x20, 0xE9,
8361
8362 0x2A, 0x44, 0x54, 0xB4,
8363 0x1A, 0x44, 0x64, 0xB4,
8364
8365 0x0A, 0x45, 0x55, 0xB0,
8366 0x02, 0x45, 0x65, 0xB0,
8367
8368 0x88, 0x73, 0x5E, 0xE9,
8369 0x2A, 0x20,
8370 0x1A, 0x20,
8371
8372 0xA0, 0x37, 0x20, 0xE9,
8373 0x0A, 0x20,
8374 0x02, 0x20,
8375
8376 0x31, 0x53, 0x2F, 0x9F,
8377 0x3E, 0x30, 0x4F, 0xE9,
8378
8379 0x39, 0xE5, 0x2C, 0x9F,
8380 0x3F, 0x38, 0x4F, 0xE9,
8381
8382 0x30, 0x50, 0x2E, 0x9F,
8383 0x3A, 0x31, 0x4F, 0xE9,
8384
8385 0x38, 0x21, 0x2C, 0x9F,
8386 0x3B, 0x39, 0x4F, 0xE9,
8387
8388 0x2A, 0x45, 0x55, 0xB2,
8389 0x1A, 0x45, 0x65, 0xB2,
8390
8391 0x0A, 0x45, 0x55, 0xB4,
8392 0x02, 0x45, 0x65, 0xB4,
8393
8394 0x0F, 0xCF, 0x75, 0xC6,
8395 0x2A, 0x20,
8396 0x1A, 0x20,
8397
8398 0xA7, 0x30, 0x4F, 0xE9,
8399 0x0A, 0x20,
8400 0x02, 0x20,
8401
8402 0x31, 0x53, 0x2F, 0x9F,
8403 0x31, 0x0F, 0x20, 0xE9,
8404
8405 0x39, 0xE5, 0x2C, 0x9F,
8406 0xA8, 0x38, 0x4F, 0xE9,
8407
8408 0x2A, 0x45, 0x55, 0xB6,
8409 0x1A, 0x45, 0x65, 0xB6,
8410
8411 0x30, 0x50, 0x2E, 0x9F,
8412 0x36, 0x31, 0x4F, 0xE9,
8413
8414 0x38, 0x21, 0x2C, 0x9F,
8415 0x37, 0x39, 0x4F, 0xE9,
8416
8417 0x00, 0x80, 0x00, 0xE8,
8418 0x2A, 0x20,
8419 0x1A, 0x20,
8420
8421 0x2A, 0x46, 0x56, 0xBF,
8422 0x1A, 0x46, 0x66, 0xBF,
8423
8424 0x31, 0x53, 0x2F, 0x9F,
8425 0xA4, 0x31, 0x4F, 0xE9,
8426
8427 0x39, 0xE5, 0x2C, 0x9F,
8428 0xA5, 0x39, 0x4F, 0xE9,
8429
8430 0x0A, 0x47, 0x57, 0xBF,
8431 0x02, 0x47, 0x67, 0xBF,
8432
8433 0x31, 0x53, 0x2F, 0x9F,
8434 0xA1, 0x30, 0x4F, 0xE9,
8435
8436 0x39, 0xE5, 0x2C, 0x9F,
8437 0xA2, 0x38, 0x4F, 0xE9,
8438
8439 0x2A, 0x43, 0x53, 0xBF,
8440 0x1A, 0x43, 0x63, 0xBF,
8441
8442 0x30, 0x50, 0x2E, 0x9F,
8443 0x35, 0x31, 0x4F, 0xE9,
8444
8445 0x38, 0x21, 0x2C, 0x9F,
8446 0x39, 0x39, 0x4F, 0xE9,
8447
8448 0x0A, 0x48, 0x58, 0xBF,
8449 0x02, 0x48, 0x68, 0xBF,
8450
8451 0x31, 0x53, 0x2F, 0x9F,
8452 0x80, 0x31, 0x57, 0xE9,
8453
8454 0x39, 0xE5, 0x2C, 0x9F,
8455 0x81, 0x39, 0x57, 0xE9,
8456
8457 0x2A, 0x49, 0x59, 0xBF,
8458 0x1A, 0x49, 0x69, 0xBF,
8459
8460 0x30, 0x50, 0x2E, 0x9F,
8461 0x82, 0x30, 0x57, 0xE9,
8462
8463 0x38, 0x21, 0x2C, 0x9F,
8464 0x83, 0x38, 0x57, 0xE9,
8465
8466 0x31, 0x53, 0x2F, 0x9F,
8467 0x84, 0x31, 0x5E, 0xE9,
8468
8469 0x39, 0xE5, 0x2C, 0x9F,
8470 0x85, 0x39, 0x5E, 0xE9,
8471
8472 0x86, 0x76, 0x57, 0xE9,
8473 0x8A, 0x36, 0x20, 0xE9,
8474
8475 0x87, 0x77, 0x57, 0xE9,
8476 0x8B, 0x3E, 0xBF, 0xEA,
8477
8478 0x80, 0x30, 0x57, 0xE9,
8479 0x81, 0x38, 0x57, 0xE9,
8480
8481 0x82, 0x31, 0x57, 0xE9,
8482 0x86, 0x78, 0x57, 0xE9,
8483
8484 0x83, 0x39, 0x57, 0xE9,
8485 0x87, 0x79, 0x57, 0xE9,
8486
8487 0x30, 0x1F, 0x5F, 0xE9,
8488 0x8A, 0x34, 0x20, 0xE9,
8489
8490 0x8B, 0x3C, 0x20, 0xE9,
8491 0x37, 0x50, 0x60, 0xBD,
8492
8493 0x57, 0x0D, 0x20, 0xE9,
8494 0x35, 0x51, 0x61, 0xBD,
8495
8496 0x2B, 0x50, 0x20, 0xE9,
8497 0x1D, 0x37, 0xE1, 0xEA,
8498
8499 0x1E, 0x35, 0xE1, 0xEA,
8500 0x00, 0xE0,
8501 0x0E, 0x77,
8502
8503 0x24, 0x51, 0x20, 0xE9,
8504 0x8D, 0xFF, 0x20, 0xEA,
8505
8506 0x16, 0x0E, 0x20, 0xE9,
8507 0x57, 0x2E, 0xBF, 0xEA,
8508
8509 0x0B, 0x46, 0xA0, 0xE8,
8510 0x1B, 0x56, 0xA0, 0xE8,
8511
8512 0x2B, 0x66, 0xA0, 0xE8,
8513 0x0C, 0x47, 0xA0, 0xE8,
8514
8515 0x1C, 0x57, 0xA0, 0xE8,
8516 0x2C, 0x67, 0xA0, 0xE8,
8517
8518 0x0B, 0x00,
8519 0x1B, 0x00,
8520 0x2B, 0x00,
8521 0x00, 0xE0,
8522
8523 0x0C, 0x00,
8524 0x1C, 0x00,
8525 0x2C, 0x00,
8526 0x00, 0xE0,
8527
8528 0x0B, 0x65,
8529 0x1B, 0x65,
8530 0x2B, 0x65,
8531 0x00, 0xE0,
8532
8533 0x0C, 0x65,
8534 0x1C, 0x65,
8535 0x2C, 0x65,
8536 0x00, 0xE0,
8537
8538 0x0B, 0x1B, 0x60, 0xEC,
8539 0x36, 0xD7, 0x36, 0xAD,
8540
8541 0x2B, 0x80, 0x60, 0xEC,
8542 0x0C, 0x1C, 0x60, 0xEC,
8543
8544 0x3E, 0xD7, 0x3E, 0xAD,
8545 0x2C, 0x80, 0x60, 0xEC,
8546
8547 0x0B, 0x2B, 0xDE, 0xE8,
8548 0x1B, 0x80, 0xDE, 0xE8,
8549
8550 0x36, 0x80, 0x36, 0xBD,
8551 0x3E, 0x80, 0x3E, 0xBD,
8552
8553 0x33, 0xD7, 0x0B, 0xBD,
8554 0x3B, 0xD7, 0x1B, 0xBD,
8555
8556 0x46, 0x80, 0x46, 0xCF,
8557 0x57, 0x80, 0x57, 0xCF,
8558
8559 0x66, 0x33, 0x66, 0xCF,
8560 0x47, 0x3B, 0x47, 0xCF,
8561
8562 0x56, 0x33, 0x56, 0xCF,
8563 0x67, 0x3B, 0x67, 0xCF,
8564
8565 0x0B, 0x48, 0xA0, 0xE8,
8566 0x1B, 0x58, 0xA0, 0xE8,
8567
8568 0x2B, 0x68, 0xA0, 0xE8,
8569 0x0C, 0x49, 0xA0, 0xE8,
8570
8571 0x1C, 0x59, 0xA0, 0xE8,
8572 0x2C, 0x69, 0xA0, 0xE8,
8573
8574 0x0B, 0x00,
8575 0x1B, 0x00,
8576 0x2B, 0x00,
8577 0x00, 0xE0,
8578
8579 0x0C, 0x00,
8580 0x1C, 0x00,
8581 0x2C, 0x00,
8582 0x00, 0xE0,
8583
8584 0x0B, 0x65,
8585 0x1B, 0x65,
8586 0x2B, 0x65,
8587 0x00, 0xE0,
8588
8589 0x0C, 0x65,
8590 0x1C, 0x65,
8591 0x2C, 0x65,
8592 0x00, 0xE0,
8593
8594 0x0B, 0x1B, 0x60, 0xEC,
8595 0x34, 0xD7, 0x34, 0xAD,
8596
8597 0x2B, 0x80, 0x60, 0xEC,
8598 0x0C, 0x1C, 0x60, 0xEC,
8599
8600 0x3C, 0xD7, 0x3C, 0xAD,
8601 0x2C, 0x80, 0x60, 0xEC,
8602
8603 0x0B, 0x2B, 0xDE, 0xE8,
8604 0x1B, 0x80, 0xDE, 0xE8,
8605
8606 0x34, 0x80, 0x34, 0xBD,
8607 0x3C, 0x80, 0x3C, 0xBD,
8608
8609 0x33, 0xD7, 0x0B, 0xBD,
8610 0x3B, 0xD7, 0x1B, 0xBD,
8611
8612 0x48, 0x80, 0x48, 0xCF,
8613 0x59, 0x80, 0x59, 0xCF,
8614
8615 0x68, 0x33, 0x68, 0xCF,
8616 0x49, 0x3B, 0x49, 0xCF,
8617
8618 0xAD, 0xFF, 0x20, 0xEA,
8619 0x00, 0x80, 0x00, 0xE8,
8620
8621 0x58, 0x33, 0x58, 0xCF,
8622 0x69, 0x3B, 0x69, 0xCF,
8623
8624 0x6B, 0xFF, 0x20, 0xEA,
8625 0x57, 0xC0, 0xBF, 0xEA,
8626
8627 0x00, 0x80, 0xA0, 0xE9,
8628 0x00, 0x00, 0xD8, 0xEC,
8629
8630};
8631
8632static unsigned char warp_g400_tgz[] = {
8633
8634 0x00, 0x88, 0x98, 0xE9,
8635 0x00, 0x80, 0x00, 0xE8,
8636
8637 0x00, 0x80, 0xA0, 0xE9,
8638 0x00, 0x00, 0xD8, 0xEC,
8639
8640 0xFF, 0x80, 0xC0, 0xE9,
8641 0x00, 0x80, 0x00, 0xE8,
8642
8643 0x22, 0x40, 0x48, 0xBF,
8644 0x2A, 0x40, 0x50, 0xBF,
8645
8646 0x32, 0x41, 0x49, 0xBF,
8647 0x3A, 0x41, 0x51, 0xBF,
8648
8649 0xC3, 0x6B,
8650 0xCB, 0x6B,
8651 0x00, 0x88, 0x98, 0xE9,
8652
8653 0x73, 0x7B, 0xC8, 0xEC,
8654 0x96, 0xE2,
8655 0x41, 0x04,
8656
8657 0x7B, 0x43, 0xA0, 0xE8,
8658 0x73, 0x4B, 0xA0, 0xE8,
8659
8660 0xAD, 0xEE, 0x29, 0x9F,
8661 0x00, 0xE0,
8662 0x49, 0x04,
8663
8664 0x90, 0xE2,
8665 0x51, 0x04,
8666 0x31, 0x46, 0xB1, 0xE8,
8667
8668 0x49, 0x41, 0xC0, 0xEC,
8669 0x39, 0x57, 0xB1, 0xE8,
8670
8671 0x00, 0x04,
8672 0x46, 0xE2,
8673 0x73, 0x53, 0xA0, 0xE8,
8674
8675 0x51, 0x41, 0xC0, 0xEC,
8676 0x31, 0x00,
8677 0x39, 0x00,
8678
8679 0x58, 0x80, 0x15, 0xEA,
8680 0x08, 0x04,
8681 0x10, 0x04,
8682
8683 0x51, 0x49, 0xC0, 0xEC,
8684 0x2F, 0x41, 0x60, 0xEA,
8685
8686 0x31, 0x20,
8687 0x39, 0x20,
8688 0x1F, 0x42, 0xA0, 0xE8,
8689
8690 0x2A, 0x42, 0x4A, 0xBF,
8691 0x27, 0x4A, 0xA0, 0xE8,
8692
8693 0x1A, 0x42, 0x52, 0xBF,
8694 0x1E, 0x49, 0x60, 0xEA,
8695
8696 0x73, 0x7B, 0xC8, 0xEC,
8697 0x26, 0x51, 0x60, 0xEA,
8698
8699 0x32, 0x40, 0x48, 0xBD,
8700 0x22, 0x40, 0x50, 0xBD,
8701
8702 0x12, 0x41, 0x49, 0xBD,
8703 0x3A, 0x41, 0x51, 0xBD,
8704
8705 0xBF, 0x2F, 0x26, 0xBD,
8706 0x00, 0xE0,
8707 0x7B, 0x72,
8708
8709 0x32, 0x20,
8710 0x22, 0x20,
8711 0x12, 0x20,
8712 0x3A, 0x20,
8713
8714 0x46, 0x31, 0x46, 0xBF,
8715 0x4E, 0x31, 0x4E, 0xBF,
8716
8717 0xB3, 0xE2, 0x2D, 0x9F,
8718 0x00, 0x80, 0x00, 0xE8,
8719
8720 0x56, 0x31, 0x56, 0xBF,
8721 0x47, 0x39, 0x47, 0xBF,
8722
8723 0x4F, 0x39, 0x4F, 0xBF,
8724 0x57, 0x39, 0x57, 0xBF,
8725
8726 0x4A, 0x80, 0x07, 0xEA,
8727 0x24, 0x41, 0x20, 0xE9,
8728
8729 0x42, 0x73, 0xF8, 0xEC,
8730 0x00, 0xE0,
8731 0x2D, 0x73,
8732
8733 0x33, 0x72,
8734 0x0C, 0xE3,
8735 0xA5, 0x2F, 0x1E, 0xBD,
8736
8737 0x43, 0x43, 0x2D, 0xDF,
8738 0x4B, 0x4B, 0x2D, 0xDF,
8739
8740 0xAE, 0x1E, 0x26, 0xBD,
8741 0x58, 0xE3,
8742 0x33, 0x66,
8743
8744 0x53, 0x53, 0x2D, 0xDF,
8745 0x00, 0x80, 0x00, 0xE8,
8746
8747 0xB8, 0x38, 0x33, 0xBF,
8748 0x00, 0xE0,
8749 0x59, 0xE3,
8750
8751 0x1E, 0x12, 0x41, 0xE9,
8752 0x1A, 0x22, 0x41, 0xE9,
8753
8754 0x2B, 0x40, 0x3D, 0xE9,
8755 0x3F, 0x4B, 0xA0, 0xE8,
8756
8757 0x2D, 0x73,
8758 0x30, 0x76,
8759 0x05, 0x80, 0x3D, 0xEA,
8760
8761 0x37, 0x43, 0xA0, 0xE8,
8762 0x3D, 0x53, 0xA0, 0xE8,
8763
8764 0x48, 0x70, 0xF8, 0xEC,
8765 0x2B, 0x48, 0x3C, 0xE9,
8766
8767 0x1F, 0x27, 0xBC, 0xE8,
8768 0x00, 0x80, 0x00, 0xE8,
8769
8770 0x00, 0x80, 0x00, 0xE8,
8771 0x00, 0x80, 0x00, 0xE8,
8772
8773 0x15, 0xC0, 0x20, 0xE9,
8774 0x15, 0xC0, 0x20, 0xE9,
8775
8776 0x15, 0xC0, 0x20, 0xE9,
8777 0x15, 0xC0, 0x20, 0xE9,
8778
8779 0x18, 0x3A, 0x41, 0xE9,
8780 0x1D, 0x32, 0x41, 0xE9,
8781
8782 0x2A, 0x40, 0x20, 0xE9,
8783 0x56, 0x3D, 0x56, 0xDF,
8784
8785 0x46, 0x37, 0x46, 0xDF,
8786 0x4E, 0x3F, 0x4E, 0xDF,
8787
8788 0x16, 0x30, 0x20, 0xE9,
8789 0x4F, 0x3F, 0x4F, 0xDF,
8790
8791 0x32, 0x32, 0x2D, 0xDF,
8792 0x22, 0x22, 0x2D, 0xDF,
8793
8794 0x12, 0x12, 0x2D, 0xDF,
8795 0x3A, 0x3A, 0x2D, 0xDF,
8796
8797 0x47, 0x37, 0x47, 0xDF,
8798 0x57, 0x3D, 0x57, 0xDF,
8799
8800 0x3D, 0xCF, 0x74, 0xC0,
8801 0x37, 0xCF, 0x74, 0xC4,
8802
8803 0x31, 0x53, 0x2F, 0x9F,
8804 0x34, 0x80, 0x20, 0xE9,
8805
8806 0x39, 0xE5, 0x2C, 0x9F,
8807 0x3C, 0x3D, 0x20, 0xE9,
8808
8809 0x0A, 0x44, 0x4C, 0xB0,
8810 0x02, 0x44, 0x54, 0xB0,
8811
8812 0x2A, 0x44, 0x4C, 0xB2,
8813 0x1A, 0x44, 0x54, 0xB2,
8814
8815 0x1D, 0x80, 0x3A, 0xEA,
8816 0x0A, 0x20,
8817 0x02, 0x20,
8818
8819 0x3D, 0xCF, 0x74, 0xC2,
8820 0x2A, 0x20,
8821 0x1A, 0x20,
8822
8823 0x30, 0x50, 0x2E, 0x9F,
8824 0x32, 0x31, 0x5F, 0xE9,
8825
8826 0x38, 0x21, 0x2C, 0x9F,
8827 0x33, 0x39, 0x5F, 0xE9,
8828
8829 0x31, 0x53, 0x2F, 0x9F,
8830 0x00, 0x80, 0x00, 0xE8,
8831
8832 0x2A, 0x44, 0x4C, 0xB4,
8833 0x1A, 0x44, 0x54, 0xB4,
8834
8835 0x39, 0xE5, 0x2C, 0x9F,
8836 0x38, 0x3D, 0x20, 0xE9,
8837
8838 0x88, 0x73, 0x5E, 0xE9,
8839 0x2A, 0x20,
8840 0x1A, 0x20,
8841
8842 0x2A, 0x46, 0x4E, 0xBF,
8843 0x1A, 0x46, 0x56, 0xBF,
8844
8845 0x31, 0x53, 0x2F, 0x9F,
8846 0x3E, 0x30, 0x4F, 0xE9,
8847
8848 0x39, 0xE5, 0x2C, 0x9F,
8849 0x3F, 0x38, 0x4F, 0xE9,
8850
8851 0x0A, 0x47, 0x4F, 0xBF,
8852 0x02, 0x47, 0x57, 0xBF,
8853
8854 0x31, 0x53, 0x2F, 0x9F,
8855 0x3A, 0x31, 0x4F, 0xE9,
8856
8857 0x39, 0xE5, 0x2C, 0x9F,
8858 0x3B, 0x39, 0x4F, 0xE9,
8859
8860 0x2A, 0x43, 0x4B, 0xBF,
8861 0x1A, 0x43, 0x53, 0xBF,
8862
8863 0x30, 0x50, 0x2E, 0x9F,
8864 0x36, 0x31, 0x4F, 0xE9,
8865
8866 0x38, 0x21, 0x2C, 0x9F,
8867 0x37, 0x39, 0x4F, 0xE9,
8868
8869 0x31, 0x53, 0x2F, 0x9F,
8870 0x80, 0x31, 0x57, 0xE9,
8871
8872 0x39, 0xE5, 0x2C, 0x9F,
8873 0x81, 0x39, 0x57, 0xE9,
8874
8875 0x37, 0x48, 0x50, 0xBD,
8876 0x8A, 0x36, 0x20, 0xE9,
8877
8878 0x86, 0x76, 0x57, 0xE9,
8879 0x8B, 0x3E, 0x20, 0xE9,
8880
8881 0x82, 0x30, 0x57, 0xE9,
8882 0x87, 0x77, 0x57, 0xE9,
8883
8884 0x83, 0x38, 0x57, 0xE9,
8885 0x35, 0x49, 0x51, 0xBD,
8886
8887 0x84, 0x31, 0x5E, 0xE9,
8888 0x30, 0x1F, 0x5F, 0xE9,
8889
8890 0x85, 0x39, 0x5E, 0xE9,
8891 0x57, 0x25, 0x20, 0xE9,
8892
8893 0x2B, 0x48, 0x20, 0xE9,
8894 0x1D, 0x37, 0xE1, 0xEA,
8895
8896 0x1E, 0x35, 0xE1, 0xEA,
8897 0x00, 0xE0,
8898 0x26, 0x77,
8899
8900 0x24, 0x49, 0x20, 0xE9,
8901 0xAF, 0xFF, 0x20, 0xEA,
8902
8903 0x16, 0x26, 0x20, 0xE9,
8904 0x57, 0x2E, 0xBF, 0xEA,
8905
8906 0x1C, 0x46, 0xA0, 0xE8,
8907 0x23, 0x4E, 0xA0, 0xE8,
8908
8909 0x2B, 0x56, 0xA0, 0xE8,
8910 0x1D, 0x47, 0xA0, 0xE8,
8911
8912 0x24, 0x4F, 0xA0, 0xE8,
8913 0x2C, 0x57, 0xA0, 0xE8,
8914
8915 0x1C, 0x00,
8916 0x23, 0x00,
8917 0x2B, 0x00,
8918 0x00, 0xE0,
8919
8920 0x1D, 0x00,
8921 0x24, 0x00,
8922 0x2C, 0x00,
8923 0x00, 0xE0,
8924
8925 0x1C, 0x65,
8926 0x23, 0x65,
8927 0x2B, 0x65,
8928 0x00, 0xE0,
8929
8930 0x1D, 0x65,
8931 0x24, 0x65,
8932 0x2C, 0x65,
8933 0x00, 0xE0,
8934
8935 0x1C, 0x23, 0x60, 0xEC,
8936 0x36, 0xD7, 0x36, 0xAD,
8937
8938 0x2B, 0x80, 0x60, 0xEC,
8939 0x1D, 0x24, 0x60, 0xEC,
8940
8941 0x3E, 0xD7, 0x3E, 0xAD,
8942 0x2C, 0x80, 0x60, 0xEC,
8943
8944 0x1C, 0x2B, 0xDE, 0xE8,
8945 0x23, 0x80, 0xDE, 0xE8,
8946
8947 0x36, 0x80, 0x36, 0xBD,
8948 0x3E, 0x80, 0x3E, 0xBD,
8949
8950 0x33, 0xD7, 0x1C, 0xBD,
8951 0x3B, 0xD7, 0x23, 0xBD,
8952
8953 0x46, 0x80, 0x46, 0xCF,
8954 0x4F, 0x80, 0x4F, 0xCF,
8955
8956 0x56, 0x33, 0x56, 0xCF,
8957 0x47, 0x3B, 0x47, 0xCF,
8958
8959 0xD6, 0xFF, 0x20, 0xEA,
8960 0x00, 0x80, 0x00, 0xE8,
8961
8962 0x4E, 0x33, 0x4E, 0xCF,
8963 0x57, 0x3B, 0x57, 0xCF,
8964
8965 0x9D, 0xFF, 0x20, 0xEA,
8966 0x57, 0xC0, 0xBF, 0xEA,
8967
8968 0x00, 0x80, 0xA0, 0xE9,
8969 0x00, 0x00, 0xD8, 0xEC,
8970
8971};
8972
8973static unsigned char warp_g400_tgza[] = {
8974
8975 0x00, 0x88, 0x98, 0xE9,
8976 0x00, 0x80, 0x00, 0xE8,
8977
8978 0x00, 0x80, 0xA0, 0xE9,
8979 0x00, 0x00, 0xD8, 0xEC,
8980
8981 0xFF, 0x80, 0xC0, 0xE9,
8982 0x00, 0x80, 0x00, 0xE8,
8983
8984 0x22, 0x40, 0x48, 0xBF,
8985 0x2A, 0x40, 0x50, 0xBF,
8986
8987 0x32, 0x41, 0x49, 0xBF,
8988 0x3A, 0x41, 0x51, 0xBF,
8989
8990 0xC3, 0x6B,
8991 0xCB, 0x6B,
8992 0x00, 0x88, 0x98, 0xE9,
8993
8994 0x73, 0x7B, 0xC8, 0xEC,
8995 0x96, 0xE2,
8996 0x41, 0x04,
8997
8998 0x7B, 0x43, 0xA0, 0xE8,
8999 0x73, 0x4B, 0xA0, 0xE8,
9000
9001 0xAD, 0xEE, 0x29, 0x9F,
9002 0x00, 0xE0,
9003 0x49, 0x04,
9004
9005 0x90, 0xE2,
9006 0x51, 0x04,
9007 0x31, 0x46, 0xB1, 0xE8,
9008
9009 0x49, 0x41, 0xC0, 0xEC,
9010 0x39, 0x57, 0xB1, 0xE8,
9011
9012 0x00, 0x04,
9013 0x46, 0xE2,
9014 0x73, 0x53, 0xA0, 0xE8,
9015
9016 0x51, 0x41, 0xC0, 0xEC,
9017 0x31, 0x00,
9018 0x39, 0x00,
9019
9020 0x5C, 0x80, 0x15, 0xEA,
9021 0x08, 0x04,
9022 0x10, 0x04,
9023
9024 0x51, 0x49, 0xC0, 0xEC,
9025 0x2F, 0x41, 0x60, 0xEA,
9026
9027 0x31, 0x20,
9028 0x39, 0x20,
9029 0x1F, 0x42, 0xA0, 0xE8,
9030
9031 0x2A, 0x42, 0x4A, 0xBF,
9032 0x27, 0x4A, 0xA0, 0xE8,
9033
9034 0x1A, 0x42, 0x52, 0xBF,
9035 0x1E, 0x49, 0x60, 0xEA,
9036
9037 0x73, 0x7B, 0xC8, 0xEC,
9038 0x26, 0x51, 0x60, 0xEA,
9039
9040 0x32, 0x40, 0x48, 0xBD,
9041 0x22, 0x40, 0x50, 0xBD,
9042
9043 0x12, 0x41, 0x49, 0xBD,
9044 0x3A, 0x41, 0x51, 0xBD,
9045
9046 0xBF, 0x2F, 0x26, 0xBD,
9047 0x00, 0xE0,
9048 0x7B, 0x72,
9049
9050 0x32, 0x20,
9051 0x22, 0x20,
9052 0x12, 0x20,
9053 0x3A, 0x20,
9054
9055 0x46, 0x31, 0x46, 0xBF,
9056 0x4E, 0x31, 0x4E, 0xBF,
9057
9058 0xB3, 0xE2, 0x2D, 0x9F,
9059 0x00, 0x80, 0x00, 0xE8,
9060
9061 0x56, 0x31, 0x56, 0xBF,
9062 0x47, 0x39, 0x47, 0xBF,
9063
9064 0x4F, 0x39, 0x4F, 0xBF,
9065 0x57, 0x39, 0x57, 0xBF,
9066
9067 0x4E, 0x80, 0x07, 0xEA,
9068 0x24, 0x41, 0x20, 0xE9,
9069
9070 0x42, 0x73, 0xF8, 0xEC,
9071 0x00, 0xE0,
9072 0x2D, 0x73,
9073
9074 0x33, 0x72,
9075 0x0C, 0xE3,
9076 0xA5, 0x2F, 0x1E, 0xBD,
9077
9078 0x43, 0x43, 0x2D, 0xDF,
9079 0x4B, 0x4B, 0x2D, 0xDF,
9080
9081 0xAE, 0x1E, 0x26, 0xBD,
9082 0x58, 0xE3,
9083 0x33, 0x66,
9084
9085 0x53, 0x53, 0x2D, 0xDF,
9086 0x00, 0x80, 0x00, 0xE8,
9087
9088 0xB8, 0x38, 0x33, 0xBF,
9089 0x00, 0xE0,
9090 0x59, 0xE3,
9091
9092 0x1E, 0x12, 0x41, 0xE9,
9093 0x1A, 0x22, 0x41, 0xE9,
9094
9095 0x2B, 0x40, 0x3D, 0xE9,
9096 0x3F, 0x4B, 0xA0, 0xE8,
9097
9098 0x2D, 0x73,
9099 0x30, 0x76,
9100 0x05, 0x80, 0x3D, 0xEA,
9101
9102 0x37, 0x43, 0xA0, 0xE8,
9103 0x3D, 0x53, 0xA0, 0xE8,
9104
9105 0x48, 0x70, 0xF8, 0xEC,
9106 0x2B, 0x48, 0x3C, 0xE9,
9107
9108 0x1F, 0x27, 0xBC, 0xE8,
9109 0x00, 0x80, 0x00, 0xE8,
9110
9111 0x00, 0x80, 0x00, 0xE8,
9112 0x00, 0x80, 0x00, 0xE8,
9113
9114 0x15, 0xC0, 0x20, 0xE9,
9115 0x15, 0xC0, 0x20, 0xE9,
9116
9117 0x15, 0xC0, 0x20, 0xE9,
9118 0x15, 0xC0, 0x20, 0xE9,
9119
9120 0x18, 0x3A, 0x41, 0xE9,
9121 0x1D, 0x32, 0x41, 0xE9,
9122
9123 0x2A, 0x40, 0x20, 0xE9,
9124 0x56, 0x3D, 0x56, 0xDF,
9125
9126 0x46, 0x37, 0x46, 0xDF,
9127 0x4E, 0x3F, 0x4E, 0xDF,
9128
9129 0x16, 0x30, 0x20, 0xE9,
9130 0x4F, 0x3F, 0x4F, 0xDF,
9131
9132 0x32, 0x32, 0x2D, 0xDF,
9133 0x22, 0x22, 0x2D, 0xDF,
9134
9135 0x12, 0x12, 0x2D, 0xDF,
9136 0x3A, 0x3A, 0x2D, 0xDF,
9137
9138 0x47, 0x37, 0x47, 0xDF,
9139 0x57, 0x3D, 0x57, 0xDF,
9140
9141 0x3D, 0xCF, 0x74, 0xC0,
9142 0x37, 0xCF, 0x74, 0xC4,
9143
9144 0x31, 0x53, 0x2F, 0x9F,
9145 0x34, 0x80, 0x20, 0xE9,
9146
9147 0x39, 0xE5, 0x2C, 0x9F,
9148 0x3C, 0x3D, 0x20, 0xE9,
9149
9150 0x27, 0xCF, 0x74, 0xC6,
9151 0x3D, 0xCF, 0x74, 0xC2,
9152
9153 0x0A, 0x44, 0x4C, 0xB0,
9154 0x02, 0x44, 0x54, 0xB0,
9155
9156 0x2A, 0x44, 0x4C, 0xB2,
9157 0x1A, 0x44, 0x54, 0xB2,
9158
9159 0x20, 0x80, 0x3A, 0xEA,
9160 0x0A, 0x20,
9161 0x02, 0x20,
9162
9163 0x88, 0x73, 0x5E, 0xE9,
9164 0x2A, 0x20,
9165 0x1A, 0x20,
9166
9167 0x30, 0x50, 0x2E, 0x9F,
9168 0x32, 0x31, 0x5F, 0xE9,
9169
9170 0x38, 0x21, 0x2C, 0x9F,
9171 0x33, 0x39, 0x5F, 0xE9,
9172
9173 0x31, 0x53, 0x2F, 0x9F,
9174 0x9C, 0x27, 0x20, 0xE9,
9175
9176 0x0A, 0x44, 0x4C, 0xB4,
9177 0x02, 0x44, 0x54, 0xB4,
9178
9179 0x2A, 0x44, 0x4C, 0xB6,
9180 0x1A, 0x44, 0x54, 0xB6,
9181
9182 0x39, 0xE5, 0x2C, 0x9F,
9183 0x38, 0x3D, 0x20, 0xE9,
9184
9185 0x0A, 0x20,
9186 0x02, 0x20,
9187 0x2A, 0x20,
9188 0x1A, 0x20,
9189
9190 0x0A, 0x47, 0x4F, 0xBF,
9191 0x02, 0x47, 0x57, 0xBF,
9192
9193 0x30, 0x50, 0x2E, 0x9F,
9194 0x3E, 0x30, 0x4F, 0xE9,
9195
9196 0x38, 0x21, 0x2C, 0x9F,
9197 0x3F, 0x38, 0x4F, 0xE9,
9198
9199 0x2A, 0x46, 0x4E, 0xBF,
9200 0x1A, 0x46, 0x56, 0xBF,
9201
9202 0x31, 0x53, 0x2F, 0x9F,
9203 0x3A, 0x31, 0x4F, 0xE9,
9204
9205 0x39, 0xE5, 0x2C, 0x9F,
9206 0x3B, 0x39, 0x4F, 0xE9,
9207
9208 0x31, 0x53, 0x2F, 0x9F,
9209 0x36, 0x30, 0x4F, 0xE9,
9210
9211 0x39, 0xE5, 0x2C, 0x9F,
9212 0x37, 0x38, 0x4F, 0xE9,
9213
9214 0x2A, 0x43, 0x4B, 0xBF,
9215 0x1A, 0x43, 0x53, 0xBF,
9216
9217 0x30, 0x50, 0x2E, 0x9F,
9218 0x9D, 0x31, 0x4F, 0xE9,
9219
9220 0x38, 0x21, 0x2C, 0x9F,
9221 0x9E, 0x39, 0x4F, 0xE9,
9222
9223 0x31, 0x53, 0x2F, 0x9F,
9224 0x80, 0x31, 0x57, 0xE9,
9225
9226 0x39, 0xE5, 0x2C, 0x9F,
9227 0x81, 0x39, 0x57, 0xE9,
9228
9229 0x37, 0x48, 0x50, 0xBD,
9230 0x8A, 0x36, 0x20, 0xE9,
9231
9232 0x86, 0x76, 0x57, 0xE9,
9233 0x8B, 0x3E, 0x20, 0xE9,
9234
9235 0x82, 0x30, 0x57, 0xE9,
9236 0x87, 0x77, 0x57, 0xE9,
9237
9238 0x83, 0x38, 0x57, 0xE9,
9239 0x35, 0x49, 0x51, 0xBD,
9240
9241 0x84, 0x31, 0x5E, 0xE9,
9242 0x30, 0x1F, 0x5F, 0xE9,
9243
9244 0x85, 0x39, 0x5E, 0xE9,
9245 0x57, 0x25, 0x20, 0xE9,
9246
9247 0x2B, 0x48, 0x20, 0xE9,
9248 0x1D, 0x37, 0xE1, 0xEA,
9249
9250 0x1E, 0x35, 0xE1, 0xEA,
9251 0x00, 0xE0,
9252 0x26, 0x77,
9253
9254 0x24, 0x49, 0x20, 0xE9,
9255 0xAB, 0xFF, 0x20, 0xEA,
9256
9257 0x16, 0x26, 0x20, 0xE9,
9258 0x57, 0x2E, 0xBF, 0xEA,
9259
9260 0x1C, 0x46, 0xA0, 0xE8,
9261 0x23, 0x4E, 0xA0, 0xE8,
9262
9263 0x2B, 0x56, 0xA0, 0xE8,
9264 0x1D, 0x47, 0xA0, 0xE8,
9265
9266 0x24, 0x4F, 0xA0, 0xE8,
9267 0x2C, 0x57, 0xA0, 0xE8,
9268
9269 0x1C, 0x00,
9270 0x23, 0x00,
9271 0x2B, 0x00,
9272 0x00, 0xE0,
9273
9274 0x1D, 0x00,
9275 0x24, 0x00,
9276 0x2C, 0x00,
9277 0x00, 0xE0,
9278
9279 0x1C, 0x65,
9280 0x23, 0x65,
9281 0x2B, 0x65,
9282 0x00, 0xE0,
9283
9284 0x1D, 0x65,
9285 0x24, 0x65,
9286 0x2C, 0x65,
9287 0x00, 0xE0,
9288
9289 0x1C, 0x23, 0x60, 0xEC,
9290 0x36, 0xD7, 0x36, 0xAD,
9291
9292 0x2B, 0x80, 0x60, 0xEC,
9293 0x1D, 0x24, 0x60, 0xEC,
9294
9295 0x3E, 0xD7, 0x3E, 0xAD,
9296 0x2C, 0x80, 0x60, 0xEC,
9297
9298 0x1C, 0x2B, 0xDE, 0xE8,
9299 0x23, 0x80, 0xDE, 0xE8,
9300
9301 0x36, 0x80, 0x36, 0xBD,
9302 0x3E, 0x80, 0x3E, 0xBD,
9303
9304 0x33, 0xD7, 0x1C, 0xBD,
9305 0x3B, 0xD7, 0x23, 0xBD,
9306
9307 0x46, 0x80, 0x46, 0xCF,
9308 0x4F, 0x80, 0x4F, 0xCF,
9309
9310 0x56, 0x33, 0x56, 0xCF,
9311 0x47, 0x3B, 0x47, 0xCF,
9312
9313 0xD3, 0xFF, 0x20, 0xEA,
9314 0x00, 0x80, 0x00, 0xE8,
9315
9316 0x4E, 0x33, 0x4E, 0xCF,
9317 0x57, 0x3B, 0x57, 0xCF,
9318
9319 0x99, 0xFF, 0x20, 0xEA,
9320 0x57, 0xC0, 0xBF, 0xEA,
9321
9322 0x00, 0x80, 0xA0, 0xE9,
9323 0x00, 0x00, 0xD8, 0xEC,
9324
9325};
9326
9327static unsigned char warp_g400_tgzaf[] = {
9328
9329 0x00, 0x88, 0x98, 0xE9,
9330 0x00, 0x80, 0x00, 0xE8,
9331
9332 0x00, 0x80, 0xA0, 0xE9,
9333 0x00, 0x00, 0xD8, 0xEC,
9334
9335 0xFF, 0x80, 0xC0, 0xE9,
9336 0x00, 0x80, 0x00, 0xE8,
9337
9338 0x22, 0x40, 0x48, 0xBF,
9339 0x2A, 0x40, 0x50, 0xBF,
9340
9341 0x32, 0x41, 0x49, 0xBF,
9342 0x3A, 0x41, 0x51, 0xBF,
9343
9344 0xC3, 0x6B,
9345 0xCB, 0x6B,
9346 0x00, 0x88, 0x98, 0xE9,
9347
9348 0x73, 0x7B, 0xC8, 0xEC,
9349 0x96, 0xE2,
9350 0x41, 0x04,
9351
9352 0x7B, 0x43, 0xA0, 0xE8,
9353 0x73, 0x4B, 0xA0, 0xE8,
9354
9355 0xAD, 0xEE, 0x29, 0x9F,
9356 0x00, 0xE0,
9357 0x49, 0x04,
9358
9359 0x90, 0xE2,
9360 0x51, 0x04,
9361 0x31, 0x46, 0xB1, 0xE8,
9362
9363 0x49, 0x41, 0xC0, 0xEC,
9364 0x39, 0x57, 0xB1, 0xE8,
9365
9366 0x00, 0x04,
9367 0x46, 0xE2,
9368 0x73, 0x53, 0xA0, 0xE8,
9369
9370 0x51, 0x41, 0xC0, 0xEC,
9371 0x31, 0x00,
9372 0x39, 0x00,
9373
9374 0x61, 0x80, 0x15, 0xEA,
9375 0x08, 0x04,
9376 0x10, 0x04,
9377
9378 0x51, 0x49, 0xC0, 0xEC,
9379 0x2F, 0x41, 0x60, 0xEA,
9380
9381 0x31, 0x20,
9382 0x39, 0x20,
9383 0x1F, 0x42, 0xA0, 0xE8,
9384
9385 0x2A, 0x42, 0x4A, 0xBF,
9386 0x27, 0x4A, 0xA0, 0xE8,
9387
9388 0x1A, 0x42, 0x52, 0xBF,
9389 0x1E, 0x49, 0x60, 0xEA,
9390
9391 0x73, 0x7B, 0xC8, 0xEC,
9392 0x26, 0x51, 0x60, 0xEA,
9393
9394 0x32, 0x40, 0x48, 0xBD,
9395 0x22, 0x40, 0x50, 0xBD,
9396
9397 0x12, 0x41, 0x49, 0xBD,
9398 0x3A, 0x41, 0x51, 0xBD,
9399
9400 0xBF, 0x2F, 0x26, 0xBD,
9401 0x00, 0xE0,
9402 0x7B, 0x72,
9403
9404 0x32, 0x20,
9405 0x22, 0x20,
9406 0x12, 0x20,
9407 0x3A, 0x20,
9408
9409 0x46, 0x31, 0x46, 0xBF,
9410 0x4E, 0x31, 0x4E, 0xBF,
9411
9412 0xB3, 0xE2, 0x2D, 0x9F,
9413 0x00, 0x80, 0x00, 0xE8,
9414
9415 0x56, 0x31, 0x56, 0xBF,
9416 0x47, 0x39, 0x47, 0xBF,
9417
9418 0x4F, 0x39, 0x4F, 0xBF,
9419 0x57, 0x39, 0x57, 0xBF,
9420
9421 0x53, 0x80, 0x07, 0xEA,
9422 0x24, 0x41, 0x20, 0xE9,
9423
9424 0x42, 0x73, 0xF8, 0xEC,
9425 0x00, 0xE0,
9426 0x2D, 0x73,
9427
9428 0x33, 0x72,
9429 0x0C, 0xE3,
9430 0xA5, 0x2F, 0x1E, 0xBD,
9431
9432 0x43, 0x43, 0x2D, 0xDF,
9433 0x4B, 0x4B, 0x2D, 0xDF,
9434
9435 0xAE, 0x1E, 0x26, 0xBD,
9436 0x58, 0xE3,
9437 0x33, 0x66,
9438
9439 0x53, 0x53, 0x2D, 0xDF,
9440 0x00, 0x80, 0x00, 0xE8,
9441
9442 0xB8, 0x38, 0x33, 0xBF,
9443 0x00, 0xE0,
9444 0x59, 0xE3,
9445
9446 0x1E, 0x12, 0x41, 0xE9,
9447 0x1A, 0x22, 0x41, 0xE9,
9448
9449 0x2B, 0x40, 0x3D, 0xE9,
9450 0x3F, 0x4B, 0xA0, 0xE8,
9451
9452 0x2D, 0x73,
9453 0x30, 0x76,
9454 0x05, 0x80, 0x3D, 0xEA,
9455
9456 0x37, 0x43, 0xA0, 0xE8,
9457 0x3D, 0x53, 0xA0, 0xE8,
9458
9459 0x48, 0x70, 0xF8, 0xEC,
9460 0x2B, 0x48, 0x3C, 0xE9,
9461
9462 0x1F, 0x27, 0xBC, 0xE8,
9463 0x00, 0x80, 0x00, 0xE8,
9464
9465 0x00, 0x80, 0x00, 0xE8,
9466 0x00, 0x80, 0x00, 0xE8,
9467
9468 0x15, 0xC0, 0x20, 0xE9,
9469 0x15, 0xC0, 0x20, 0xE9,
9470
9471 0x15, 0xC0, 0x20, 0xE9,
9472 0x15, 0xC0, 0x20, 0xE9,
9473
9474 0x18, 0x3A, 0x41, 0xE9,
9475 0x1D, 0x32, 0x41, 0xE9,
9476
9477 0x2A, 0x40, 0x20, 0xE9,
9478 0x56, 0x3D, 0x56, 0xDF,
9479
9480 0x46, 0x37, 0x46, 0xDF,
9481 0x4E, 0x3F, 0x4E, 0xDF,
9482
9483 0x16, 0x30, 0x20, 0xE9,
9484 0x4F, 0x3F, 0x4F, 0xDF,
9485
9486 0x32, 0x32, 0x2D, 0xDF,
9487 0x22, 0x22, 0x2D, 0xDF,
9488
9489 0x12, 0x12, 0x2D, 0xDF,
9490 0x3A, 0x3A, 0x2D, 0xDF,
9491
9492 0x47, 0x37, 0x47, 0xDF,
9493 0x57, 0x3D, 0x57, 0xDF,
9494
9495 0x3D, 0xCF, 0x74, 0xC0,
9496 0x37, 0xCF, 0x74, 0xC4,
9497
9498 0x0A, 0x44, 0x4C, 0xB0,
9499 0x02, 0x44, 0x54, 0xB0,
9500
9501 0x31, 0x53, 0x2F, 0x9F,
9502 0x34, 0x37, 0x20, 0xE9,
9503
9504 0x39, 0xE5, 0x2C, 0x9F,
9505 0x3C, 0x3D, 0x20, 0xE9,
9506
9507 0x2A, 0x44, 0x4C, 0xB2,
9508 0x1A, 0x44, 0x54, 0xB2,
9509
9510 0x26, 0x80, 0x3A, 0xEA,
9511 0x0A, 0x20,
9512 0x02, 0x20,
9513
9514 0x88, 0x73, 0x5E, 0xE9,
9515 0x2A, 0x20,
9516 0x1A, 0x20,
9517
9518 0x3D, 0xCF, 0x74, 0xC2,
9519 0x27, 0xCF, 0x74, 0xC6,
9520
9521 0x30, 0x50, 0x2E, 0x9F,
9522 0x32, 0x31, 0x5F, 0xE9,
9523
9524 0x38, 0x21, 0x2C, 0x9F,
9525 0x33, 0x39, 0x5F, 0xE9,
9526
9527 0x31, 0x53, 0x2F, 0x9F,
9528 0x9C, 0x27, 0x20, 0xE9,
9529
9530 0x0A, 0x44, 0x4C, 0xB4,
9531 0x02, 0x44, 0x54, 0xB4,
9532
9533 0x2A, 0x44, 0x4C, 0xB6,
9534 0x1A, 0x44, 0x54, 0xB6,
9535
9536 0x39, 0xE5, 0x2C, 0x9F,
9537 0x38, 0x3D, 0x20, 0xE9,
9538
9539 0x0A, 0x20,
9540 0x02, 0x20,
9541 0x2A, 0x20,
9542 0x1A, 0x20,
9543
9544 0x3D, 0xCF, 0x75, 0xC6,
9545 0x00, 0x80, 0x00, 0xE8,
9546
9547 0x30, 0x50, 0x2E, 0x9F,
9548 0x3E, 0x30, 0x4F, 0xE9,
9549
9550 0x38, 0x21, 0x2C, 0x9F,
9551 0x3F, 0x38, 0x4F, 0xE9,
9552
9553 0x0A, 0x45, 0x4D, 0xB6,
9554 0x02, 0x45, 0x55, 0xB6,
9555
9556 0x31, 0x53, 0x2F, 0x9F,
9557 0x3A, 0x31, 0x4F, 0xE9,
9558
9559 0x39, 0xE5, 0x2C, 0x9F,
9560 0x3B, 0x39, 0x4F, 0xE9,
9561
9562 0x31, 0x3D, 0x20, 0xE9,
9563 0x0A, 0x20,
9564 0x02, 0x20,
9565
9566 0x2A, 0x46, 0x4E, 0xBF,
9567 0x1A, 0x46, 0x56, 0xBF,
9568
9569 0x0A, 0x47, 0x4F, 0xBF,
9570 0x02, 0x47, 0x57, 0xBF,
9571
9572 0x30, 0x50, 0x2E, 0x9F,
9573 0x36, 0x30, 0x4F, 0xE9,
9574
9575 0x38, 0x21, 0x2C, 0x9F,
9576 0x37, 0x38, 0x4F, 0xE9,
9577
9578 0x31, 0x53, 0x2F, 0x9F,
9579 0x9D, 0x31, 0x4F, 0xE9,
9580
9581 0x39, 0xE5, 0x2C, 0x9F,
9582 0x9E, 0x39, 0x4F, 0xE9,
9583
9584 0x2A, 0x43, 0x4B, 0xBF,
9585 0x1A, 0x43, 0x53, 0xBF,
9586
9587 0x30, 0x50, 0x2E, 0x9F,
9588 0x35, 0x30, 0x4F, 0xE9,
9589
9590 0x38, 0x21, 0x2C, 0x9F,
9591 0x39, 0x38, 0x4F, 0xE9,
9592
9593 0x31, 0x53, 0x2F, 0x9F,
9594 0x80, 0x31, 0x57, 0xE9,
9595
9596 0x39, 0xE5, 0x2C, 0x9F,
9597 0x81, 0x39, 0x57, 0xE9,
9598
9599 0x37, 0x48, 0x50, 0xBD,
9600 0x8A, 0x36, 0x20, 0xE9,
9601
9602 0x86, 0x76, 0x57, 0xE9,
9603 0x8B, 0x3E, 0x20, 0xE9,
9604
9605 0x82, 0x30, 0x57, 0xE9,
9606 0x87, 0x77, 0x57, 0xE9,
9607
9608 0x83, 0x38, 0x57, 0xE9,
9609 0x35, 0x49, 0x51, 0xBD,
9610
9611 0x84, 0x31, 0x5E, 0xE9,
9612 0x30, 0x1F, 0x5F, 0xE9,
9613
9614 0x85, 0x39, 0x5E, 0xE9,
9615 0x57, 0x25, 0x20, 0xE9,
9616
9617 0x2B, 0x48, 0x20, 0xE9,
9618 0x1D, 0x37, 0xE1, 0xEA,
9619
9620 0x1E, 0x35, 0xE1, 0xEA,
9621 0x00, 0xE0,
9622 0x26, 0x77,
9623
9624 0x24, 0x49, 0x20, 0xE9,
9625 0xA6, 0xFF, 0x20, 0xEA,
9626
9627 0x16, 0x26, 0x20, 0xE9,
9628 0x57, 0x2E, 0xBF, 0xEA,
9629
9630 0x1C, 0x46, 0xA0, 0xE8,
9631 0x23, 0x4E, 0xA0, 0xE8,
9632
9633 0x2B, 0x56, 0xA0, 0xE8,
9634 0x1D, 0x47, 0xA0, 0xE8,
9635
9636 0x24, 0x4F, 0xA0, 0xE8,
9637 0x2C, 0x57, 0xA0, 0xE8,
9638
9639 0x1C, 0x00,
9640 0x23, 0x00,
9641 0x2B, 0x00,
9642 0x00, 0xE0,
9643
9644 0x1D, 0x00,
9645 0x24, 0x00,
9646 0x2C, 0x00,
9647 0x00, 0xE0,
9648
9649 0x1C, 0x65,
9650 0x23, 0x65,
9651 0x2B, 0x65,
9652 0x00, 0xE0,
9653
9654 0x1D, 0x65,
9655 0x24, 0x65,
9656 0x2C, 0x65,
9657 0x00, 0xE0,
9658
9659 0x1C, 0x23, 0x60, 0xEC,
9660 0x36, 0xD7, 0x36, 0xAD,
9661
9662 0x2B, 0x80, 0x60, 0xEC,
9663 0x1D, 0x24, 0x60, 0xEC,
9664
9665 0x3E, 0xD7, 0x3E, 0xAD,
9666 0x2C, 0x80, 0x60, 0xEC,
9667
9668 0x1C, 0x2B, 0xDE, 0xE8,
9669 0x23, 0x80, 0xDE, 0xE8,
9670
9671 0x36, 0x80, 0x36, 0xBD,
9672 0x3E, 0x80, 0x3E, 0xBD,
9673
9674 0x33, 0xD7, 0x1C, 0xBD,
9675 0x3B, 0xD7, 0x23, 0xBD,
9676
9677 0x46, 0x80, 0x46, 0xCF,
9678 0x4F, 0x80, 0x4F, 0xCF,
9679
9680 0x56, 0x33, 0x56, 0xCF,
9681 0x47, 0x3B, 0x47, 0xCF,
9682
9683 0xCD, 0xFF, 0x20, 0xEA,
9684 0x00, 0x80, 0x00, 0xE8,
9685
9686 0x4E, 0x33, 0x4E, 0xCF,
9687 0x57, 0x3B, 0x57, 0xCF,
9688
9689 0x94, 0xFF, 0x20, 0xEA,
9690 0x57, 0xC0, 0xBF, 0xEA,
9691
9692 0x00, 0x80, 0xA0, 0xE9,
9693 0x00, 0x00, 0xD8, 0xEC,
9694
9695};
9696
9697static unsigned char warp_g400_tgzf[] = {
9698
9699 0x00, 0x88, 0x98, 0xE9,
9700 0x00, 0x80, 0x00, 0xE8,
9701
9702 0x00, 0x80, 0xA0, 0xE9,
9703 0x00, 0x00, 0xD8, 0xEC,
9704
9705 0xFF, 0x80, 0xC0, 0xE9,
9706 0x00, 0x80, 0x00, 0xE8,
9707
9708 0x22, 0x40, 0x48, 0xBF,
9709 0x2A, 0x40, 0x50, 0xBF,
9710
9711 0x32, 0x41, 0x49, 0xBF,
9712 0x3A, 0x41, 0x51, 0xBF,
9713
9714 0xC3, 0x6B,
9715 0xCB, 0x6B,
9716 0x00, 0x88, 0x98, 0xE9,
9717
9718 0x73, 0x7B, 0xC8, 0xEC,
9719 0x96, 0xE2,
9720 0x41, 0x04,
9721
9722 0x7B, 0x43, 0xA0, 0xE8,
9723 0x73, 0x4B, 0xA0, 0xE8,
9724
9725 0xAD, 0xEE, 0x29, 0x9F,
9726 0x00, 0xE0,
9727 0x49, 0x04,
9728
9729 0x90, 0xE2,
9730 0x51, 0x04,
9731 0x31, 0x46, 0xB1, 0xE8,
9732
9733 0x49, 0x41, 0xC0, 0xEC,
9734 0x39, 0x57, 0xB1, 0xE8,
9735
9736 0x00, 0x04,
9737 0x46, 0xE2,
9738 0x73, 0x53, 0xA0, 0xE8,
9739
9740 0x51, 0x41, 0xC0, 0xEC,
9741 0x31, 0x00,
9742 0x39, 0x00,
9743
9744 0x5D, 0x80, 0x15, 0xEA,
9745 0x08, 0x04,
9746 0x10, 0x04,
9747
9748 0x51, 0x49, 0xC0, 0xEC,
9749 0x2F, 0x41, 0x60, 0xEA,
9750
9751 0x31, 0x20,
9752 0x39, 0x20,
9753 0x1F, 0x42, 0xA0, 0xE8,
9754
9755 0x2A, 0x42, 0x4A, 0xBF,
9756 0x27, 0x4A, 0xA0, 0xE8,
9757
9758 0x1A, 0x42, 0x52, 0xBF,
9759 0x1E, 0x49, 0x60, 0xEA,
9760
9761 0x73, 0x7B, 0xC8, 0xEC,
9762 0x26, 0x51, 0x60, 0xEA,
9763
9764 0x32, 0x40, 0x48, 0xBD,
9765 0x22, 0x40, 0x50, 0xBD,
9766
9767 0x12, 0x41, 0x49, 0xBD,
9768 0x3A, 0x41, 0x51, 0xBD,
9769
9770 0xBF, 0x2F, 0x26, 0xBD,
9771 0x00, 0xE0,
9772 0x7B, 0x72,
9773
9774 0x32, 0x20,
9775 0x22, 0x20,
9776 0x12, 0x20,
9777 0x3A, 0x20,
9778
9779 0x46, 0x31, 0x46, 0xBF,
9780 0x4E, 0x31, 0x4E, 0xBF,
9781
9782 0xB3, 0xE2, 0x2D, 0x9F,
9783 0x00, 0x80, 0x00, 0xE8,
9784
9785 0x56, 0x31, 0x56, 0xBF,
9786 0x47, 0x39, 0x47, 0xBF,
9787
9788 0x4F, 0x39, 0x4F, 0xBF,
9789 0x57, 0x39, 0x57, 0xBF,
9790
9791 0x4F, 0x80, 0x07, 0xEA,
9792 0x24, 0x41, 0x20, 0xE9,
9793
9794 0x42, 0x73, 0xF8, 0xEC,
9795 0x00, 0xE0,
9796 0x2D, 0x73,
9797
9798 0x33, 0x72,
9799 0x0C, 0xE3,
9800 0xA5, 0x2F, 0x1E, 0xBD,
9801
9802 0x43, 0x43, 0x2D, 0xDF,
9803 0x4B, 0x4B, 0x2D, 0xDF,
9804
9805 0xAE, 0x1E, 0x26, 0xBD,
9806 0x58, 0xE3,
9807 0x33, 0x66,
9808
9809 0x53, 0x53, 0x2D, 0xDF,
9810 0x00, 0x80, 0x00, 0xE8,
9811
9812 0xB8, 0x38, 0x33, 0xBF,
9813 0x00, 0xE0,
9814 0x59, 0xE3,
9815
9816 0x1E, 0x12, 0x41, 0xE9,
9817 0x1A, 0x22, 0x41, 0xE9,
9818
9819 0x2B, 0x40, 0x3D, 0xE9,
9820 0x3F, 0x4B, 0xA0, 0xE8,
9821
9822 0x2D, 0x73,
9823 0x30, 0x76,
9824 0x05, 0x80, 0x3D, 0xEA,
9825
9826 0x37, 0x43, 0xA0, 0xE8,
9827 0x3D, 0x53, 0xA0, 0xE8,
9828
9829 0x48, 0x70, 0xF8, 0xEC,
9830 0x2B, 0x48, 0x3C, 0xE9,
9831
9832 0x1F, 0x27, 0xBC, 0xE8,
9833 0x00, 0x80, 0x00, 0xE8,
9834
9835 0x00, 0x80, 0x00, 0xE8,
9836 0x00, 0x80, 0x00, 0xE8,
9837
9838 0x15, 0xC0, 0x20, 0xE9,
9839 0x15, 0xC0, 0x20, 0xE9,
9840
9841 0x15, 0xC0, 0x20, 0xE9,
9842 0x15, 0xC0, 0x20, 0xE9,
9843
9844 0x18, 0x3A, 0x41, 0xE9,
9845 0x1D, 0x32, 0x41, 0xE9,
9846
9847 0x2A, 0x40, 0x20, 0xE9,
9848 0x56, 0x3D, 0x56, 0xDF,
9849
9850 0x46, 0x37, 0x46, 0xDF,
9851 0x4E, 0x3F, 0x4E, 0xDF,
9852
9853 0x16, 0x30, 0x20, 0xE9,
9854 0x4F, 0x3F, 0x4F, 0xDF,
9855
9856 0x32, 0x32, 0x2D, 0xDF,
9857 0x22, 0x22, 0x2D, 0xDF,
9858
9859 0x12, 0x12, 0x2D, 0xDF,
9860 0x3A, 0x3A, 0x2D, 0xDF,
9861
9862 0x47, 0x37, 0x47, 0xDF,
9863 0x57, 0x3D, 0x57, 0xDF,
9864
9865 0x3D, 0xCF, 0x74, 0xC0,
9866 0x37, 0xCF, 0x74, 0xC4,
9867
9868 0x39, 0xE5, 0x2C, 0x9F,
9869 0x34, 0x80, 0x20, 0xE9,
9870
9871 0x31, 0x53, 0x2F, 0x9F,
9872 0x00, 0x80, 0x00, 0xE8,
9873
9874 0x88, 0x73, 0x5E, 0xE9,
9875 0x00, 0x80, 0x00, 0xE8,
9876
9877 0x27, 0xCF, 0x75, 0xC6,
9878 0x3C, 0x3D, 0x20, 0xE9,
9879
9880 0x0A, 0x44, 0x4C, 0xB0,
9881 0x02, 0x44, 0x54, 0xB0,
9882
9883 0x2A, 0x44, 0x4C, 0xB2,
9884 0x1A, 0x44, 0x54, 0xB2,
9885
9886 0x20, 0x80, 0x3A, 0xEA,
9887 0x0A, 0x20,
9888 0x02, 0x20,
9889
9890 0x3D, 0xCF, 0x74, 0xC2,
9891 0x2A, 0x20,
9892 0x1A, 0x20,
9893
9894 0x30, 0x50, 0x2E, 0x9F,
9895 0x32, 0x31, 0x5F, 0xE9,
9896
9897 0x38, 0x21, 0x2C, 0x9F,
9898 0x33, 0x39, 0x5F, 0xE9,
9899
9900 0x31, 0x53, 0x2F, 0x9F,
9901 0x31, 0x27, 0x20, 0xE9,
9902
9903 0x0A, 0x44, 0x4C, 0xB4,
9904 0x02, 0x44, 0x54, 0xB4,
9905
9906 0x2A, 0x45, 0x4D, 0xB6,
9907 0x1A, 0x45, 0x55, 0xB6,
9908
9909 0x39, 0xE5, 0x2C, 0x9F,
9910 0x38, 0x3D, 0x20, 0xE9,
9911
9912 0x0A, 0x20,
9913 0x02, 0x20,
9914 0x2A, 0x20,
9915 0x1A, 0x20,
9916
9917 0x0A, 0x47, 0x4F, 0xBF,
9918 0x02, 0x47, 0x57, 0xBF,
9919
9920 0x30, 0x50, 0x2E, 0x9F,
9921 0x3E, 0x30, 0x4F, 0xE9,
9922
9923 0x38, 0x21, 0x2C, 0x9F,
9924 0x3F, 0x38, 0x4F, 0xE9,
9925
9926 0x2A, 0x46, 0x4E, 0xBF,
9927 0x1A, 0x46, 0x56, 0xBF,
9928
9929 0x31, 0x53, 0x2F, 0x9F,
9930 0x3A, 0x31, 0x4F, 0xE9,
9931
9932 0x39, 0xE5, 0x2C, 0x9F,
9933 0x3B, 0x39, 0x4F, 0xE9,
9934
9935 0x31, 0x53, 0x2F, 0x9F,
9936 0x36, 0x30, 0x4F, 0xE9,
9937
9938 0x39, 0xE5, 0x2C, 0x9F,
9939 0x37, 0x38, 0x4F, 0xE9,
9940
9941 0x2A, 0x43, 0x4B, 0xBF,
9942 0x1A, 0x43, 0x53, 0xBF,
9943
9944 0x30, 0x50, 0x2E, 0x9F,
9945 0x35, 0x31, 0x4F, 0xE9,
9946
9947 0x38, 0x21, 0x2C, 0x9F,
9948 0x39, 0x39, 0x4F, 0xE9,
9949
9950 0x31, 0x53, 0x2F, 0x9F,
9951 0x80, 0x31, 0x57, 0xE9,
9952
9953 0x39, 0xE5, 0x2C, 0x9F,
9954 0x81, 0x39, 0x57, 0xE9,
9955
9956 0x37, 0x48, 0x50, 0xBD,
9957 0x8A, 0x36, 0x20, 0xE9,
9958
9959 0x86, 0x76, 0x57, 0xE9,
9960 0x8B, 0x3E, 0x20, 0xE9,
9961
9962 0x82, 0x30, 0x57, 0xE9,
9963 0x87, 0x77, 0x57, 0xE9,
9964
9965 0x83, 0x38, 0x57, 0xE9,
9966 0x35, 0x49, 0x51, 0xBD,
9967
9968 0x84, 0x31, 0x5E, 0xE9,
9969 0x30, 0x1F, 0x5F, 0xE9,
9970
9971 0x85, 0x39, 0x5E, 0xE9,
9972 0x57, 0x25, 0x20, 0xE9,
9973
9974 0x2B, 0x48, 0x20, 0xE9,
9975 0x1D, 0x37, 0xE1, 0xEA,
9976
9977 0x1E, 0x35, 0xE1, 0xEA,
9978 0x00, 0xE0,
9979 0x26, 0x77,
9980
9981 0x24, 0x49, 0x20, 0xE9,
9982 0xAA, 0xFF, 0x20, 0xEA,
9983
9984 0x16, 0x26, 0x20, 0xE9,
9985 0x57, 0x2E, 0xBF, 0xEA,
9986
9987 0x1C, 0x46, 0xA0, 0xE8,
9988 0x23, 0x4E, 0xA0, 0xE8,
9989
9990 0x2B, 0x56, 0xA0, 0xE8,
9991 0x1D, 0x47, 0xA0, 0xE8,
9992
9993 0x24, 0x4F, 0xA0, 0xE8,
9994 0x2C, 0x57, 0xA0, 0xE8,
9995
9996 0x1C, 0x00,
9997 0x23, 0x00,
9998 0x2B, 0x00,
9999 0x00, 0xE0,
10000
10001 0x1D, 0x00,
10002 0x24, 0x00,
10003 0x2C, 0x00,
10004 0x00, 0xE0,
10005
10006 0x1C, 0x65,
10007 0x23, 0x65,
10008 0x2B, 0x65,
10009 0x00, 0xE0,
10010
10011 0x1D, 0x65,
10012 0x24, 0x65,
10013 0x2C, 0x65,
10014 0x00, 0xE0,
10015
10016 0x1C, 0x23, 0x60, 0xEC,
10017 0x36, 0xD7, 0x36, 0xAD,
10018
10019 0x2B, 0x80, 0x60, 0xEC,
10020 0x1D, 0x24, 0x60, 0xEC,
10021
10022 0x3E, 0xD7, 0x3E, 0xAD,
10023 0x2C, 0x80, 0x60, 0xEC,
10024
10025 0x1C, 0x2B, 0xDE, 0xE8,
10026 0x23, 0x80, 0xDE, 0xE8,
10027
10028 0x36, 0x80, 0x36, 0xBD,
10029 0x3E, 0x80, 0x3E, 0xBD,
10030
10031 0x33, 0xD7, 0x1C, 0xBD,
10032 0x3B, 0xD7, 0x23, 0xBD,
10033
10034 0x46, 0x80, 0x46, 0xCF,
10035 0x4F, 0x80, 0x4F, 0xCF,
10036
10037 0x56, 0x33, 0x56, 0xCF,
10038 0x47, 0x3B, 0x47, 0xCF,
10039
10040 0xD3, 0xFF, 0x20, 0xEA,
10041 0x00, 0x80, 0x00, 0xE8,
10042
10043 0x4E, 0x33, 0x4E, 0xCF,
10044 0x57, 0x3B, 0x57, 0xCF,
10045
10046 0x98, 0xFF, 0x20, 0xEA,
10047 0x57, 0xC0, 0xBF, 0xEA,
10048
10049 0x00, 0x80, 0xA0, 0xE9,
10050 0x00, 0x00, 0xD8, 0xEC,
10051
10052};
10053
10054static unsigned char warp_g400_tgzs[] = {
10055
10056 0x00, 0x88, 0x98, 0xE9,
10057 0x00, 0x80, 0x00, 0xE8,
10058
10059 0x00, 0x80, 0xA0, 0xE9,
10060 0x00, 0x00, 0xD8, 0xEC,
10061
10062 0xFF, 0x80, 0xC0, 0xE9,
10063 0x00, 0x80, 0x00, 0xE8,
10064
10065 0x22, 0x40, 0x48, 0xBF,
10066 0x2A, 0x40, 0x50, 0xBF,
10067
10068 0x32, 0x41, 0x49, 0xBF,
10069 0x3A, 0x41, 0x51, 0xBF,
10070
10071 0xC3, 0x6B,
10072 0xCB, 0x6B,
10073 0x00, 0x88, 0x98, 0xE9,
10074
10075 0x73, 0x7B, 0xC8, 0xEC,
10076 0x96, 0xE2,
10077 0x41, 0x04,
10078
10079 0x7B, 0x43, 0xA0, 0xE8,
10080 0x73, 0x4B, 0xA0, 0xE8,
10081
10082 0xAD, 0xEE, 0x29, 0x9F,
10083 0x00, 0xE0,
10084 0x49, 0x04,
10085
10086 0x90, 0xE2,
10087 0x51, 0x04,
10088 0x31, 0x46, 0xB1, 0xE8,
10089
10090 0x49, 0x41, 0xC0, 0xEC,
10091 0x39, 0x57, 0xB1, 0xE8,
10092
10093 0x00, 0x04,
10094 0x46, 0xE2,
10095 0x73, 0x53, 0xA0, 0xE8,
10096
10097 0x51, 0x41, 0xC0, 0xEC,
10098 0x31, 0x00,
10099 0x39, 0x00,
10100
10101 0x65, 0x80, 0x15, 0xEA,
10102 0x08, 0x04,
10103 0x10, 0x04,
10104
10105 0x51, 0x49, 0xC0, 0xEC,
10106 0x2F, 0x41, 0x60, 0xEA,
10107
10108 0x31, 0x20,
10109 0x39, 0x20,
10110 0x1F, 0x42, 0xA0, 0xE8,
10111
10112 0x2A, 0x42, 0x4A, 0xBF,
10113 0x27, 0x4A, 0xA0, 0xE8,
10114
10115 0x1A, 0x42, 0x52, 0xBF,
10116 0x1E, 0x49, 0x60, 0xEA,
10117
10118 0x73, 0x7B, 0xC8, 0xEC,
10119 0x26, 0x51, 0x60, 0xEA,
10120
10121 0x32, 0x40, 0x48, 0xBD,
10122 0x22, 0x40, 0x50, 0xBD,
10123
10124 0x12, 0x41, 0x49, 0xBD,
10125 0x3A, 0x41, 0x51, 0xBD,
10126
10127 0xBF, 0x2F, 0x26, 0xBD,
10128 0x00, 0xE0,
10129 0x7B, 0x72,
10130
10131 0x32, 0x20,
10132 0x22, 0x20,
10133 0x12, 0x20,
10134 0x3A, 0x20,
10135
10136 0x46, 0x31, 0x46, 0xBF,
10137 0x4E, 0x31, 0x4E, 0xBF,
10138
10139 0xB3, 0xE2, 0x2D, 0x9F,
10140 0x00, 0x80, 0x00, 0xE8,
10141
10142 0x56, 0x31, 0x56, 0xBF,
10143 0x47, 0x39, 0x47, 0xBF,
10144
10145 0x4F, 0x39, 0x4F, 0xBF,
10146 0x57, 0x39, 0x57, 0xBF,
10147
10148 0x57, 0x80, 0x07, 0xEA,
10149 0x24, 0x41, 0x20, 0xE9,
10150
10151 0x42, 0x73, 0xF8, 0xEC,
10152 0x00, 0xE0,
10153 0x2D, 0x73,
10154
10155 0x33, 0x72,
10156 0x0C, 0xE3,
10157 0xA5, 0x2F, 0x1E, 0xBD,
10158
10159 0x43, 0x43, 0x2D, 0xDF,
10160 0x4B, 0x4B, 0x2D, 0xDF,
10161
10162 0xAE, 0x1E, 0x26, 0xBD,
10163 0x58, 0xE3,
10164 0x33, 0x66,
10165
10166 0x53, 0x53, 0x2D, 0xDF,
10167 0x00, 0x80, 0x00, 0xE8,
10168
10169 0xB8, 0x38, 0x33, 0xBF,
10170 0x00, 0xE0,
10171 0x59, 0xE3,
10172
10173 0x1E, 0x12, 0x41, 0xE9,
10174 0x1A, 0x22, 0x41, 0xE9,
10175
10176 0x2B, 0x40, 0x3D, 0xE9,
10177 0x3F, 0x4B, 0xA0, 0xE8,
10178
10179 0x2D, 0x73,
10180 0x30, 0x76,
10181 0x05, 0x80, 0x3D, 0xEA,
10182
10183 0x37, 0x43, 0xA0, 0xE8,
10184 0x3D, 0x53, 0xA0, 0xE8,
10185
10186 0x48, 0x70, 0xF8, 0xEC,
10187 0x2B, 0x48, 0x3C, 0xE9,
10188
10189 0x1F, 0x27, 0xBC, 0xE8,
10190 0x00, 0x80, 0x00, 0xE8,
10191
10192 0x00, 0x80, 0x00, 0xE8,
10193 0x00, 0x80, 0x00, 0xE8,
10194
10195 0x15, 0xC0, 0x20, 0xE9,
10196 0x15, 0xC0, 0x20, 0xE9,
10197
10198 0x15, 0xC0, 0x20, 0xE9,
10199 0x15, 0xC0, 0x20, 0xE9,
10200
10201 0x18, 0x3A, 0x41, 0xE9,
10202 0x1D, 0x32, 0x41, 0xE9,
10203
10204 0x2A, 0x40, 0x20, 0xE9,
10205 0x56, 0x3D, 0x56, 0xDF,
10206
10207 0x46, 0x37, 0x46, 0xDF,
10208 0x4E, 0x3F, 0x4E, 0xDF,
10209
10210 0x16, 0x30, 0x20, 0xE9,
10211 0x4F, 0x3F, 0x4F, 0xDF,
10212
10213 0x47, 0x37, 0x47, 0xDF,
10214 0x57, 0x3D, 0x57, 0xDF,
10215
10216 0x32, 0x32, 0x2D, 0xDF,
10217 0x22, 0x22, 0x2D, 0xDF,
10218
10219 0x12, 0x12, 0x2D, 0xDF,
10220 0x3A, 0x3A, 0x2D, 0xDF,
10221
10222 0x27, 0xCF, 0x74, 0xC2,
10223 0x37, 0xCF, 0x74, 0xC4,
10224
10225 0x0A, 0x44, 0x4C, 0xB0,
10226 0x02, 0x44, 0x54, 0xB0,
10227
10228 0x3D, 0xCF, 0x74, 0xC0,
10229 0x34, 0x37, 0x20, 0xE9,
10230
10231 0x31, 0x53, 0x2F, 0x9F,
10232 0x38, 0x27, 0x20, 0xE9,
10233
10234 0x39, 0xE5, 0x2C, 0x9F,
10235 0x3C, 0x3D, 0x20, 0xE9,
10236
10237 0x2A, 0x44, 0x4C, 0xB2,
10238 0x1A, 0x44, 0x54, 0xB2,
10239
10240 0x29, 0x80, 0x3A, 0xEA,
10241 0x0A, 0x20,
10242 0x02, 0x20,
10243
10244 0x27, 0xCF, 0x75, 0xC0,
10245 0x2A, 0x20,
10246 0x1A, 0x20,
10247
10248 0x30, 0x50, 0x2E, 0x9F,
10249 0x32, 0x31, 0x5F, 0xE9,
10250
10251 0x38, 0x21, 0x2C, 0x9F,
10252 0x33, 0x39, 0x5F, 0xE9,
10253
10254 0x3D, 0xCF, 0x75, 0xC2,
10255 0x37, 0xCF, 0x75, 0xC4,
10256
10257 0x31, 0x53, 0x2F, 0x9F,
10258 0xA6, 0x27, 0x20, 0xE9,
10259
10260 0x39, 0xE5, 0x2C, 0x9F,
10261 0xA3, 0x3D, 0x20, 0xE9,
10262
10263 0x2A, 0x44, 0x4C, 0xB4,
10264 0x1A, 0x44, 0x54, 0xB4,
10265
10266 0x0A, 0x45, 0x4D, 0xB0,
10267 0x02, 0x45, 0x55, 0xB0,
10268
10269 0x88, 0x73, 0x5E, 0xE9,
10270 0x2A, 0x20,
10271 0x1A, 0x20,
10272
10273 0xA0, 0x37, 0x20, 0xE9,
10274 0x0A, 0x20,
10275 0x02, 0x20,
10276
10277 0x31, 0x53, 0x2F, 0x9F,
10278 0x3E, 0x30, 0x4F, 0xE9,
10279
10280 0x39, 0xE5, 0x2C, 0x9F,
10281 0x3F, 0x38, 0x4F, 0xE9,
10282
10283 0x30, 0x50, 0x2E, 0x9F,
10284 0x3A, 0x31, 0x4F, 0xE9,
10285
10286 0x2A, 0x45, 0x4D, 0xB2,
10287 0x1A, 0x45, 0x55, 0xB2,
10288
10289 0x0A, 0x45, 0x4D, 0xB4,
10290 0x02, 0x45, 0x55, 0xB4,
10291
10292 0x38, 0x21, 0x2C, 0x9F,
10293 0x3B, 0x39, 0x4F, 0xE9,
10294
10295 0x0A, 0x20,
10296 0x02, 0x20,
10297 0x2A, 0x20,
10298 0x1A, 0x20,
10299
10300 0x2A, 0x46, 0x4E, 0xBF,
10301 0x1A, 0x46, 0x56, 0xBF,
10302
10303 0x31, 0x53, 0x2F, 0x9F,
10304 0x36, 0x31, 0x4F, 0xE9,
10305
10306 0x39, 0xE5, 0x2C, 0x9F,
10307 0x37, 0x39, 0x4F, 0xE9,
10308
10309 0x30, 0x50, 0x2E, 0x9F,
10310 0xA7, 0x30, 0x4F, 0xE9,
10311
10312 0x38, 0x21, 0x2C, 0x9F,
10313 0xA8, 0x38, 0x4F, 0xE9,
10314
10315 0x0A, 0x47, 0x4F, 0xBF,
10316 0x02, 0x47, 0x57, 0xBF,
10317
10318 0x31, 0x53, 0x2F, 0x9F,
10319 0xA4, 0x31, 0x4F, 0xE9,
10320
10321 0x39, 0xE5, 0x2C, 0x9F,
10322 0xA5, 0x39, 0x4F, 0xE9,
10323
10324 0x2A, 0x43, 0x4B, 0xBF,
10325 0x1A, 0x43, 0x53, 0xBF,
10326
10327 0x30, 0x50, 0x2E, 0x9F,
10328 0xA1, 0x30, 0x4F, 0xE9,
10329
10330 0x38, 0x21, 0x2C, 0x9F,
10331 0xA2, 0x38, 0x4F, 0xE9,
10332
10333 0x31, 0x53, 0x2F, 0x9F,
10334 0x80, 0x31, 0x57, 0xE9,
10335
10336 0x39, 0xE5, 0x2C, 0x9F,
10337 0x81, 0x39, 0x57, 0xE9,
10338
10339 0x37, 0x48, 0x50, 0xBD,
10340 0x8A, 0x36, 0x20, 0xE9,
10341
10342 0x86, 0x76, 0x57, 0xE9,
10343 0x8B, 0x3E, 0x20, 0xE9,
10344
10345 0x82, 0x30, 0x57, 0xE9,
10346 0x87, 0x77, 0x57, 0xE9,
10347
10348 0x83, 0x38, 0x57, 0xE9,
10349 0x35, 0x49, 0x51, 0xBD,
10350
10351 0x84, 0x31, 0x5E, 0xE9,
10352 0x30, 0x1F, 0x5F, 0xE9,
10353
10354 0x85, 0x39, 0x5E, 0xE9,
10355 0x57, 0x25, 0x20, 0xE9,
10356
10357 0x2B, 0x48, 0x20, 0xE9,
10358 0x1D, 0x37, 0xE1, 0xEA,
10359
10360 0x1E, 0x35, 0xE1, 0xEA,
10361 0x00, 0xE0,
10362 0x26, 0x77,
10363
10364 0x24, 0x49, 0x20, 0xE9,
10365 0xA2, 0xFF, 0x20, 0xEA,
10366
10367 0x16, 0x26, 0x20, 0xE9,
10368 0x57, 0x2E, 0xBF, 0xEA,
10369
10370 0x1C, 0x46, 0xA0, 0xE8,
10371 0x23, 0x4E, 0xA0, 0xE8,
10372
10373 0x2B, 0x56, 0xA0, 0xE8,
10374 0x1D, 0x47, 0xA0, 0xE8,
10375
10376 0x24, 0x4F, 0xA0, 0xE8,
10377 0x2C, 0x57, 0xA0, 0xE8,
10378
10379 0x1C, 0x00,
10380 0x23, 0x00,
10381 0x2B, 0x00,
10382 0x00, 0xE0,
10383
10384 0x1D, 0x00,
10385 0x24, 0x00,
10386 0x2C, 0x00,
10387 0x00, 0xE0,
10388
10389 0x1C, 0x65,
10390 0x23, 0x65,
10391 0x2B, 0x65,
10392 0x00, 0xE0,
10393
10394 0x1D, 0x65,
10395 0x24, 0x65,
10396 0x2C, 0x65,
10397 0x00, 0xE0,
10398
10399 0x1C, 0x23, 0x60, 0xEC,
10400 0x36, 0xD7, 0x36, 0xAD,
10401
10402 0x2B, 0x80, 0x60, 0xEC,
10403 0x1D, 0x24, 0x60, 0xEC,
10404
10405 0x3E, 0xD7, 0x3E, 0xAD,
10406 0x2C, 0x80, 0x60, 0xEC,
10407
10408 0x1C, 0x2B, 0xDE, 0xE8,
10409 0x23, 0x80, 0xDE, 0xE8,
10410
10411 0x36, 0x80, 0x36, 0xBD,
10412 0x3E, 0x80, 0x3E, 0xBD,
10413
10414 0x33, 0xD7, 0x1C, 0xBD,
10415 0x3B, 0xD7, 0x23, 0xBD,
10416
10417 0x46, 0x80, 0x46, 0xCF,
10418 0x4F, 0x80, 0x4F, 0xCF,
10419
10420 0x56, 0x33, 0x56, 0xCF,
10421 0x47, 0x3B, 0x47, 0xCF,
10422
10423 0xCA, 0xFF, 0x20, 0xEA,
10424 0x00, 0x80, 0x00, 0xE8,
10425
10426 0x4E, 0x33, 0x4E, 0xCF,
10427 0x57, 0x3B, 0x57, 0xCF,
10428
10429 0x90, 0xFF, 0x20, 0xEA,
10430 0x57, 0xC0, 0xBF, 0xEA,
10431
10432 0x00, 0x80, 0xA0, 0xE9,
10433 0x00, 0x00, 0xD8, 0xEC,
10434
10435};
10436
10437static unsigned char warp_g400_tgzsa[] = {
10438
10439 0x00, 0x88, 0x98, 0xE9,
10440 0x00, 0x80, 0x00, 0xE8,
10441
10442 0x00, 0x80, 0xA0, 0xE9,
10443 0x00, 0x00, 0xD8, 0xEC,
10444
10445 0xFF, 0x80, 0xC0, 0xE9,
10446 0x00, 0x80, 0x00, 0xE8,
10447
10448 0x22, 0x40, 0x48, 0xBF,
10449 0x2A, 0x40, 0x50, 0xBF,
10450
10451 0x32, 0x41, 0x49, 0xBF,
10452 0x3A, 0x41, 0x51, 0xBF,
10453
10454 0xC3, 0x6B,
10455 0xCB, 0x6B,
10456 0x00, 0x88, 0x98, 0xE9,
10457
10458 0x73, 0x7B, 0xC8, 0xEC,
10459 0x96, 0xE2,
10460 0x41, 0x04,
10461
10462 0x7B, 0x43, 0xA0, 0xE8,
10463 0x73, 0x4B, 0xA0, 0xE8,
10464
10465 0xAD, 0xEE, 0x29, 0x9F,
10466 0x00, 0xE0,
10467 0x49, 0x04,
10468
10469 0x90, 0xE2,
10470 0x51, 0x04,
10471 0x31, 0x46, 0xB1, 0xE8,
10472
10473 0x49, 0x41, 0xC0, 0xEC,
10474 0x39, 0x57, 0xB1, 0xE8,
10475
10476 0x00, 0x04,
10477 0x46, 0xE2,
10478 0x73, 0x53, 0xA0, 0xE8,
10479
10480 0x51, 0x41, 0xC0, 0xEC,
10481 0x31, 0x00,
10482 0x39, 0x00,
10483
10484 0x6A, 0x80, 0x15, 0xEA,
10485 0x08, 0x04,
10486 0x10, 0x04,
10487
10488 0x51, 0x49, 0xC0, 0xEC,
10489 0x2F, 0x41, 0x60, 0xEA,
10490
10491 0x31, 0x20,
10492 0x39, 0x20,
10493 0x1F, 0x42, 0xA0, 0xE8,
10494
10495 0x2A, 0x42, 0x4A, 0xBF,
10496 0x27, 0x4A, 0xA0, 0xE8,
10497
10498 0x1A, 0x42, 0x52, 0xBF,
10499 0x1E, 0x49, 0x60, 0xEA,
10500
10501 0x73, 0x7B, 0xC8, 0xEC,
10502 0x26, 0x51, 0x60, 0xEA,
10503
10504 0x32, 0x40, 0x48, 0xBD,
10505 0x22, 0x40, 0x50, 0xBD,
10506
10507 0x12, 0x41, 0x49, 0xBD,
10508 0x3A, 0x41, 0x51, 0xBD,
10509
10510 0xBF, 0x2F, 0x26, 0xBD,
10511 0x00, 0xE0,
10512 0x7B, 0x72,
10513
10514 0x32, 0x20,
10515 0x22, 0x20,
10516 0x12, 0x20,
10517 0x3A, 0x20,
10518
10519 0x46, 0x31, 0x46, 0xBF,
10520 0x4E, 0x31, 0x4E, 0xBF,
10521
10522 0xB3, 0xE2, 0x2D, 0x9F,
10523 0x00, 0x80, 0x00, 0xE8,
10524
10525 0x56, 0x31, 0x56, 0xBF,
10526 0x47, 0x39, 0x47, 0xBF,
10527
10528 0x4F, 0x39, 0x4F, 0xBF,
10529 0x57, 0x39, 0x57, 0xBF,
10530
10531 0x5C, 0x80, 0x07, 0xEA,
10532 0x24, 0x41, 0x20, 0xE9,
10533
10534 0x42, 0x73, 0xF8, 0xEC,
10535 0x00, 0xE0,
10536 0x2D, 0x73,
10537
10538 0x33, 0x72,
10539 0x0C, 0xE3,
10540 0xA5, 0x2F, 0x1E, 0xBD,
10541
10542 0x43, 0x43, 0x2D, 0xDF,
10543 0x4B, 0x4B, 0x2D, 0xDF,
10544
10545 0xAE, 0x1E, 0x26, 0xBD,
10546 0x58, 0xE3,
10547 0x33, 0x66,
10548
10549 0x53, 0x53, 0x2D, 0xDF,
10550 0x00, 0x80, 0x00, 0xE8,
10551
10552 0xB8, 0x38, 0x33, 0xBF,
10553 0x00, 0xE0,
10554 0x59, 0xE3,
10555
10556 0x1E, 0x12, 0x41, 0xE9,
10557 0x1A, 0x22, 0x41, 0xE9,
10558
10559 0x2B, 0x40, 0x3D, 0xE9,
10560 0x3F, 0x4B, 0xA0, 0xE8,
10561
10562 0x2D, 0x73,
10563 0x30, 0x76,
10564 0x05, 0x80, 0x3D, 0xEA,
10565
10566 0x37, 0x43, 0xA0, 0xE8,
10567 0x3D, 0x53, 0xA0, 0xE8,
10568
10569 0x48, 0x70, 0xF8, 0xEC,
10570 0x2B, 0x48, 0x3C, 0xE9,
10571
10572 0x1F, 0x27, 0xBC, 0xE8,
10573 0x00, 0x80, 0x00, 0xE8,
10574
10575 0x00, 0x80, 0x00, 0xE8,
10576 0x00, 0x80, 0x00, 0xE8,
10577
10578 0x15, 0xC0, 0x20, 0xE9,
10579 0x15, 0xC0, 0x20, 0xE9,
10580
10581 0x15, 0xC0, 0x20, 0xE9,
10582 0x15, 0xC0, 0x20, 0xE9,
10583
10584 0x18, 0x3A, 0x41, 0xE9,
10585 0x1D, 0x32, 0x41, 0xE9,
10586
10587 0x2A, 0x40, 0x20, 0xE9,
10588 0x56, 0x3D, 0x56, 0xDF,
10589
10590 0x46, 0x37, 0x46, 0xDF,
10591 0x4E, 0x3F, 0x4E, 0xDF,
10592
10593 0x16, 0x30, 0x20, 0xE9,
10594 0x4F, 0x3F, 0x4F, 0xDF,
10595
10596 0x47, 0x37, 0x47, 0xDF,
10597 0x57, 0x3D, 0x57, 0xDF,
10598
10599 0x32, 0x32, 0x2D, 0xDF,
10600 0x22, 0x22, 0x2D, 0xDF,
10601
10602 0x12, 0x12, 0x2D, 0xDF,
10603 0x3A, 0x3A, 0x2D, 0xDF,
10604
10605 0x27, 0xCF, 0x74, 0xC2,
10606 0x37, 0xCF, 0x74, 0xC4,
10607
10608 0x0A, 0x44, 0x4C, 0xB0,
10609 0x02, 0x44, 0x54, 0xB0,
10610
10611 0x3D, 0xCF, 0x74, 0xC0,
10612 0x34, 0x37, 0x20, 0xE9,
10613
10614 0x31, 0x53, 0x2F, 0x9F,
10615 0x38, 0x27, 0x20, 0xE9,
10616
10617 0x39, 0xE5, 0x2C, 0x9F,
10618 0x3C, 0x3D, 0x20, 0xE9,
10619
10620 0x2A, 0x44, 0x4C, 0xB2,
10621 0x1A, 0x44, 0x54, 0xB2,
10622
10623 0x2E, 0x80, 0x3A, 0xEA,
10624 0x0A, 0x20,
10625 0x02, 0x20,
10626
10627 0x27, 0xCF, 0x75, 0xC0,
10628 0x2A, 0x20,
10629 0x1A, 0x20,
10630
10631 0x30, 0x50, 0x2E, 0x9F,
10632 0x32, 0x31, 0x5F, 0xE9,
10633
10634 0x38, 0x21, 0x2C, 0x9F,
10635 0x33, 0x39, 0x5F, 0xE9,
10636
10637 0x3D, 0xCF, 0x75, 0xC2,
10638 0x37, 0xCF, 0x75, 0xC4,
10639
10640 0x31, 0x53, 0x2F, 0x9F,
10641 0xA6, 0x27, 0x20, 0xE9,
10642
10643 0x39, 0xE5, 0x2C, 0x9F,
10644 0xA3, 0x3D, 0x20, 0xE9,
10645
10646 0x2A, 0x44, 0x4C, 0xB4,
10647 0x1A, 0x44, 0x54, 0xB4,
10648
10649 0x0A, 0x45, 0x4D, 0xB0,
10650 0x02, 0x45, 0x55, 0xB0,
10651
10652 0x88, 0x73, 0x5E, 0xE9,
10653 0x2A, 0x20,
10654 0x1A, 0x20,
10655
10656 0xA0, 0x37, 0x20, 0xE9,
10657 0x0A, 0x20,
10658 0x02, 0x20,
10659
10660 0x31, 0x53, 0x2F, 0x9F,
10661 0x3E, 0x30, 0x4F, 0xE9,
10662
10663 0x39, 0xE5, 0x2C, 0x9F,
10664 0x3F, 0x38, 0x4F, 0xE9,
10665
10666 0x30, 0x50, 0x2E, 0x9F,
10667 0x3A, 0x31, 0x4F, 0xE9,
10668
10669 0x38, 0x21, 0x2C, 0x9F,
10670 0x3B, 0x39, 0x4F, 0xE9,
10671
10672 0x2A, 0x45, 0x4D, 0xB2,
10673 0x1A, 0x45, 0x55, 0xB2,
10674
10675 0x0A, 0x45, 0x4D, 0xB4,
10676 0x02, 0x45, 0x55, 0xB4,
10677
10678 0x27, 0xCF, 0x74, 0xC6,
10679 0x2A, 0x20,
10680 0x1A, 0x20,
10681
10682 0xA7, 0x30, 0x4F, 0xE9,
10683 0x0A, 0x20,
10684 0x02, 0x20,
10685
10686 0x31, 0x53, 0x2F, 0x9F,
10687 0x9C, 0x27, 0x20, 0xE9,
10688
10689 0x39, 0xE5, 0x2C, 0x9F,
10690 0xA8, 0x38, 0x4F, 0xE9,
10691
10692 0x2A, 0x44, 0x4C, 0xB6,
10693 0x1A, 0x44, 0x54, 0xB6,
10694
10695 0x30, 0x50, 0x2E, 0x9F,
10696 0x36, 0x31, 0x4F, 0xE9,
10697
10698 0x38, 0x21, 0x2C, 0x9F,
10699 0x37, 0x39, 0x4F, 0xE9,
10700
10701 0x00, 0x80, 0x00, 0xE8,
10702 0x2A, 0x20,
10703 0x1A, 0x20,
10704
10705 0x2A, 0x46, 0x4E, 0xBF,
10706 0x1A, 0x46, 0x56, 0xBF,
10707
10708 0x31, 0x53, 0x2F, 0x9F,
10709 0xA4, 0x31, 0x4F, 0xE9,
10710
10711 0x39, 0xE5, 0x2C, 0x9F,
10712 0xA5, 0x39, 0x4F, 0xE9,
10713
10714 0x0A, 0x47, 0x4F, 0xBF,
10715 0x02, 0x47, 0x57, 0xBF,
10716
10717 0x31, 0x53, 0x2F, 0x9F,
10718 0xA1, 0x30, 0x4F, 0xE9,
10719
10720 0x39, 0xE5, 0x2C, 0x9F,
10721 0xA2, 0x38, 0x4F, 0xE9,
10722
10723 0x2A, 0x43, 0x4B, 0xBF,
10724 0x1A, 0x43, 0x53, 0xBF,
10725
10726 0x30, 0x50, 0x2E, 0x9F,
10727 0x9D, 0x31, 0x4F, 0xE9,
10728
10729 0x38, 0x21, 0x2C, 0x9F,
10730 0x9E, 0x39, 0x4F, 0xE9,
10731
10732 0x31, 0x53, 0x2F, 0x9F,
10733 0x80, 0x31, 0x57, 0xE9,
10734
10735 0x39, 0xE5, 0x2C, 0x9F,
10736 0x81, 0x39, 0x57, 0xE9,
10737
10738 0x37, 0x48, 0x50, 0xBD,
10739 0x8A, 0x36, 0x20, 0xE9,
10740
10741 0x86, 0x76, 0x57, 0xE9,
10742 0x8B, 0x3E, 0x20, 0xE9,
10743
10744 0x82, 0x30, 0x57, 0xE9,
10745 0x87, 0x77, 0x57, 0xE9,
10746
10747 0x83, 0x38, 0x57, 0xE9,
10748 0x35, 0x49, 0x51, 0xBD,
10749
10750 0x84, 0x31, 0x5E, 0xE9,
10751 0x30, 0x1F, 0x5F, 0xE9,
10752
10753 0x85, 0x39, 0x5E, 0xE9,
10754 0x57, 0x25, 0x20, 0xE9,
10755
10756 0x2B, 0x48, 0x20, 0xE9,
10757 0x1D, 0x37, 0xE1, 0xEA,
10758
10759 0x1E, 0x35, 0xE1, 0xEA,
10760 0x00, 0xE0,
10761 0x26, 0x77,
10762
10763 0x24, 0x49, 0x20, 0xE9,
10764 0x9D, 0xFF, 0x20, 0xEA,
10765
10766 0x16, 0x26, 0x20, 0xE9,
10767 0x57, 0x2E, 0xBF, 0xEA,
10768
10769 0x1C, 0x46, 0xA0, 0xE8,
10770 0x23, 0x4E, 0xA0, 0xE8,
10771
10772 0x2B, 0x56, 0xA0, 0xE8,
10773 0x1D, 0x47, 0xA0, 0xE8,
10774
10775 0x24, 0x4F, 0xA0, 0xE8,
10776 0x2C, 0x57, 0xA0, 0xE8,
10777
10778 0x1C, 0x00,
10779 0x23, 0x00,
10780 0x2B, 0x00,
10781 0x00, 0xE0,
10782
10783 0x1D, 0x00,
10784 0x24, 0x00,
10785 0x2C, 0x00,
10786 0x00, 0xE0,
10787
10788 0x1C, 0x65,
10789 0x23, 0x65,
10790 0x2B, 0x65,
10791 0x00, 0xE0,
10792
10793 0x1D, 0x65,
10794 0x24, 0x65,
10795 0x2C, 0x65,
10796 0x00, 0xE0,
10797
10798 0x1C, 0x23, 0x60, 0xEC,
10799 0x36, 0xD7, 0x36, 0xAD,
10800
10801 0x2B, 0x80, 0x60, 0xEC,
10802 0x1D, 0x24, 0x60, 0xEC,
10803
10804 0x3E, 0xD7, 0x3E, 0xAD,
10805 0x2C, 0x80, 0x60, 0xEC,
10806
10807 0x1C, 0x2B, 0xDE, 0xE8,
10808 0x23, 0x80, 0xDE, 0xE8,
10809
10810 0x36, 0x80, 0x36, 0xBD,
10811 0x3E, 0x80, 0x3E, 0xBD,
10812
10813 0x33, 0xD7, 0x1C, 0xBD,
10814 0x3B, 0xD7, 0x23, 0xBD,
10815
10816 0x46, 0x80, 0x46, 0xCF,
10817 0x4F, 0x80, 0x4F, 0xCF,
10818
10819 0x56, 0x33, 0x56, 0xCF,
10820 0x47, 0x3B, 0x47, 0xCF,
10821
10822 0xC5, 0xFF, 0x20, 0xEA,
10823 0x00, 0x80, 0x00, 0xE8,
10824
10825 0x4E, 0x33, 0x4E, 0xCF,
10826 0x57, 0x3B, 0x57, 0xCF,
10827
10828 0x8B, 0xFF, 0x20, 0xEA,
10829 0x57, 0xC0, 0xBF, 0xEA,
10830
10831 0x00, 0x80, 0xA0, 0xE9,
10832 0x00, 0x00, 0xD8, 0xEC,
10833
10834};
10835
10836static unsigned char warp_g400_tgzsaf[] = {
10837
10838 0x00, 0x88, 0x98, 0xE9,
10839 0x00, 0x80, 0x00, 0xE8,
10840
10841 0x00, 0x80, 0xA0, 0xE9,
10842 0x00, 0x00, 0xD8, 0xEC,
10843
10844 0xFF, 0x80, 0xC0, 0xE9,
10845 0x00, 0x80, 0x00, 0xE8,
10846
10847 0x22, 0x40, 0x48, 0xBF,
10848 0x2A, 0x40, 0x50, 0xBF,
10849
10850 0x32, 0x41, 0x49, 0xBF,
10851 0x3A, 0x41, 0x51, 0xBF,
10852
10853 0xC3, 0x6B,
10854 0xCB, 0x6B,
10855 0x00, 0x88, 0x98, 0xE9,
10856
10857 0x73, 0x7B, 0xC8, 0xEC,
10858 0x96, 0xE2,
10859 0x41, 0x04,
10860
10861 0x7B, 0x43, 0xA0, 0xE8,
10862 0x73, 0x4B, 0xA0, 0xE8,
10863
10864 0xAD, 0xEE, 0x29, 0x9F,
10865 0x00, 0xE0,
10866 0x49, 0x04,
10867
10868 0x90, 0xE2,
10869 0x51, 0x04,
10870 0x31, 0x46, 0xB1, 0xE8,
10871
10872 0x49, 0x41, 0xC0, 0xEC,
10873 0x39, 0x57, 0xB1, 0xE8,
10874
10875 0x00, 0x04,
10876 0x46, 0xE2,
10877 0x73, 0x53, 0xA0, 0xE8,
10878
10879 0x51, 0x41, 0xC0, 0xEC,
10880 0x31, 0x00,
10881 0x39, 0x00,
10882
10883 0x6E, 0x80, 0x15, 0xEA,
10884 0x08, 0x04,
10885 0x10, 0x04,
10886
10887 0x51, 0x49, 0xC0, 0xEC,
10888 0x2F, 0x41, 0x60, 0xEA,
10889
10890 0x31, 0x20,
10891 0x39, 0x20,
10892 0x1F, 0x42, 0xA0, 0xE8,
10893
10894 0x2A, 0x42, 0x4A, 0xBF,
10895 0x27, 0x4A, 0xA0, 0xE8,
10896
10897 0x1A, 0x42, 0x52, 0xBF,
10898 0x1E, 0x49, 0x60, 0xEA,
10899
10900 0x73, 0x7B, 0xC8, 0xEC,
10901 0x26, 0x51, 0x60, 0xEA,
10902
10903 0x32, 0x40, 0x48, 0xBD,
10904 0x22, 0x40, 0x50, 0xBD,
10905
10906 0x12, 0x41, 0x49, 0xBD,
10907 0x3A, 0x41, 0x51, 0xBD,
10908
10909 0xBF, 0x2F, 0x26, 0xBD,
10910 0x00, 0xE0,
10911 0x7B, 0x72,
10912
10913 0x32, 0x20,
10914 0x22, 0x20,
10915 0x12, 0x20,
10916 0x3A, 0x20,
10917
10918 0x46, 0x31, 0x46, 0xBF,
10919 0x4E, 0x31, 0x4E, 0xBF,
10920
10921 0xB3, 0xE2, 0x2D, 0x9F,
10922 0x00, 0x80, 0x00, 0xE8,
10923
10924 0x56, 0x31, 0x56, 0xBF,
10925 0x47, 0x39, 0x47, 0xBF,
10926
10927 0x4F, 0x39, 0x4F, 0xBF,
10928 0x57, 0x39, 0x57, 0xBF,
10929
10930 0x60, 0x80, 0x07, 0xEA,
10931 0x24, 0x41, 0x20, 0xE9,
10932
10933 0x42, 0x73, 0xF8, 0xEC,
10934 0x00, 0xE0,
10935 0x2D, 0x73,
10936
10937 0x33, 0x72,
10938 0x0C, 0xE3,
10939 0xA5, 0x2F, 0x1E, 0xBD,
10940
10941 0x43, 0x43, 0x2D, 0xDF,
10942 0x4B, 0x4B, 0x2D, 0xDF,
10943
10944 0xAE, 0x1E, 0x26, 0xBD,
10945 0x58, 0xE3,
10946 0x33, 0x66,
10947
10948 0x53, 0x53, 0x2D, 0xDF,
10949 0x00, 0x80, 0x00, 0xE8,
10950
10951 0xB8, 0x38, 0x33, 0xBF,
10952 0x00, 0xE0,
10953 0x59, 0xE3,
10954
10955 0x1E, 0x12, 0x41, 0xE9,
10956 0x1A, 0x22, 0x41, 0xE9,
10957
10958 0x2B, 0x40, 0x3D, 0xE9,
10959 0x3F, 0x4B, 0xA0, 0xE8,
10960
10961 0x2D, 0x73,
10962 0x30, 0x76,
10963 0x05, 0x80, 0x3D, 0xEA,
10964
10965 0x37, 0x43, 0xA0, 0xE8,
10966 0x3D, 0x53, 0xA0, 0xE8,
10967
10968 0x48, 0x70, 0xF8, 0xEC,
10969 0x2B, 0x48, 0x3C, 0xE9,
10970
10971 0x1F, 0x27, 0xBC, 0xE8,
10972 0x00, 0x80, 0x00, 0xE8,
10973
10974 0x00, 0x80, 0x00, 0xE8,
10975 0x00, 0x80, 0x00, 0xE8,
10976
10977 0x15, 0xC0, 0x20, 0xE9,
10978 0x15, 0xC0, 0x20, 0xE9,
10979
10980 0x15, 0xC0, 0x20, 0xE9,
10981 0x15, 0xC0, 0x20, 0xE9,
10982
10983 0x18, 0x3A, 0x41, 0xE9,
10984 0x1D, 0x32, 0x41, 0xE9,
10985
10986 0x2A, 0x40, 0x20, 0xE9,
10987 0x56, 0x3D, 0x56, 0xDF,
10988
10989 0x46, 0x37, 0x46, 0xDF,
10990 0x4E, 0x3F, 0x4E, 0xDF,
10991
10992 0x16, 0x30, 0x20, 0xE9,
10993 0x4F, 0x3F, 0x4F, 0xDF,
10994
10995 0x47, 0x37, 0x47, 0xDF,
10996 0x57, 0x3D, 0x57, 0xDF,
10997
10998 0x32, 0x32, 0x2D, 0xDF,
10999 0x22, 0x22, 0x2D, 0xDF,
11000
11001 0x12, 0x12, 0x2D, 0xDF,
11002 0x3A, 0x3A, 0x2D, 0xDF,
11003
11004 0x27, 0xCF, 0x74, 0xC2,
11005 0x37, 0xCF, 0x74, 0xC4,
11006
11007 0x0A, 0x44, 0x4C, 0xB0,
11008 0x02, 0x44, 0x54, 0xB0,
11009
11010 0x3D, 0xCF, 0x74, 0xC0,
11011 0x34, 0x37, 0x20, 0xE9,
11012
11013 0x31, 0x53, 0x2F, 0x9F,
11014 0x38, 0x27, 0x20, 0xE9,
11015
11016 0x39, 0xE5, 0x2C, 0x9F,
11017 0x3C, 0x3D, 0x20, 0xE9,
11018
11019 0x2A, 0x44, 0x4C, 0xB2,
11020 0x1A, 0x44, 0x54, 0xB2,
11021
11022 0x32, 0x80, 0x3A, 0xEA,
11023 0x0A, 0x20,
11024 0x02, 0x20,
11025
11026 0x27, 0xCF, 0x75, 0xC0,
11027 0x2A, 0x20,
11028 0x1A, 0x20,
11029
11030 0x30, 0x50, 0x2E, 0x9F,
11031 0x32, 0x31, 0x5F, 0xE9,
11032
11033 0x38, 0x21, 0x2C, 0x9F,
11034 0x33, 0x39, 0x5F, 0xE9,
11035
11036 0x3D, 0xCF, 0x75, 0xC2,
11037 0x37, 0xCF, 0x75, 0xC4,
11038
11039 0x31, 0x53, 0x2F, 0x9F,
11040 0xA6, 0x27, 0x20, 0xE9,
11041
11042 0x39, 0xE5, 0x2C, 0x9F,
11043 0xA3, 0x3D, 0x20, 0xE9,
11044
11045 0x2A, 0x44, 0x4C, 0xB4,
11046 0x1A, 0x44, 0x54, 0xB4,
11047
11048 0x0A, 0x45, 0x4D, 0xB0,
11049 0x02, 0x45, 0x55, 0xB0,
11050
11051 0x88, 0x73, 0x5E, 0xE9,
11052 0x2A, 0x20,
11053 0x1A, 0x20,
11054
11055 0xA0, 0x37, 0x20, 0xE9,
11056 0x0A, 0x20,
11057 0x02, 0x20,
11058
11059 0x31, 0x53, 0x2F, 0x9F,
11060 0x3E, 0x30, 0x4F, 0xE9,
11061
11062 0x39, 0xE5, 0x2C, 0x9F,
11063 0x3F, 0x38, 0x4F, 0xE9,
11064
11065 0x30, 0x50, 0x2E, 0x9F,
11066 0x3A, 0x31, 0x4F, 0xE9,
11067
11068 0x38, 0x21, 0x2C, 0x9F,
11069 0x3B, 0x39, 0x4F, 0xE9,
11070
11071 0x2A, 0x45, 0x4D, 0xB2,
11072 0x1A, 0x45, 0x55, 0xB2,
11073
11074 0x0A, 0x45, 0x4D, 0xB4,
11075 0x02, 0x45, 0x55, 0xB4,
11076
11077 0x27, 0xCF, 0x74, 0xC6,
11078 0x2A, 0x20,
11079 0x1A, 0x20,
11080
11081 0xA7, 0x30, 0x4F, 0xE9,
11082 0x0A, 0x20,
11083 0x02, 0x20,
11084
11085 0x31, 0x53, 0x2F, 0x9F,
11086 0x9C, 0x27, 0x20, 0xE9,
11087
11088 0x39, 0xE5, 0x2C, 0x9F,
11089 0xA8, 0x38, 0x4F, 0xE9,
11090
11091 0x2A, 0x44, 0x4C, 0xB6,
11092 0x1A, 0x44, 0x54, 0xB6,
11093
11094 0x30, 0x50, 0x2E, 0x9F,
11095 0x36, 0x31, 0x4F, 0xE9,
11096
11097 0x38, 0x21, 0x2C, 0x9F,
11098 0x37, 0x39, 0x4F, 0xE9,
11099
11100 0x0A, 0x45, 0x4D, 0xB6,
11101 0x02, 0x45, 0x55, 0xB6,
11102
11103 0x3D, 0xCF, 0x75, 0xC6,
11104 0x2A, 0x20,
11105 0x1A, 0x20,
11106
11107 0x2A, 0x46, 0x4E, 0xBF,
11108 0x1A, 0x46, 0x56, 0xBF,
11109
11110 0x31, 0x53, 0x2F, 0x9F,
11111 0xA4, 0x31, 0x4F, 0xE9,
11112
11113 0x39, 0xE5, 0x2C, 0x9F,
11114 0xA5, 0x39, 0x4F, 0xE9,
11115
11116 0x31, 0x3D, 0x20, 0xE9,
11117 0x0A, 0x20,
11118 0x02, 0x20,
11119
11120 0x0A, 0x47, 0x4F, 0xBF,
11121 0x02, 0x47, 0x57, 0xBF,
11122
11123 0x30, 0x50, 0x2E, 0x9F,
11124 0xA1, 0x30, 0x4F, 0xE9,
11125
11126 0x38, 0x21, 0x2C, 0x9F,
11127 0xA2, 0x38, 0x4F, 0xE9,
11128
11129 0x31, 0x53, 0x2F, 0x9F,
11130 0x9D, 0x31, 0x4F, 0xE9,
11131
11132 0x39, 0xE5, 0x2C, 0x9F,
11133 0x9E, 0x39, 0x4F, 0xE9,
11134
11135 0x2A, 0x43, 0x4B, 0xBF,
11136 0x1A, 0x43, 0x53, 0xBF,
11137
11138 0x30, 0x50, 0x2E, 0x9F,
11139 0x35, 0x30, 0x4F, 0xE9,
11140
11141 0x38, 0x21, 0x2C, 0x9F,
11142 0x39, 0x38, 0x4F, 0xE9,
11143
11144 0x31, 0x53, 0x2F, 0x9F,
11145 0x80, 0x31, 0x57, 0xE9,
11146
11147 0x39, 0xE5, 0x2C, 0x9F,
11148 0x81, 0x39, 0x57, 0xE9,
11149
11150 0x37, 0x48, 0x50, 0xBD,
11151 0x8A, 0x36, 0x20, 0xE9,
11152
11153 0x86, 0x76, 0x57, 0xE9,
11154 0x8B, 0x3E, 0x20, 0xE9,
11155
11156 0x82, 0x30, 0x57, 0xE9,
11157 0x87, 0x77, 0x57, 0xE9,
11158
11159 0x83, 0x38, 0x57, 0xE9,
11160 0x35, 0x49, 0x51, 0xBD,
11161
11162 0x84, 0x31, 0x5E, 0xE9,
11163 0x30, 0x1F, 0x5F, 0xE9,
11164
11165 0x85, 0x39, 0x5E, 0xE9,
11166 0x57, 0x25, 0x20, 0xE9,
11167
11168 0x2B, 0x48, 0x20, 0xE9,
11169 0x1D, 0x37, 0xE1, 0xEA,
11170
11171 0x1E, 0x35, 0xE1, 0xEA,
11172 0x00, 0xE0,
11173 0x26, 0x77,
11174
11175 0x24, 0x49, 0x20, 0xE9,
11176 0x99, 0xFF, 0x20, 0xEA,
11177
11178 0x16, 0x26, 0x20, 0xE9,
11179 0x57, 0x2E, 0xBF, 0xEA,
11180
11181 0x1C, 0x46, 0xA0, 0xE8,
11182 0x23, 0x4E, 0xA0, 0xE8,
11183
11184 0x2B, 0x56, 0xA0, 0xE8,
11185 0x1D, 0x47, 0xA0, 0xE8,
11186
11187 0x24, 0x4F, 0xA0, 0xE8,
11188 0x2C, 0x57, 0xA0, 0xE8,
11189
11190 0x1C, 0x00,
11191 0x23, 0x00,
11192 0x2B, 0x00,
11193 0x00, 0xE0,
11194
11195 0x1D, 0x00,
11196 0x24, 0x00,
11197 0x2C, 0x00,
11198 0x00, 0xE0,
11199
11200 0x1C, 0x65,
11201 0x23, 0x65,
11202 0x2B, 0x65,
11203 0x00, 0xE0,
11204
11205 0x1D, 0x65,
11206 0x24, 0x65,
11207 0x2C, 0x65,
11208 0x00, 0xE0,
11209
11210 0x1C, 0x23, 0x60, 0xEC,
11211 0x36, 0xD7, 0x36, 0xAD,
11212
11213 0x2B, 0x80, 0x60, 0xEC,
11214 0x1D, 0x24, 0x60, 0xEC,
11215
11216 0x3E, 0xD7, 0x3E, 0xAD,
11217 0x2C, 0x80, 0x60, 0xEC,
11218
11219 0x1C, 0x2B, 0xDE, 0xE8,
11220 0x23, 0x80, 0xDE, 0xE8,
11221
11222 0x36, 0x80, 0x36, 0xBD,
11223 0x3E, 0x80, 0x3E, 0xBD,
11224
11225 0x33, 0xD7, 0x1C, 0xBD,
11226 0x3B, 0xD7, 0x23, 0xBD,
11227
11228 0x46, 0x80, 0x46, 0xCF,
11229 0x4F, 0x80, 0x4F, 0xCF,
11230
11231 0x56, 0x33, 0x56, 0xCF,
11232 0x47, 0x3B, 0x47, 0xCF,
11233
11234 0xC1, 0xFF, 0x20, 0xEA,
11235 0x00, 0x80, 0x00, 0xE8,
11236
11237 0x4E, 0x33, 0x4E, 0xCF,
11238 0x57, 0x3B, 0x57, 0xCF,
11239
11240 0x87, 0xFF, 0x20, 0xEA,
11241 0x57, 0xC0, 0xBF, 0xEA,
11242
11243 0x00, 0x80, 0xA0, 0xE9,
11244 0x00, 0x00, 0xD8, 0xEC,
11245
11246};
11247
11248static unsigned char warp_g400_tgzsf[] = {
11249
11250 0x00, 0x88, 0x98, 0xE9,
11251 0x00, 0x80, 0x00, 0xE8,
11252
11253 0x00, 0x80, 0xA0, 0xE9,
11254 0x00, 0x00, 0xD8, 0xEC,
11255
11256 0xFF, 0x80, 0xC0, 0xE9,
11257 0x00, 0x80, 0x00, 0xE8,
11258
11259 0x22, 0x40, 0x48, 0xBF,
11260 0x2A, 0x40, 0x50, 0xBF,
11261
11262 0x32, 0x41, 0x49, 0xBF,
11263 0x3A, 0x41, 0x51, 0xBF,
11264
11265 0xC3, 0x6B,
11266 0xCB, 0x6B,
11267 0x00, 0x88, 0x98, 0xE9,
11268
11269 0x73, 0x7B, 0xC8, 0xEC,
11270 0x96, 0xE2,
11271 0x41, 0x04,
11272
11273 0x7B, 0x43, 0xA0, 0xE8,
11274 0x73, 0x4B, 0xA0, 0xE8,
11275
11276 0xAD, 0xEE, 0x29, 0x9F,
11277 0x00, 0xE0,
11278 0x49, 0x04,
11279
11280 0x90, 0xE2,
11281 0x51, 0x04,
11282 0x31, 0x46, 0xB1, 0xE8,
11283
11284 0x49, 0x41, 0xC0, 0xEC,
11285 0x39, 0x57, 0xB1, 0xE8,
11286
11287 0x00, 0x04,
11288 0x46, 0xE2,
11289 0x73, 0x53, 0xA0, 0xE8,
11290
11291 0x51, 0x41, 0xC0, 0xEC,
11292 0x31, 0x00,
11293 0x39, 0x00,
11294
11295 0x6A, 0x80, 0x15, 0xEA,
11296 0x08, 0x04,
11297 0x10, 0x04,
11298
11299 0x51, 0x49, 0xC0, 0xEC,
11300 0x2F, 0x41, 0x60, 0xEA,
11301
11302 0x31, 0x20,
11303 0x39, 0x20,
11304 0x1F, 0x42, 0xA0, 0xE8,
11305
11306 0x2A, 0x42, 0x4A, 0xBF,
11307 0x27, 0x4A, 0xA0, 0xE8,
11308
11309 0x1A, 0x42, 0x52, 0xBF,
11310 0x1E, 0x49, 0x60, 0xEA,
11311
11312 0x73, 0x7B, 0xC8, 0xEC,
11313 0x26, 0x51, 0x60, 0xEA,
11314
11315 0x32, 0x40, 0x48, 0xBD,
11316 0x22, 0x40, 0x50, 0xBD,
11317
11318 0x12, 0x41, 0x49, 0xBD,
11319 0x3A, 0x41, 0x51, 0xBD,
11320
11321 0xBF, 0x2F, 0x26, 0xBD,
11322 0x00, 0xE0,
11323 0x7B, 0x72,
11324
11325 0x32, 0x20,
11326 0x22, 0x20,
11327 0x12, 0x20,
11328 0x3A, 0x20,
11329
11330 0x46, 0x31, 0x46, 0xBF,
11331 0x4E, 0x31, 0x4E, 0xBF,
11332
11333 0xB3, 0xE2, 0x2D, 0x9F,
11334 0x00, 0x80, 0x00, 0xE8,
11335
11336 0x56, 0x31, 0x56, 0xBF,
11337 0x47, 0x39, 0x47, 0xBF,
11338
11339 0x4F, 0x39, 0x4F, 0xBF,
11340 0x57, 0x39, 0x57, 0xBF,
11341
11342 0x5C, 0x80, 0x07, 0xEA,
11343 0x24, 0x41, 0x20, 0xE9,
11344
11345 0x42, 0x73, 0xF8, 0xEC,
11346 0x00, 0xE0,
11347 0x2D, 0x73,
11348
11349 0x33, 0x72,
11350 0x0C, 0xE3,
11351 0xA5, 0x2F, 0x1E, 0xBD,
11352
11353 0x43, 0x43, 0x2D, 0xDF,
11354 0x4B, 0x4B, 0x2D, 0xDF,
11355
11356 0xAE, 0x1E, 0x26, 0xBD,
11357 0x58, 0xE3,
11358 0x33, 0x66,
11359
11360 0x53, 0x53, 0x2D, 0xDF,
11361 0x00, 0x80, 0x00, 0xE8,
11362
11363 0xB8, 0x38, 0x33, 0xBF,
11364 0x00, 0xE0,
11365 0x59, 0xE3,
11366
11367 0x1E, 0x12, 0x41, 0xE9,
11368 0x1A, 0x22, 0x41, 0xE9,
11369
11370 0x2B, 0x40, 0x3D, 0xE9,
11371 0x3F, 0x4B, 0xA0, 0xE8,
11372
11373 0x2D, 0x73,
11374 0x30, 0x76,
11375 0x05, 0x80, 0x3D, 0xEA,
11376
11377 0x37, 0x43, 0xA0, 0xE8,
11378 0x3D, 0x53, 0xA0, 0xE8,
11379
11380 0x48, 0x70, 0xF8, 0xEC,
11381 0x2B, 0x48, 0x3C, 0xE9,
11382
11383 0x1F, 0x27, 0xBC, 0xE8,
11384 0x00, 0x80, 0x00, 0xE8,
11385
11386 0x00, 0x80, 0x00, 0xE8,
11387 0x00, 0x80, 0x00, 0xE8,
11388
11389 0x15, 0xC0, 0x20, 0xE9,
11390 0x15, 0xC0, 0x20, 0xE9,
11391
11392 0x15, 0xC0, 0x20, 0xE9,
11393 0x15, 0xC0, 0x20, 0xE9,
11394
11395 0x18, 0x3A, 0x41, 0xE9,
11396 0x1D, 0x32, 0x41, 0xE9,
11397
11398 0x2A, 0x40, 0x20, 0xE9,
11399 0x56, 0x3D, 0x56, 0xDF,
11400
11401 0x46, 0x37, 0x46, 0xDF,
11402 0x4E, 0x3F, 0x4E, 0xDF,
11403
11404 0x16, 0x30, 0x20, 0xE9,
11405 0x4F, 0x3F, 0x4F, 0xDF,
11406
11407 0x47, 0x37, 0x47, 0xDF,
11408 0x57, 0x3D, 0x57, 0xDF,
11409
11410 0x32, 0x32, 0x2D, 0xDF,
11411 0x22, 0x22, 0x2D, 0xDF,
11412
11413 0x12, 0x12, 0x2D, 0xDF,
11414 0x3A, 0x3A, 0x2D, 0xDF,
11415
11416 0x27, 0xCF, 0x74, 0xC2,
11417 0x37, 0xCF, 0x74, 0xC4,
11418
11419 0x0A, 0x44, 0x4C, 0xB0,
11420 0x02, 0x44, 0x54, 0xB0,
11421
11422 0x3D, 0xCF, 0x74, 0xC0,
11423 0x34, 0x37, 0x20, 0xE9,
11424
11425 0x31, 0x53, 0x2F, 0x9F,
11426 0x38, 0x27, 0x20, 0xE9,
11427
11428 0x39, 0xE5, 0x2C, 0x9F,
11429 0x3C, 0x3D, 0x20, 0xE9,
11430
11431 0x2A, 0x44, 0x4C, 0xB2,
11432 0x1A, 0x44, 0x54, 0xB2,
11433
11434 0x2E, 0x80, 0x3A, 0xEA,
11435 0x0A, 0x20,
11436 0x02, 0x20,
11437
11438 0x27, 0xCF, 0x75, 0xC0,
11439 0x2A, 0x20,
11440 0x1A, 0x20,
11441
11442 0x30, 0x50, 0x2E, 0x9F,
11443 0x32, 0x31, 0x5F, 0xE9,
11444
11445 0x38, 0x21, 0x2C, 0x9F,
11446 0x33, 0x39, 0x5F, 0xE9,
11447
11448 0x3D, 0xCF, 0x75, 0xC2,
11449 0x37, 0xCF, 0x75, 0xC4,
11450
11451 0x31, 0x53, 0x2F, 0x9F,
11452 0xA6, 0x27, 0x20, 0xE9,
11453
11454 0x39, 0xE5, 0x2C, 0x9F,
11455 0xA3, 0x3D, 0x20, 0xE9,
11456
11457 0x2A, 0x44, 0x4C, 0xB4,
11458 0x1A, 0x44, 0x54, 0xB4,
11459
11460 0x0A, 0x45, 0x4D, 0xB0,
11461 0x02, 0x45, 0x55, 0xB0,
11462
11463 0x88, 0x73, 0x5E, 0xE9,
11464 0x2A, 0x20,
11465 0x1A, 0x20,
11466
11467 0xA0, 0x37, 0x20, 0xE9,
11468 0x0A, 0x20,
11469 0x02, 0x20,
11470
11471 0x31, 0x53, 0x2F, 0x9F,
11472 0x3E, 0x30, 0x4F, 0xE9,
11473
11474 0x39, 0xE5, 0x2C, 0x9F,
11475 0x3F, 0x38, 0x4F, 0xE9,
11476
11477 0x30, 0x50, 0x2E, 0x9F,
11478 0x3A, 0x31, 0x4F, 0xE9,
11479
11480 0x38, 0x21, 0x2C, 0x9F,
11481 0x3B, 0x39, 0x4F, 0xE9,
11482
11483 0x2A, 0x45, 0x4D, 0xB2,
11484 0x1A, 0x45, 0x55, 0xB2,
11485
11486 0x0A, 0x45, 0x4D, 0xB4,
11487 0x02, 0x45, 0x55, 0xB4,
11488
11489 0x27, 0xCF, 0x75, 0xC6,
11490 0x2A, 0x20,
11491 0x1A, 0x20,
11492
11493 0xA7, 0x30, 0x4F, 0xE9,
11494 0x0A, 0x20,
11495 0x02, 0x20,
11496
11497 0x31, 0x53, 0x2F, 0x9F,
11498 0x31, 0x27, 0x20, 0xE9,
11499
11500 0x39, 0xE5, 0x2C, 0x9F,
11501 0xA8, 0x38, 0x4F, 0xE9,
11502
11503 0x2A, 0x45, 0x4D, 0xB6,
11504 0x1A, 0x45, 0x55, 0xB6,
11505
11506 0x30, 0x50, 0x2E, 0x9F,
11507 0x36, 0x31, 0x4F, 0xE9,
11508
11509 0x38, 0x21, 0x2C, 0x9F,
11510 0x37, 0x39, 0x4F, 0xE9,
11511
11512 0x00, 0x80, 0x00, 0xE8,
11513 0x2A, 0x20,
11514 0x1A, 0x20,
11515
11516 0x2A, 0x46, 0x4E, 0xBF,
11517 0x1A, 0x46, 0x56, 0xBF,
11518
11519 0x31, 0x53, 0x2F, 0x9F,
11520 0xA4, 0x31, 0x4F, 0xE9,
11521
11522 0x39, 0xE5, 0x2C, 0x9F,
11523 0xA5, 0x39, 0x4F, 0xE9,
11524
11525 0x0A, 0x47, 0x4F, 0xBF,
11526 0x02, 0x47, 0x57, 0xBF,
11527
11528 0x31, 0x53, 0x2F, 0x9F,
11529 0xA1, 0x30, 0x4F, 0xE9,
11530
11531 0x39, 0xE5, 0x2C, 0x9F,
11532 0xA2, 0x38, 0x4F, 0xE9,
11533
11534 0x2A, 0x43, 0x4B, 0xBF,
11535 0x1A, 0x43, 0x53, 0xBF,
11536
11537 0x30, 0x50, 0x2E, 0x9F,
11538 0x35, 0x31, 0x4F, 0xE9,
11539
11540 0x38, 0x21, 0x2C, 0x9F,
11541 0x39, 0x39, 0x4F, 0xE9,
11542
11543 0x31, 0x53, 0x2F, 0x9F,
11544 0x80, 0x31, 0x57, 0xE9,
11545
11546 0x39, 0xE5, 0x2C, 0x9F,
11547 0x81, 0x39, 0x57, 0xE9,
11548
11549 0x37, 0x48, 0x50, 0xBD,
11550 0x8A, 0x36, 0x20, 0xE9,
11551
11552 0x86, 0x76, 0x57, 0xE9,
11553 0x8B, 0x3E, 0x20, 0xE9,
11554
11555 0x82, 0x30, 0x57, 0xE9,
11556 0x87, 0x77, 0x57, 0xE9,
11557
11558 0x83, 0x38, 0x57, 0xE9,
11559 0x35, 0x49, 0x51, 0xBD,
11560
11561 0x84, 0x31, 0x5E, 0xE9,
11562 0x30, 0x1F, 0x5F, 0xE9,
11563
11564 0x85, 0x39, 0x5E, 0xE9,
11565 0x57, 0x25, 0x20, 0xE9,
11566
11567 0x2B, 0x48, 0x20, 0xE9,
11568 0x1D, 0x37, 0xE1, 0xEA,
11569
11570 0x1E, 0x35, 0xE1, 0xEA,
11571 0x00, 0xE0,
11572 0x26, 0x77,
11573
11574 0x24, 0x49, 0x20, 0xE9,
11575 0x9D, 0xFF, 0x20, 0xEA,
11576
11577 0x16, 0x26, 0x20, 0xE9,
11578 0x57, 0x2E, 0xBF, 0xEA,
11579
11580 0x1C, 0x46, 0xA0, 0xE8,
11581 0x23, 0x4E, 0xA0, 0xE8,
11582
11583 0x2B, 0x56, 0xA0, 0xE8,
11584 0x1D, 0x47, 0xA0, 0xE8,
11585
11586 0x24, 0x4F, 0xA0, 0xE8,
11587 0x2C, 0x57, 0xA0, 0xE8,
11588
11589 0x1C, 0x00,
11590 0x23, 0x00,
11591 0x2B, 0x00,
11592 0x00, 0xE0,
11593
11594 0x1D, 0x00,
11595 0x24, 0x00,
11596 0x2C, 0x00,
11597 0x00, 0xE0,
11598
11599 0x1C, 0x65,
11600 0x23, 0x65,
11601 0x2B, 0x65,
11602 0x00, 0xE0,
11603
11604 0x1D, 0x65,
11605 0x24, 0x65,
11606 0x2C, 0x65,
11607 0x00, 0xE0,
11608
11609 0x1C, 0x23, 0x60, 0xEC,
11610 0x36, 0xD7, 0x36, 0xAD,
11611
11612 0x2B, 0x80, 0x60, 0xEC,
11613 0x1D, 0x24, 0x60, 0xEC,
11614
11615 0x3E, 0xD7, 0x3E, 0xAD,
11616 0x2C, 0x80, 0x60, 0xEC,
11617
11618 0x1C, 0x2B, 0xDE, 0xE8,
11619 0x23, 0x80, 0xDE, 0xE8,
11620
11621 0x36, 0x80, 0x36, 0xBD,
11622 0x3E, 0x80, 0x3E, 0xBD,
11623
11624 0x33, 0xD7, 0x1C, 0xBD,
11625 0x3B, 0xD7, 0x23, 0xBD,
11626
11627 0x46, 0x80, 0x46, 0xCF,
11628 0x4F, 0x80, 0x4F, 0xCF,
11629
11630 0x56, 0x33, 0x56, 0xCF,
11631 0x47, 0x3B, 0x47, 0xCF,
11632
11633 0xC5, 0xFF, 0x20, 0xEA,
11634 0x00, 0x80, 0x00, 0xE8,
11635
11636 0x4E, 0x33, 0x4E, 0xCF,
11637 0x57, 0x3B, 0x57, 0xCF,
11638
11639 0x8B, 0xFF, 0x20, 0xEA,
11640 0x57, 0xC0, 0xBF, 0xEA,
11641
11642 0x00, 0x80, 0xA0, 0xE9,
11643 0x00, 0x00, 0xD8, 0xEC,
11644
11645};
diff --git a/drivers/char/drm/mga_warp.c b/drivers/char/drm/mga_warp.c
deleted file mode 100644
index 651b93c8ab5d..000000000000
--- a/drivers/char/drm/mga_warp.c
+++ /dev/null
@@ -1,193 +0,0 @@
1/* mga_warp.c -- Matrox G200/G400 WARP engine management -*- linux-c -*-
2 * Created: Thu Jan 11 21:29:32 2001 by gareth@valinux.com
3 *
4 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
5 * All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the next
15 * paragraph) shall be included in all copies or substantial portions of the
16 * Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
22 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24 * OTHER DEALINGS IN THE SOFTWARE.
25 *
26 * Authors:
27 * Gareth Hughes <gareth@valinux.com>
28 */
29
30#include "drmP.h"
31#include "drm.h"
32#include "mga_drm.h"
33#include "mga_drv.h"
34#include "mga_ucode.h"
35
36#define MGA_WARP_CODE_ALIGN 256 /* in bytes */
37
38#define WARP_UCODE_SIZE( which ) \
39 ((sizeof(which) / MGA_WARP_CODE_ALIGN + 1) * MGA_WARP_CODE_ALIGN)
40
41#define WARP_UCODE_INSTALL( which, where ) \
42do { \
43 DRM_DEBUG( " pcbase = 0x%08lx vcbase = %p\n", pcbase, vcbase );\
44 dev_priv->warp_pipe_phys[where] = pcbase; \
45 memcpy( vcbase, which, sizeof(which) ); \
46 pcbase += WARP_UCODE_SIZE( which ); \
47 vcbase += WARP_UCODE_SIZE( which ); \
48} while (0)
49
50static const unsigned int mga_warp_g400_microcode_size =
51 (WARP_UCODE_SIZE(warp_g400_tgz) +
52 WARP_UCODE_SIZE(warp_g400_tgza) +
53 WARP_UCODE_SIZE(warp_g400_tgzaf) +
54 WARP_UCODE_SIZE(warp_g400_tgzf) +
55 WARP_UCODE_SIZE(warp_g400_tgzs) +
56 WARP_UCODE_SIZE(warp_g400_tgzsa) +
57 WARP_UCODE_SIZE(warp_g400_tgzsaf) +
58 WARP_UCODE_SIZE(warp_g400_tgzsf) +
59 WARP_UCODE_SIZE(warp_g400_t2gz) +
60 WARP_UCODE_SIZE(warp_g400_t2gza) +
61 WARP_UCODE_SIZE(warp_g400_t2gzaf) +
62 WARP_UCODE_SIZE(warp_g400_t2gzf) +
63 WARP_UCODE_SIZE(warp_g400_t2gzs) +
64 WARP_UCODE_SIZE(warp_g400_t2gzsa) +
65 WARP_UCODE_SIZE(warp_g400_t2gzsaf) + WARP_UCODE_SIZE(warp_g400_t2gzsf));
66
67static const unsigned int mga_warp_g200_microcode_size =
68 (WARP_UCODE_SIZE(warp_g200_tgz) +
69 WARP_UCODE_SIZE(warp_g200_tgza) +
70 WARP_UCODE_SIZE(warp_g200_tgzaf) +
71 WARP_UCODE_SIZE(warp_g200_tgzf) +
72 WARP_UCODE_SIZE(warp_g200_tgzs) +
73 WARP_UCODE_SIZE(warp_g200_tgzsa) +
74 WARP_UCODE_SIZE(warp_g200_tgzsaf) + WARP_UCODE_SIZE(warp_g200_tgzsf));
75
76unsigned int mga_warp_microcode_size(const drm_mga_private_t * dev_priv)
77{
78 switch (dev_priv->chipset) {
79 case MGA_CARD_TYPE_G400:
80 case MGA_CARD_TYPE_G550:
81 return PAGE_ALIGN(mga_warp_g400_microcode_size);
82 case MGA_CARD_TYPE_G200:
83 return PAGE_ALIGN(mga_warp_g200_microcode_size);
84 default:
85 return 0;
86 }
87}
88
89static int mga_warp_install_g400_microcode(drm_mga_private_t * dev_priv)
90{
91 unsigned char *vcbase = dev_priv->warp->handle;
92 unsigned long pcbase = dev_priv->warp->offset;
93
94 memset(dev_priv->warp_pipe_phys, 0, sizeof(dev_priv->warp_pipe_phys));
95
96 WARP_UCODE_INSTALL(warp_g400_tgz, MGA_WARP_TGZ);
97 WARP_UCODE_INSTALL(warp_g400_tgzf, MGA_WARP_TGZF);
98 WARP_UCODE_INSTALL(warp_g400_tgza, MGA_WARP_TGZA);
99 WARP_UCODE_INSTALL(warp_g400_tgzaf, MGA_WARP_TGZAF);
100 WARP_UCODE_INSTALL(warp_g400_tgzs, MGA_WARP_TGZS);
101 WARP_UCODE_INSTALL(warp_g400_tgzsf, MGA_WARP_TGZSF);
102 WARP_UCODE_INSTALL(warp_g400_tgzsa, MGA_WARP_TGZSA);
103 WARP_UCODE_INSTALL(warp_g400_tgzsaf, MGA_WARP_TGZSAF);
104
105 WARP_UCODE_INSTALL(warp_g400_t2gz, MGA_WARP_T2GZ);
106 WARP_UCODE_INSTALL(warp_g400_t2gzf, MGA_WARP_T2GZF);
107 WARP_UCODE_INSTALL(warp_g400_t2gza, MGA_WARP_T2GZA);
108 WARP_UCODE_INSTALL(warp_g400_t2gzaf, MGA_WARP_T2GZAF);
109 WARP_UCODE_INSTALL(warp_g400_t2gzs, MGA_WARP_T2GZS);
110 WARP_UCODE_INSTALL(warp_g400_t2gzsf, MGA_WARP_T2GZSF);
111 WARP_UCODE_INSTALL(warp_g400_t2gzsa, MGA_WARP_T2GZSA);
112 WARP_UCODE_INSTALL(warp_g400_t2gzsaf, MGA_WARP_T2GZSAF);
113
114 return 0;
115}
116
117static int mga_warp_install_g200_microcode(drm_mga_private_t * dev_priv)
118{
119 unsigned char *vcbase = dev_priv->warp->handle;
120 unsigned long pcbase = dev_priv->warp->offset;
121
122 memset(dev_priv->warp_pipe_phys, 0, sizeof(dev_priv->warp_pipe_phys));
123
124 WARP_UCODE_INSTALL(warp_g200_tgz, MGA_WARP_TGZ);
125 WARP_UCODE_INSTALL(warp_g200_tgzf, MGA_WARP_TGZF);
126 WARP_UCODE_INSTALL(warp_g200_tgza, MGA_WARP_TGZA);
127 WARP_UCODE_INSTALL(warp_g200_tgzaf, MGA_WARP_TGZAF);
128 WARP_UCODE_INSTALL(warp_g200_tgzs, MGA_WARP_TGZS);
129 WARP_UCODE_INSTALL(warp_g200_tgzsf, MGA_WARP_TGZSF);
130 WARP_UCODE_INSTALL(warp_g200_tgzsa, MGA_WARP_TGZSA);
131 WARP_UCODE_INSTALL(warp_g200_tgzsaf, MGA_WARP_TGZSAF);
132
133 return 0;
134}
135
136int mga_warp_install_microcode(drm_mga_private_t * dev_priv)
137{
138 const unsigned int size = mga_warp_microcode_size(dev_priv);
139
140 DRM_DEBUG("MGA ucode size = %d bytes\n", size);
141 if (size > dev_priv->warp->size) {
142 DRM_ERROR("microcode too large! (%u > %lu)\n",
143 size, dev_priv->warp->size);
144 return -ENOMEM;
145 }
146
147 switch (dev_priv->chipset) {
148 case MGA_CARD_TYPE_G400:
149 case MGA_CARD_TYPE_G550:
150 return mga_warp_install_g400_microcode(dev_priv);
151 case MGA_CARD_TYPE_G200:
152 return mga_warp_install_g200_microcode(dev_priv);
153 default:
154 return -EINVAL;
155 }
156}
157
158#define WMISC_EXPECTED (MGA_WUCODECACHE_ENABLE | MGA_WMASTER_ENABLE)
159
160int mga_warp_init(drm_mga_private_t * dev_priv)
161{
162 u32 wmisc;
163
164 /* FIXME: Get rid of these damned magic numbers...
165 */
166 switch (dev_priv->chipset) {
167 case MGA_CARD_TYPE_G400:
168 case MGA_CARD_TYPE_G550:
169 MGA_WRITE(MGA_WIADDR2, MGA_WMODE_SUSPEND);
170 MGA_WRITE(MGA_WGETMSB, 0x00000E00);
171 MGA_WRITE(MGA_WVRTXSZ, 0x00001807);
172 MGA_WRITE(MGA_WACCEPTSEQ, 0x18000000);
173 break;
174 case MGA_CARD_TYPE_G200:
175 MGA_WRITE(MGA_WIADDR, MGA_WMODE_SUSPEND);
176 MGA_WRITE(MGA_WGETMSB, 0x1606);
177 MGA_WRITE(MGA_WVRTXSZ, 7);
178 break;
179 default:
180 return -EINVAL;
181 }
182
183 MGA_WRITE(MGA_WMISC, (MGA_WUCODECACHE_ENABLE |
184 MGA_WMASTER_ENABLE | MGA_WCACHEFLUSH_ENABLE));
185 wmisc = MGA_READ(MGA_WMISC);
186 if (wmisc != WMISC_EXPECTED) {
187 DRM_ERROR("WARP engine config failed! 0x%x != 0x%x\n",
188 wmisc, WMISC_EXPECTED);
189 return -EINVAL;
190 }
191
192 return 0;
193}
diff --git a/drivers/char/drm/r128_cce.c b/drivers/char/drm/r128_cce.c
deleted file mode 100644
index c31afbde62e7..000000000000
--- a/drivers/char/drm/r128_cce.c
+++ /dev/null
@@ -1,935 +0,0 @@
1/* r128_cce.c -- ATI Rage 128 driver -*- linux-c -*-
2 * Created: Wed Apr 5 19:24:19 2000 by kevin@precisioninsight.com
3 */
4/*
5 * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas.
6 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
7 * All Rights Reserved.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice (including the next
17 * paragraph) shall be included in all copies or substantial portions of the
18 * Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
24 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
25 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 * DEALINGS IN THE SOFTWARE.
27 *
28 * Authors:
29 * Gareth Hughes <gareth@valinux.com>
30 */
31
32#include "drmP.h"
33#include "drm.h"
34#include "r128_drm.h"
35#include "r128_drv.h"
36
37#define R128_FIFO_DEBUG 0
38
39/* CCE microcode (from ATI) */
40static u32 r128_cce_microcode[] = {
41 0, 276838400, 0, 268449792, 2, 142, 2, 145, 0, 1076765731, 0,
42 1617039951, 0, 774592877, 0, 1987540286, 0, 2307490946U, 0,
43 599558925, 0, 589505315, 0, 596487092, 0, 589505315, 1,
44 11544576, 1, 206848, 1, 311296, 1, 198656, 2, 912273422, 11,
45 262144, 0, 0, 1, 33559837, 1, 7438, 1, 14809, 1, 6615, 12, 28,
46 1, 6614, 12, 28, 2, 23, 11, 18874368, 0, 16790922, 1, 409600, 9,
47 30, 1, 147854772, 16, 420483072, 3, 8192, 0, 10240, 1, 198656,
48 1, 15630, 1, 51200, 10, 34858, 9, 42, 1, 33559823, 2, 10276, 1,
49 15717, 1, 15718, 2, 43, 1, 15936948, 1, 570480831, 1, 14715071,
50 12, 322123831, 1, 33953125, 12, 55, 1, 33559908, 1, 15718, 2,
51 46, 4, 2099258, 1, 526336, 1, 442623, 4, 4194365, 1, 509952, 1,
52 459007, 3, 0, 12, 92, 2, 46, 12, 176, 1, 15734, 1, 206848, 1,
53 18432, 1, 133120, 1, 100670734, 1, 149504, 1, 165888, 1,
54 15975928, 1, 1048576, 6, 3145806, 1, 15715, 16, 2150645232U, 2,
55 268449859, 2, 10307, 12, 176, 1, 15734, 1, 15735, 1, 15630, 1,
56 15631, 1, 5253120, 6, 3145810, 16, 2150645232U, 1, 15864, 2, 82,
57 1, 343310, 1, 1064207, 2, 3145813, 1, 15728, 1, 7817, 1, 15729,
58 3, 15730, 12, 92, 2, 98, 1, 16168, 1, 16167, 1, 16002, 1, 16008,
59 1, 15974, 1, 15975, 1, 15990, 1, 15976, 1, 15977, 1, 15980, 0,
60 15981, 1, 10240, 1, 5253120, 1, 15720, 1, 198656, 6, 110, 1,
61 180224, 1, 103824738, 2, 112, 2, 3145839, 0, 536885440, 1,
62 114880, 14, 125, 12, 206975, 1, 33559995, 12, 198784, 0,
63 33570236, 1, 15803, 0, 15804, 3, 294912, 1, 294912, 3, 442370,
64 1, 11544576, 0, 811612160, 1, 12593152, 1, 11536384, 1,
65 14024704, 7, 310382726, 0, 10240, 1, 14796, 1, 14797, 1, 14793,
66 1, 14794, 0, 14795, 1, 268679168, 1, 9437184, 1, 268449792, 1,
67 198656, 1, 9452827, 1, 1075854602, 1, 1075854603, 1, 557056, 1,
68 114880, 14, 159, 12, 198784, 1, 1109409213, 12, 198783, 1,
69 1107312059, 12, 198784, 1, 1109409212, 2, 162, 1, 1075854781, 1,
70 1073757627, 1, 1075854780, 1, 540672, 1, 10485760, 6, 3145894,
71 16, 274741248, 9, 168, 3, 4194304, 3, 4209949, 0, 0, 0, 256, 14,
72 174, 1, 114857, 1, 33560007, 12, 176, 0, 10240, 1, 114858, 1,
73 33560018, 1, 114857, 3, 33560007, 1, 16008, 1, 114874, 1,
74 33560360, 1, 114875, 1, 33560154, 0, 15963, 0, 256, 0, 4096, 1,
75 409611, 9, 188, 0, 10240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
76 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
77 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
78 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
79 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
80 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
81 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
82};
83
84static int R128_READ_PLL(struct drm_device * dev, int addr)
85{
86 drm_r128_private_t *dev_priv = dev->dev_private;
87
88 R128_WRITE8(R128_CLOCK_CNTL_INDEX, addr & 0x1f);
89 return R128_READ(R128_CLOCK_CNTL_DATA);
90}
91
92#if R128_FIFO_DEBUG
93static void r128_status(drm_r128_private_t * dev_priv)
94{
95 printk("GUI_STAT = 0x%08x\n",
96 (unsigned int)R128_READ(R128_GUI_STAT));
97 printk("PM4_STAT = 0x%08x\n",
98 (unsigned int)R128_READ(R128_PM4_STAT));
99 printk("PM4_BUFFER_DL_WPTR = 0x%08x\n",
100 (unsigned int)R128_READ(R128_PM4_BUFFER_DL_WPTR));
101 printk("PM4_BUFFER_DL_RPTR = 0x%08x\n",
102 (unsigned int)R128_READ(R128_PM4_BUFFER_DL_RPTR));
103 printk("PM4_MICRO_CNTL = 0x%08x\n",
104 (unsigned int)R128_READ(R128_PM4_MICRO_CNTL));
105 printk("PM4_BUFFER_CNTL = 0x%08x\n",
106 (unsigned int)R128_READ(R128_PM4_BUFFER_CNTL));
107}
108#endif
109
110/* ================================================================
111 * Engine, FIFO control
112 */
113
114static int r128_do_pixcache_flush(drm_r128_private_t * dev_priv)
115{
116 u32 tmp;
117 int i;
118
119 tmp = R128_READ(R128_PC_NGUI_CTLSTAT) | R128_PC_FLUSH_ALL;
120 R128_WRITE(R128_PC_NGUI_CTLSTAT, tmp);
121
122 for (i = 0; i < dev_priv->usec_timeout; i++) {
123 if (!(R128_READ(R128_PC_NGUI_CTLSTAT) & R128_PC_BUSY)) {
124 return 0;
125 }
126 DRM_UDELAY(1);
127 }
128
129#if R128_FIFO_DEBUG
130 DRM_ERROR("failed!\n");
131#endif
132 return -EBUSY;
133}
134
135static int r128_do_wait_for_fifo(drm_r128_private_t * dev_priv, int entries)
136{
137 int i;
138
139 for (i = 0; i < dev_priv->usec_timeout; i++) {
140 int slots = R128_READ(R128_GUI_STAT) & R128_GUI_FIFOCNT_MASK;
141 if (slots >= entries)
142 return 0;
143 DRM_UDELAY(1);
144 }
145
146#if R128_FIFO_DEBUG
147 DRM_ERROR("failed!\n");
148#endif
149 return -EBUSY;
150}
151
152static int r128_do_wait_for_idle(drm_r128_private_t * dev_priv)
153{
154 int i, ret;
155
156 ret = r128_do_wait_for_fifo(dev_priv, 64);
157 if (ret)
158 return ret;
159
160 for (i = 0; i < dev_priv->usec_timeout; i++) {
161 if (!(R128_READ(R128_GUI_STAT) & R128_GUI_ACTIVE)) {
162 r128_do_pixcache_flush(dev_priv);
163 return 0;
164 }
165 DRM_UDELAY(1);
166 }
167
168#if R128_FIFO_DEBUG
169 DRM_ERROR("failed!\n");
170#endif
171 return -EBUSY;
172}
173
174/* ================================================================
175 * CCE control, initialization
176 */
177
178/* Load the microcode for the CCE */
179static void r128_cce_load_microcode(drm_r128_private_t * dev_priv)
180{
181 int i;
182
183 DRM_DEBUG("\n");
184
185 r128_do_wait_for_idle(dev_priv);
186
187 R128_WRITE(R128_PM4_MICROCODE_ADDR, 0);
188 for (i = 0; i < 256; i++) {
189 R128_WRITE(R128_PM4_MICROCODE_DATAH, r128_cce_microcode[i * 2]);
190 R128_WRITE(R128_PM4_MICROCODE_DATAL,
191 r128_cce_microcode[i * 2 + 1]);
192 }
193}
194
195/* Flush any pending commands to the CCE. This should only be used just
196 * prior to a wait for idle, as it informs the engine that the command
197 * stream is ending.
198 */
199static void r128_do_cce_flush(drm_r128_private_t * dev_priv)
200{
201 u32 tmp;
202
203 tmp = R128_READ(R128_PM4_BUFFER_DL_WPTR) | R128_PM4_BUFFER_DL_DONE;
204 R128_WRITE(R128_PM4_BUFFER_DL_WPTR, tmp);
205}
206
207/* Wait for the CCE to go idle.
208 */
209int r128_do_cce_idle(drm_r128_private_t * dev_priv)
210{
211 int i;
212
213 for (i = 0; i < dev_priv->usec_timeout; i++) {
214 if (GET_RING_HEAD(dev_priv) == dev_priv->ring.tail) {
215 int pm4stat = R128_READ(R128_PM4_STAT);
216 if (((pm4stat & R128_PM4_FIFOCNT_MASK) >=
217 dev_priv->cce_fifo_size) &&
218 !(pm4stat & (R128_PM4_BUSY |
219 R128_PM4_GUI_ACTIVE))) {
220 return r128_do_pixcache_flush(dev_priv);
221 }
222 }
223 DRM_UDELAY(1);
224 }
225
226#if R128_FIFO_DEBUG
227 DRM_ERROR("failed!\n");
228 r128_status(dev_priv);
229#endif
230 return -EBUSY;
231}
232
233/* Start the Concurrent Command Engine.
234 */
235static void r128_do_cce_start(drm_r128_private_t * dev_priv)
236{
237 r128_do_wait_for_idle(dev_priv);
238
239 R128_WRITE(R128_PM4_BUFFER_CNTL,
240 dev_priv->cce_mode | dev_priv->ring.size_l2qw
241 | R128_PM4_BUFFER_CNTL_NOUPDATE);
242 R128_READ(R128_PM4_BUFFER_ADDR); /* as per the sample code */
243 R128_WRITE(R128_PM4_MICRO_CNTL, R128_PM4_MICRO_FREERUN);
244
245 dev_priv->cce_running = 1;
246}
247
248/* Reset the Concurrent Command Engine. This will not flush any pending
249 * commands, so you must wait for the CCE command stream to complete
250 * before calling this routine.
251 */
252static void r128_do_cce_reset(drm_r128_private_t * dev_priv)
253{
254 R128_WRITE(R128_PM4_BUFFER_DL_WPTR, 0);
255 R128_WRITE(R128_PM4_BUFFER_DL_RPTR, 0);
256 dev_priv->ring.tail = 0;
257}
258
259/* Stop the Concurrent Command Engine. This will not flush any pending
260 * commands, so you must flush the command stream and wait for the CCE
261 * to go idle before calling this routine.
262 */
263static void r128_do_cce_stop(drm_r128_private_t * dev_priv)
264{
265 R128_WRITE(R128_PM4_MICRO_CNTL, 0);
266 R128_WRITE(R128_PM4_BUFFER_CNTL,
267 R128_PM4_NONPM4 | R128_PM4_BUFFER_CNTL_NOUPDATE);
268
269 dev_priv->cce_running = 0;
270}
271
272/* Reset the engine. This will stop the CCE if it is running.
273 */
274static int r128_do_engine_reset(struct drm_device * dev)
275{
276 drm_r128_private_t *dev_priv = dev->dev_private;
277 u32 clock_cntl_index, mclk_cntl, gen_reset_cntl;
278
279 r128_do_pixcache_flush(dev_priv);
280
281 clock_cntl_index = R128_READ(R128_CLOCK_CNTL_INDEX);
282 mclk_cntl = R128_READ_PLL(dev, R128_MCLK_CNTL);
283
284 R128_WRITE_PLL(R128_MCLK_CNTL,
285 mclk_cntl | R128_FORCE_GCP | R128_FORCE_PIPE3D_CP);
286
287 gen_reset_cntl = R128_READ(R128_GEN_RESET_CNTL);
288
289 /* Taken from the sample code - do not change */
290 R128_WRITE(R128_GEN_RESET_CNTL, gen_reset_cntl | R128_SOFT_RESET_GUI);
291 R128_READ(R128_GEN_RESET_CNTL);
292 R128_WRITE(R128_GEN_RESET_CNTL, gen_reset_cntl & ~R128_SOFT_RESET_GUI);
293 R128_READ(R128_GEN_RESET_CNTL);
294
295 R128_WRITE_PLL(R128_MCLK_CNTL, mclk_cntl);
296 R128_WRITE(R128_CLOCK_CNTL_INDEX, clock_cntl_index);
297 R128_WRITE(R128_GEN_RESET_CNTL, gen_reset_cntl);
298
299 /* Reset the CCE ring */
300 r128_do_cce_reset(dev_priv);
301
302 /* The CCE is no longer running after an engine reset */
303 dev_priv->cce_running = 0;
304
305 /* Reset any pending vertex, indirect buffers */
306 r128_freelist_reset(dev);
307
308 return 0;
309}
310
311static void r128_cce_init_ring_buffer(struct drm_device * dev,
312 drm_r128_private_t * dev_priv)
313{
314 u32 ring_start;
315 u32 tmp;
316
317 DRM_DEBUG("\n");
318
319 /* The manual (p. 2) says this address is in "VM space". This
320 * means it's an offset from the start of AGP space.
321 */
322#if __OS_HAS_AGP
323 if (!dev_priv->is_pci)
324 ring_start = dev_priv->cce_ring->offset - dev->agp->base;
325 else
326#endif
327 ring_start = dev_priv->cce_ring->offset -
328 (unsigned long)dev->sg->virtual;
329
330 R128_WRITE(R128_PM4_BUFFER_OFFSET, ring_start | R128_AGP_OFFSET);
331
332 R128_WRITE(R128_PM4_BUFFER_DL_WPTR, 0);
333 R128_WRITE(R128_PM4_BUFFER_DL_RPTR, 0);
334
335 /* Set watermark control */
336 R128_WRITE(R128_PM4_BUFFER_WM_CNTL,
337 ((R128_WATERMARK_L / 4) << R128_WMA_SHIFT)
338 | ((R128_WATERMARK_M / 4) << R128_WMB_SHIFT)
339 | ((R128_WATERMARK_N / 4) << R128_WMC_SHIFT)
340 | ((R128_WATERMARK_K / 64) << R128_WB_WM_SHIFT));
341
342 /* Force read. Why? Because it's in the examples... */
343 R128_READ(R128_PM4_BUFFER_ADDR);
344
345 /* Turn on bus mastering */
346 tmp = R128_READ(R128_BUS_CNTL) & ~R128_BUS_MASTER_DIS;
347 R128_WRITE(R128_BUS_CNTL, tmp);
348}
349
350static int r128_do_init_cce(struct drm_device * dev, drm_r128_init_t * init)
351{
352 drm_r128_private_t *dev_priv;
353
354 DRM_DEBUG("\n");
355
356 dev_priv = drm_alloc(sizeof(drm_r128_private_t), DRM_MEM_DRIVER);
357 if (dev_priv == NULL)
358 return -ENOMEM;
359
360 memset(dev_priv, 0, sizeof(drm_r128_private_t));
361
362 dev_priv->is_pci = init->is_pci;
363
364 if (dev_priv->is_pci && !dev->sg) {
365 DRM_ERROR("PCI GART memory not allocated!\n");
366 dev->dev_private = (void *)dev_priv;
367 r128_do_cleanup_cce(dev);
368 return -EINVAL;
369 }
370
371 dev_priv->usec_timeout = init->usec_timeout;
372 if (dev_priv->usec_timeout < 1 ||
373 dev_priv->usec_timeout > R128_MAX_USEC_TIMEOUT) {
374 DRM_DEBUG("TIMEOUT problem!\n");
375 dev->dev_private = (void *)dev_priv;
376 r128_do_cleanup_cce(dev);
377 return -EINVAL;
378 }
379
380 dev_priv->cce_mode = init->cce_mode;
381
382 /* GH: Simple idle check.
383 */
384 atomic_set(&dev_priv->idle_count, 0);
385
386 /* We don't support anything other than bus-mastering ring mode,
387 * but the ring can be in either AGP or PCI space for the ring
388 * read pointer.
389 */
390 if ((init->cce_mode != R128_PM4_192BM) &&
391 (init->cce_mode != R128_PM4_128BM_64INDBM) &&
392 (init->cce_mode != R128_PM4_64BM_128INDBM) &&
393 (init->cce_mode != R128_PM4_64BM_64VCBM_64INDBM)) {
394 DRM_DEBUG("Bad cce_mode!\n");
395 dev->dev_private = (void *)dev_priv;
396 r128_do_cleanup_cce(dev);
397 return -EINVAL;
398 }
399
400 switch (init->cce_mode) {
401 case R128_PM4_NONPM4:
402 dev_priv->cce_fifo_size = 0;
403 break;
404 case R128_PM4_192PIO:
405 case R128_PM4_192BM:
406 dev_priv->cce_fifo_size = 192;
407 break;
408 case R128_PM4_128PIO_64INDBM:
409 case R128_PM4_128BM_64INDBM:
410 dev_priv->cce_fifo_size = 128;
411 break;
412 case R128_PM4_64PIO_128INDBM:
413 case R128_PM4_64BM_128INDBM:
414 case R128_PM4_64PIO_64VCBM_64INDBM:
415 case R128_PM4_64BM_64VCBM_64INDBM:
416 case R128_PM4_64PIO_64VCPIO_64INDPIO:
417 dev_priv->cce_fifo_size = 64;
418 break;
419 }
420
421 switch (init->fb_bpp) {
422 case 16:
423 dev_priv->color_fmt = R128_DATATYPE_RGB565;
424 break;
425 case 32:
426 default:
427 dev_priv->color_fmt = R128_DATATYPE_ARGB8888;
428 break;
429 }
430 dev_priv->front_offset = init->front_offset;
431 dev_priv->front_pitch = init->front_pitch;
432 dev_priv->back_offset = init->back_offset;
433 dev_priv->back_pitch = init->back_pitch;
434
435 switch (init->depth_bpp) {
436 case 16:
437 dev_priv->depth_fmt = R128_DATATYPE_RGB565;
438 break;
439 case 24:
440 case 32:
441 default:
442 dev_priv->depth_fmt = R128_DATATYPE_ARGB8888;
443 break;
444 }
445 dev_priv->depth_offset = init->depth_offset;
446 dev_priv->depth_pitch = init->depth_pitch;
447 dev_priv->span_offset = init->span_offset;
448
449 dev_priv->front_pitch_offset_c = (((dev_priv->front_pitch / 8) << 21) |
450 (dev_priv->front_offset >> 5));
451 dev_priv->back_pitch_offset_c = (((dev_priv->back_pitch / 8) << 21) |
452 (dev_priv->back_offset >> 5));
453 dev_priv->depth_pitch_offset_c = (((dev_priv->depth_pitch / 8) << 21) |
454 (dev_priv->depth_offset >> 5) |
455 R128_DST_TILE);
456 dev_priv->span_pitch_offset_c = (((dev_priv->depth_pitch / 8) << 21) |
457 (dev_priv->span_offset >> 5));
458
459 dev_priv->sarea = drm_getsarea(dev);
460 if (!dev_priv->sarea) {
461 DRM_ERROR("could not find sarea!\n");
462 dev->dev_private = (void *)dev_priv;
463 r128_do_cleanup_cce(dev);
464 return -EINVAL;
465 }
466
467 dev_priv->mmio = drm_core_findmap(dev, init->mmio_offset);
468 if (!dev_priv->mmio) {
469 DRM_ERROR("could not find mmio region!\n");
470 dev->dev_private = (void *)dev_priv;
471 r128_do_cleanup_cce(dev);
472 return -EINVAL;
473 }
474 dev_priv->cce_ring = drm_core_findmap(dev, init->ring_offset);
475 if (!dev_priv->cce_ring) {
476 DRM_ERROR("could not find cce ring region!\n");
477 dev->dev_private = (void *)dev_priv;
478 r128_do_cleanup_cce(dev);
479 return -EINVAL;
480 }
481 dev_priv->ring_rptr = drm_core_findmap(dev, init->ring_rptr_offset);
482 if (!dev_priv->ring_rptr) {
483 DRM_ERROR("could not find ring read pointer!\n");
484 dev->dev_private = (void *)dev_priv;
485 r128_do_cleanup_cce(dev);
486 return -EINVAL;
487 }
488 dev->agp_buffer_token = init->buffers_offset;
489 dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset);
490 if (!dev->agp_buffer_map) {
491 DRM_ERROR("could not find dma buffer region!\n");
492 dev->dev_private = (void *)dev_priv;
493 r128_do_cleanup_cce(dev);
494 return -EINVAL;
495 }
496
497 if (!dev_priv->is_pci) {
498 dev_priv->agp_textures =
499 drm_core_findmap(dev, init->agp_textures_offset);
500 if (!dev_priv->agp_textures) {
501 DRM_ERROR("could not find agp texture region!\n");
502 dev->dev_private = (void *)dev_priv;
503 r128_do_cleanup_cce(dev);
504 return -EINVAL;
505 }
506 }
507
508 dev_priv->sarea_priv =
509 (drm_r128_sarea_t *) ((u8 *) dev_priv->sarea->handle +
510 init->sarea_priv_offset);
511
512#if __OS_HAS_AGP
513 if (!dev_priv->is_pci) {
514 drm_core_ioremap(dev_priv->cce_ring, dev);
515 drm_core_ioremap(dev_priv->ring_rptr, dev);
516 drm_core_ioremap(dev->agp_buffer_map, dev);
517 if (!dev_priv->cce_ring->handle ||
518 !dev_priv->ring_rptr->handle ||
519 !dev->agp_buffer_map->handle) {
520 DRM_ERROR("Could not ioremap agp regions!\n");
521 dev->dev_private = (void *)dev_priv;
522 r128_do_cleanup_cce(dev);
523 return -ENOMEM;
524 }
525 } else
526#endif
527 {
528 dev_priv->cce_ring->handle = (void *)dev_priv->cce_ring->offset;
529 dev_priv->ring_rptr->handle =
530 (void *)dev_priv->ring_rptr->offset;
531 dev->agp_buffer_map->handle =
532 (void *)dev->agp_buffer_map->offset;
533 }
534
535#if __OS_HAS_AGP
536 if (!dev_priv->is_pci)
537 dev_priv->cce_buffers_offset = dev->agp->base;
538 else
539#endif
540 dev_priv->cce_buffers_offset = (unsigned long)dev->sg->virtual;
541
542 dev_priv->ring.start = (u32 *) dev_priv->cce_ring->handle;
543 dev_priv->ring.end = ((u32 *) dev_priv->cce_ring->handle
544 + init->ring_size / sizeof(u32));
545 dev_priv->ring.size = init->ring_size;
546 dev_priv->ring.size_l2qw = drm_order(init->ring_size / 8);
547
548 dev_priv->ring.tail_mask = (dev_priv->ring.size / sizeof(u32)) - 1;
549
550 dev_priv->ring.high_mark = 128;
551
552 dev_priv->sarea_priv->last_frame = 0;
553 R128_WRITE(R128_LAST_FRAME_REG, dev_priv->sarea_priv->last_frame);
554
555 dev_priv->sarea_priv->last_dispatch = 0;
556 R128_WRITE(R128_LAST_DISPATCH_REG, dev_priv->sarea_priv->last_dispatch);
557
558#if __OS_HAS_AGP
559 if (dev_priv->is_pci) {
560#endif
561 dev_priv->gart_info.table_mask = DMA_BIT_MASK(32);
562 dev_priv->gart_info.gart_table_location = DRM_ATI_GART_MAIN;
563 dev_priv->gart_info.table_size = R128_PCIGART_TABLE_SIZE;
564 dev_priv->gart_info.addr = NULL;
565 dev_priv->gart_info.bus_addr = 0;
566 dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCI;
567 if (!drm_ati_pcigart_init(dev, &dev_priv->gart_info)) {
568 DRM_ERROR("failed to init PCI GART!\n");
569 dev->dev_private = (void *)dev_priv;
570 r128_do_cleanup_cce(dev);
571 return -ENOMEM;
572 }
573 R128_WRITE(R128_PCI_GART_PAGE, dev_priv->gart_info.bus_addr);
574#if __OS_HAS_AGP
575 }
576#endif
577
578 r128_cce_init_ring_buffer(dev, dev_priv);
579 r128_cce_load_microcode(dev_priv);
580
581 dev->dev_private = (void *)dev_priv;
582
583 r128_do_engine_reset(dev);
584
585 return 0;
586}
587
588int r128_do_cleanup_cce(struct drm_device * dev)
589{
590
591 /* Make sure interrupts are disabled here because the uninstall ioctl
592 * may not have been called from userspace and after dev_private
593 * is freed, it's too late.
594 */
595 if (dev->irq_enabled)
596 drm_irq_uninstall(dev);
597
598 if (dev->dev_private) {
599 drm_r128_private_t *dev_priv = dev->dev_private;
600
601#if __OS_HAS_AGP
602 if (!dev_priv->is_pci) {
603 if (dev_priv->cce_ring != NULL)
604 drm_core_ioremapfree(dev_priv->cce_ring, dev);
605 if (dev_priv->ring_rptr != NULL)
606 drm_core_ioremapfree(dev_priv->ring_rptr, dev);
607 if (dev->agp_buffer_map != NULL) {
608 drm_core_ioremapfree(dev->agp_buffer_map, dev);
609 dev->agp_buffer_map = NULL;
610 }
611 } else
612#endif
613 {
614 if (dev_priv->gart_info.bus_addr)
615 if (!drm_ati_pcigart_cleanup(dev,
616 &dev_priv->gart_info))
617 DRM_ERROR
618 ("failed to cleanup PCI GART!\n");
619 }
620
621 drm_free(dev->dev_private, sizeof(drm_r128_private_t),
622 DRM_MEM_DRIVER);
623 dev->dev_private = NULL;
624 }
625
626 return 0;
627}
628
629int r128_cce_init(struct drm_device *dev, void *data, struct drm_file *file_priv)
630{
631 drm_r128_init_t *init = data;
632
633 DRM_DEBUG("\n");
634
635 LOCK_TEST_WITH_RETURN(dev, file_priv);
636
637 switch (init->func) {
638 case R128_INIT_CCE:
639 return r128_do_init_cce(dev, init);
640 case R128_CLEANUP_CCE:
641 return r128_do_cleanup_cce(dev);
642 }
643
644 return -EINVAL;
645}
646
647int r128_cce_start(struct drm_device *dev, void *data, struct drm_file *file_priv)
648{
649 drm_r128_private_t *dev_priv = dev->dev_private;
650 DRM_DEBUG("\n");
651
652 LOCK_TEST_WITH_RETURN(dev, file_priv);
653
654 if (dev_priv->cce_running || dev_priv->cce_mode == R128_PM4_NONPM4) {
655 DRM_DEBUG("while CCE running\n");
656 return 0;
657 }
658
659 r128_do_cce_start(dev_priv);
660
661 return 0;
662}
663
664/* Stop the CCE. The engine must have been idled before calling this
665 * routine.
666 */
667int r128_cce_stop(struct drm_device *dev, void *data, struct drm_file *file_priv)
668{
669 drm_r128_private_t *dev_priv = dev->dev_private;
670 drm_r128_cce_stop_t *stop = data;
671 int ret;
672 DRM_DEBUG("\n");
673
674 LOCK_TEST_WITH_RETURN(dev, file_priv);
675
676 /* Flush any pending CCE commands. This ensures any outstanding
677 * commands are exectuted by the engine before we turn it off.
678 */
679 if (stop->flush) {
680 r128_do_cce_flush(dev_priv);
681 }
682
683 /* If we fail to make the engine go idle, we return an error
684 * code so that the DRM ioctl wrapper can try again.
685 */
686 if (stop->idle) {
687 ret = r128_do_cce_idle(dev_priv);
688 if (ret)
689 return ret;
690 }
691
692 /* Finally, we can turn off the CCE. If the engine isn't idle,
693 * we will get some dropped triangles as they won't be fully
694 * rendered before the CCE is shut down.
695 */
696 r128_do_cce_stop(dev_priv);
697
698 /* Reset the engine */
699 r128_do_engine_reset(dev);
700
701 return 0;
702}
703
704/* Just reset the CCE ring. Called as part of an X Server engine reset.
705 */
706int r128_cce_reset(struct drm_device *dev, void *data, struct drm_file *file_priv)
707{
708 drm_r128_private_t *dev_priv = dev->dev_private;
709 DRM_DEBUG("\n");
710
711 LOCK_TEST_WITH_RETURN(dev, file_priv);
712
713 if (!dev_priv) {
714 DRM_DEBUG("called before init done\n");
715 return -EINVAL;
716 }
717
718 r128_do_cce_reset(dev_priv);
719
720 /* The CCE is no longer running after an engine reset */
721 dev_priv->cce_running = 0;
722
723 return 0;
724}
725
726int r128_cce_idle(struct drm_device *dev, void *data, struct drm_file *file_priv)
727{
728 drm_r128_private_t *dev_priv = dev->dev_private;
729 DRM_DEBUG("\n");
730
731 LOCK_TEST_WITH_RETURN(dev, file_priv);
732
733 if (dev_priv->cce_running) {
734 r128_do_cce_flush(dev_priv);
735 }
736
737 return r128_do_cce_idle(dev_priv);
738}
739
740int r128_engine_reset(struct drm_device *dev, void *data, struct drm_file *file_priv)
741{
742 DRM_DEBUG("\n");
743
744 LOCK_TEST_WITH_RETURN(dev, file_priv);
745
746 return r128_do_engine_reset(dev);
747}
748
749int r128_fullscreen(struct drm_device *dev, void *data, struct drm_file *file_priv)
750{
751 return -EINVAL;
752}
753
754/* ================================================================
755 * Freelist management
756 */
757#define R128_BUFFER_USED 0xffffffff
758#define R128_BUFFER_FREE 0
759
760#if 0
761static int r128_freelist_init(struct drm_device * dev)
762{
763 struct drm_device_dma *dma = dev->dma;
764 drm_r128_private_t *dev_priv = dev->dev_private;
765 struct drm_buf *buf;
766 drm_r128_buf_priv_t *buf_priv;
767 drm_r128_freelist_t *entry;
768 int i;
769
770 dev_priv->head = drm_alloc(sizeof(drm_r128_freelist_t), DRM_MEM_DRIVER);
771 if (dev_priv->head == NULL)
772 return -ENOMEM;
773
774 memset(dev_priv->head, 0, sizeof(drm_r128_freelist_t));
775 dev_priv->head->age = R128_BUFFER_USED;
776
777 for (i = 0; i < dma->buf_count; i++) {
778 buf = dma->buflist[i];
779 buf_priv = buf->dev_private;
780
781 entry = drm_alloc(sizeof(drm_r128_freelist_t), DRM_MEM_DRIVER);
782 if (!entry)
783 return -ENOMEM;
784
785 entry->age = R128_BUFFER_FREE;
786 entry->buf = buf;
787 entry->prev = dev_priv->head;
788 entry->next = dev_priv->head->next;
789 if (!entry->next)
790 dev_priv->tail = entry;
791
792 buf_priv->discard = 0;
793 buf_priv->dispatched = 0;
794 buf_priv->list_entry = entry;
795
796 dev_priv->head->next = entry;
797
798 if (dev_priv->head->next)
799 dev_priv->head->next->prev = entry;
800 }
801
802 return 0;
803
804}
805#endif
806
807static struct drm_buf *r128_freelist_get(struct drm_device * dev)
808{
809 struct drm_device_dma *dma = dev->dma;
810 drm_r128_private_t *dev_priv = dev->dev_private;
811 drm_r128_buf_priv_t *buf_priv;
812 struct drm_buf *buf;
813 int i, t;
814
815 /* FIXME: Optimize -- use freelist code */
816
817 for (i = 0; i < dma->buf_count; i++) {
818 buf = dma->buflist[i];
819 buf_priv = buf->dev_private;
820 if (!buf->file_priv)
821 return buf;
822 }
823
824 for (t = 0; t < dev_priv->usec_timeout; t++) {
825 u32 done_age = R128_READ(R128_LAST_DISPATCH_REG);
826
827 for (i = 0; i < dma->buf_count; i++) {
828 buf = dma->buflist[i];
829 buf_priv = buf->dev_private;
830 if (buf->pending && buf_priv->age <= done_age) {
831 /* The buffer has been processed, so it
832 * can now be used.
833 */
834 buf->pending = 0;
835 return buf;
836 }
837 }
838 DRM_UDELAY(1);
839 }
840
841 DRM_DEBUG("returning NULL!\n");
842 return NULL;
843}
844
845void r128_freelist_reset(struct drm_device * dev)
846{
847 struct drm_device_dma *dma = dev->dma;
848 int i;
849
850 for (i = 0; i < dma->buf_count; i++) {
851 struct drm_buf *buf = dma->buflist[i];
852 drm_r128_buf_priv_t *buf_priv = buf->dev_private;
853 buf_priv->age = 0;
854 }
855}
856
857/* ================================================================
858 * CCE command submission
859 */
860
861int r128_wait_ring(drm_r128_private_t * dev_priv, int n)
862{
863 drm_r128_ring_buffer_t *ring = &dev_priv->ring;
864 int i;
865
866 for (i = 0; i < dev_priv->usec_timeout; i++) {
867 r128_update_ring_snapshot(dev_priv);
868 if (ring->space >= n)
869 return 0;
870 DRM_UDELAY(1);
871 }
872
873 /* FIXME: This is being ignored... */
874 DRM_ERROR("failed!\n");
875 return -EBUSY;
876}
877
878static int r128_cce_get_buffers(struct drm_device * dev,
879 struct drm_file *file_priv,
880 struct drm_dma * d)
881{
882 int i;
883 struct drm_buf *buf;
884
885 for (i = d->granted_count; i < d->request_count; i++) {
886 buf = r128_freelist_get(dev);
887 if (!buf)
888 return -EAGAIN;
889
890 buf->file_priv = file_priv;
891
892 if (DRM_COPY_TO_USER(&d->request_indices[i], &buf->idx,
893 sizeof(buf->idx)))
894 return -EFAULT;
895 if (DRM_COPY_TO_USER(&d->request_sizes[i], &buf->total,
896 sizeof(buf->total)))
897 return -EFAULT;
898
899 d->granted_count++;
900 }
901 return 0;
902}
903
904int r128_cce_buffers(struct drm_device *dev, void *data, struct drm_file *file_priv)
905{
906 struct drm_device_dma *dma = dev->dma;
907 int ret = 0;
908 struct drm_dma *d = data;
909
910 LOCK_TEST_WITH_RETURN(dev, file_priv);
911
912 /* Please don't send us buffers.
913 */
914 if (d->send_count != 0) {
915 DRM_ERROR("Process %d trying to send %d buffers via drmDMA\n",
916 DRM_CURRENTPID, d->send_count);
917 return -EINVAL;
918 }
919
920 /* We'll send you buffers.
921 */
922 if (d->request_count < 0 || d->request_count > dma->buf_count) {
923 DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n",
924 DRM_CURRENTPID, d->request_count, dma->buf_count);
925 return -EINVAL;
926 }
927
928 d->granted_count = 0;
929
930 if (d->request_count) {
931 ret = r128_cce_get_buffers(dev, file_priv, d);
932 }
933
934 return ret;
935}
diff --git a/drivers/char/drm/r128_drm.h b/drivers/char/drm/r128_drm.h
deleted file mode 100644
index 8d8878b55f55..000000000000
--- a/drivers/char/drm/r128_drm.h
+++ /dev/null
@@ -1,326 +0,0 @@
1/* r128_drm.h -- Public header for the r128 driver -*- linux-c -*-
2 * Created: Wed Apr 5 19:24:19 2000 by kevin@precisioninsight.com
3 */
4/*
5 * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas.
6 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
7 * All rights reserved.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice (including the next
17 * paragraph) shall be included in all copies or substantial portions of the
18 * Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
24 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
25 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 * DEALINGS IN THE SOFTWARE.
27 *
28 * Authors:
29 * Gareth Hughes <gareth@valinux.com>
30 * Kevin E. Martin <martin@valinux.com>
31 */
32
33#ifndef __R128_DRM_H__
34#define __R128_DRM_H__
35
36/* WARNING: If you change any of these defines, make sure to change the
37 * defines in the X server file (r128_sarea.h)
38 */
39#ifndef __R128_SAREA_DEFINES__
40#define __R128_SAREA_DEFINES__
41
42/* What needs to be changed for the current vertex buffer?
43 */
44#define R128_UPLOAD_CONTEXT 0x001
45#define R128_UPLOAD_SETUP 0x002
46#define R128_UPLOAD_TEX0 0x004
47#define R128_UPLOAD_TEX1 0x008
48#define R128_UPLOAD_TEX0IMAGES 0x010
49#define R128_UPLOAD_TEX1IMAGES 0x020
50#define R128_UPLOAD_CORE 0x040
51#define R128_UPLOAD_MASKS 0x080
52#define R128_UPLOAD_WINDOW 0x100
53#define R128_UPLOAD_CLIPRECTS 0x200 /* handled client-side */
54#define R128_REQUIRE_QUIESCENCE 0x400
55#define R128_UPLOAD_ALL 0x7ff
56
57#define R128_FRONT 0x1
58#define R128_BACK 0x2
59#define R128_DEPTH 0x4
60
61/* Primitive types
62 */
63#define R128_POINTS 0x1
64#define R128_LINES 0x2
65#define R128_LINE_STRIP 0x3
66#define R128_TRIANGLES 0x4
67#define R128_TRIANGLE_FAN 0x5
68#define R128_TRIANGLE_STRIP 0x6
69
70/* Vertex/indirect buffer size
71 */
72#define R128_BUFFER_SIZE 16384
73
74/* Byte offsets for indirect buffer data
75 */
76#define R128_INDEX_PRIM_OFFSET 20
77#define R128_HOSTDATA_BLIT_OFFSET 32
78
79/* Keep these small for testing.
80 */
81#define R128_NR_SAREA_CLIPRECTS 12
82
83/* There are 2 heaps (local/AGP). Each region within a heap is a
84 * minimum of 64k, and there are at most 64 of them per heap.
85 */
86#define R128_LOCAL_TEX_HEAP 0
87#define R128_AGP_TEX_HEAP 1
88#define R128_NR_TEX_HEAPS 2
89#define R128_NR_TEX_REGIONS 64
90#define R128_LOG_TEX_GRANULARITY 16
91
92#define R128_NR_CONTEXT_REGS 12
93
94#define R128_MAX_TEXTURE_LEVELS 11
95#define R128_MAX_TEXTURE_UNITS 2
96
97#endif /* __R128_SAREA_DEFINES__ */
98
99typedef struct {
100 /* Context state - can be written in one large chunk */
101 unsigned int dst_pitch_offset_c;
102 unsigned int dp_gui_master_cntl_c;
103 unsigned int sc_top_left_c;
104 unsigned int sc_bottom_right_c;
105 unsigned int z_offset_c;
106 unsigned int z_pitch_c;
107 unsigned int z_sten_cntl_c;
108 unsigned int tex_cntl_c;
109 unsigned int misc_3d_state_cntl_reg;
110 unsigned int texture_clr_cmp_clr_c;
111 unsigned int texture_clr_cmp_msk_c;
112 unsigned int fog_color_c;
113
114 /* Texture state */
115 unsigned int tex_size_pitch_c;
116 unsigned int constant_color_c;
117
118 /* Setup state */
119 unsigned int pm4_vc_fpu_setup;
120 unsigned int setup_cntl;
121
122 /* Mask state */
123 unsigned int dp_write_mask;
124 unsigned int sten_ref_mask_c;
125 unsigned int plane_3d_mask_c;
126
127 /* Window state */
128 unsigned int window_xy_offset;
129
130 /* Core state */
131 unsigned int scale_3d_cntl;
132} drm_r128_context_regs_t;
133
134/* Setup registers for each texture unit
135 */
136typedef struct {
137 unsigned int tex_cntl;
138 unsigned int tex_combine_cntl;
139 unsigned int tex_size_pitch;
140 unsigned int tex_offset[R128_MAX_TEXTURE_LEVELS];
141 unsigned int tex_border_color;
142} drm_r128_texture_regs_t;
143
144typedef struct drm_r128_sarea {
145 /* The channel for communication of state information to the kernel
146 * on firing a vertex buffer.
147 */
148 drm_r128_context_regs_t context_state;
149 drm_r128_texture_regs_t tex_state[R128_MAX_TEXTURE_UNITS];
150 unsigned int dirty;
151 unsigned int vertsize;
152 unsigned int vc_format;
153
154 /* The current cliprects, or a subset thereof.
155 */
156 struct drm_clip_rect boxes[R128_NR_SAREA_CLIPRECTS];
157 unsigned int nbox;
158
159 /* Counters for client-side throttling of rendering clients.
160 */
161 unsigned int last_frame;
162 unsigned int last_dispatch;
163
164 struct drm_tex_region tex_list[R128_NR_TEX_HEAPS][R128_NR_TEX_REGIONS + 1];
165 unsigned int tex_age[R128_NR_TEX_HEAPS];
166 int ctx_owner;
167 int pfAllowPageFlip; /* number of 3d windows (0,1,2 or more) */
168 int pfCurrentPage; /* which buffer is being displayed? */
169} drm_r128_sarea_t;
170
171/* WARNING: If you change any of these defines, make sure to change the
172 * defines in the Xserver file (xf86drmR128.h)
173 */
174
175/* Rage 128 specific ioctls
176 * The device specific ioctl range is 0x40 to 0x79.
177 */
178#define DRM_R128_INIT 0x00
179#define DRM_R128_CCE_START 0x01
180#define DRM_R128_CCE_STOP 0x02
181#define DRM_R128_CCE_RESET 0x03
182#define DRM_R128_CCE_IDLE 0x04
183/* 0x05 not used */
184#define DRM_R128_RESET 0x06
185#define DRM_R128_SWAP 0x07
186#define DRM_R128_CLEAR 0x08
187#define DRM_R128_VERTEX 0x09
188#define DRM_R128_INDICES 0x0a
189#define DRM_R128_BLIT 0x0b
190#define DRM_R128_DEPTH 0x0c
191#define DRM_R128_STIPPLE 0x0d
192/* 0x0e not used */
193#define DRM_R128_INDIRECT 0x0f
194#define DRM_R128_FULLSCREEN 0x10
195#define DRM_R128_CLEAR2 0x11
196#define DRM_R128_GETPARAM 0x12
197#define DRM_R128_FLIP 0x13
198
199#define DRM_IOCTL_R128_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_R128_INIT, drm_r128_init_t)
200#define DRM_IOCTL_R128_CCE_START DRM_IO( DRM_COMMAND_BASE + DRM_R128_CCE_START)
201#define DRM_IOCTL_R128_CCE_STOP DRM_IOW( DRM_COMMAND_BASE + DRM_R128_CCE_STOP, drm_r128_cce_stop_t)
202#define DRM_IOCTL_R128_CCE_RESET DRM_IO( DRM_COMMAND_BASE + DRM_R128_CCE_RESET)
203#define DRM_IOCTL_R128_CCE_IDLE DRM_IO( DRM_COMMAND_BASE + DRM_R128_CCE_IDLE)
204/* 0x05 not used */
205#define DRM_IOCTL_R128_RESET DRM_IO( DRM_COMMAND_BASE + DRM_R128_RESET)
206#define DRM_IOCTL_R128_SWAP DRM_IO( DRM_COMMAND_BASE + DRM_R128_SWAP)
207#define DRM_IOCTL_R128_CLEAR DRM_IOW( DRM_COMMAND_BASE + DRM_R128_CLEAR, drm_r128_clear_t)
208#define DRM_IOCTL_R128_VERTEX DRM_IOW( DRM_COMMAND_BASE + DRM_R128_VERTEX, drm_r128_vertex_t)
209#define DRM_IOCTL_R128_INDICES DRM_IOW( DRM_COMMAND_BASE + DRM_R128_INDICES, drm_r128_indices_t)
210#define DRM_IOCTL_R128_BLIT DRM_IOW( DRM_COMMAND_BASE + DRM_R128_BLIT, drm_r128_blit_t)
211#define DRM_IOCTL_R128_DEPTH DRM_IOW( DRM_COMMAND_BASE + DRM_R128_DEPTH, drm_r128_depth_t)
212#define DRM_IOCTL_R128_STIPPLE DRM_IOW( DRM_COMMAND_BASE + DRM_R128_STIPPLE, drm_r128_stipple_t)
213/* 0x0e not used */
214#define DRM_IOCTL_R128_INDIRECT DRM_IOWR(DRM_COMMAND_BASE + DRM_R128_INDIRECT, drm_r128_indirect_t)
215#define DRM_IOCTL_R128_FULLSCREEN DRM_IOW( DRM_COMMAND_BASE + DRM_R128_FULLSCREEN, drm_r128_fullscreen_t)
216#define DRM_IOCTL_R128_CLEAR2 DRM_IOW( DRM_COMMAND_BASE + DRM_R128_CLEAR2, drm_r128_clear2_t)
217#define DRM_IOCTL_R128_GETPARAM DRM_IOWR( DRM_COMMAND_BASE + DRM_R128_GETPARAM, drm_r128_getparam_t)
218#define DRM_IOCTL_R128_FLIP DRM_IO( DRM_COMMAND_BASE + DRM_R128_FLIP)
219
220typedef struct drm_r128_init {
221 enum {
222 R128_INIT_CCE = 0x01,
223 R128_CLEANUP_CCE = 0x02
224 } func;
225 unsigned long sarea_priv_offset;
226 int is_pci;
227 int cce_mode;
228 int cce_secure;
229 int ring_size;
230 int usec_timeout;
231
232 unsigned int fb_bpp;
233 unsigned int front_offset, front_pitch;
234 unsigned int back_offset, back_pitch;
235 unsigned int depth_bpp;
236 unsigned int depth_offset, depth_pitch;
237 unsigned int span_offset;
238
239 unsigned long fb_offset;
240 unsigned long mmio_offset;
241 unsigned long ring_offset;
242 unsigned long ring_rptr_offset;
243 unsigned long buffers_offset;
244 unsigned long agp_textures_offset;
245} drm_r128_init_t;
246
247typedef struct drm_r128_cce_stop {
248 int flush;
249 int idle;
250} drm_r128_cce_stop_t;
251
252typedef struct drm_r128_clear {
253 unsigned int flags;
254 unsigned int clear_color;
255 unsigned int clear_depth;
256 unsigned int color_mask;
257 unsigned int depth_mask;
258} drm_r128_clear_t;
259
260typedef struct drm_r128_vertex {
261 int prim;
262 int idx; /* Index of vertex buffer */
263 int count; /* Number of vertices in buffer */
264 int discard; /* Client finished with buffer? */
265} drm_r128_vertex_t;
266
267typedef struct drm_r128_indices {
268 int prim;
269 int idx;
270 int start;
271 int end;
272 int discard; /* Client finished with buffer? */
273} drm_r128_indices_t;
274
275typedef struct drm_r128_blit {
276 int idx;
277 int pitch;
278 int offset;
279 int format;
280 unsigned short x, y;
281 unsigned short width, height;
282} drm_r128_blit_t;
283
284typedef struct drm_r128_depth {
285 enum {
286 R128_WRITE_SPAN = 0x01,
287 R128_WRITE_PIXELS = 0x02,
288 R128_READ_SPAN = 0x03,
289 R128_READ_PIXELS = 0x04
290 } func;
291 int n;
292 int __user *x;
293 int __user *y;
294 unsigned int __user *buffer;
295 unsigned char __user *mask;
296} drm_r128_depth_t;
297
298typedef struct drm_r128_stipple {
299 unsigned int __user *mask;
300} drm_r128_stipple_t;
301
302typedef struct drm_r128_indirect {
303 int idx;
304 int start;
305 int end;
306 int discard;
307} drm_r128_indirect_t;
308
309typedef struct drm_r128_fullscreen {
310 enum {
311 R128_INIT_FULLSCREEN = 0x01,
312 R128_CLEANUP_FULLSCREEN = 0x02
313 } func;
314} drm_r128_fullscreen_t;
315
316/* 2.3: An ioctl to get parameters that aren't available to the 3d
317 * client any other way.
318 */
319#define R128_PARAM_IRQ_NR 1
320
321typedef struct drm_r128_getparam {
322 int param;
323 void __user *value;
324} drm_r128_getparam_t;
325
326#endif
diff --git a/drivers/char/drm/r128_drv.c b/drivers/char/drm/r128_drv.c
deleted file mode 100644
index 2888aa01ebc7..000000000000
--- a/drivers/char/drm/r128_drv.c
+++ /dev/null
@@ -1,104 +0,0 @@
1/* r128_drv.c -- ATI Rage 128 driver -*- linux-c -*-
2 * Created: Mon Dec 13 09:47:27 1999 by faith@precisioninsight.com
3 *
4 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
5 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
6 * All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice (including the next
16 * paragraph) shall be included in all copies or substantial portions of the
17 * Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
23 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25 * OTHER DEALINGS IN THE SOFTWARE.
26 *
27 * Authors:
28 * Rickard E. (Rik) Faith <faith@valinux.com>
29 * Gareth Hughes <gareth@valinux.com>
30 */
31
32#include "drmP.h"
33#include "drm.h"
34#include "r128_drm.h"
35#include "r128_drv.h"
36
37#include "drm_pciids.h"
38
39static struct pci_device_id pciidlist[] = {
40 r128_PCI_IDS
41};
42
43static struct drm_driver driver = {
44 .driver_features =
45 DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG |
46 DRIVER_HAVE_DMA | DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED,
47 .dev_priv_size = sizeof(drm_r128_buf_priv_t),
48 .preclose = r128_driver_preclose,
49 .lastclose = r128_driver_lastclose,
50 .get_vblank_counter = r128_get_vblank_counter,
51 .enable_vblank = r128_enable_vblank,
52 .disable_vblank = r128_disable_vblank,
53 .irq_preinstall = r128_driver_irq_preinstall,
54 .irq_postinstall = r128_driver_irq_postinstall,
55 .irq_uninstall = r128_driver_irq_uninstall,
56 .irq_handler = r128_driver_irq_handler,
57 .reclaim_buffers = drm_core_reclaim_buffers,
58 .get_map_ofs = drm_core_get_map_ofs,
59 .get_reg_ofs = drm_core_get_reg_ofs,
60 .ioctls = r128_ioctls,
61 .dma_ioctl = r128_cce_buffers,
62 .fops = {
63 .owner = THIS_MODULE,
64 .open = drm_open,
65 .release = drm_release,
66 .ioctl = drm_ioctl,
67 .mmap = drm_mmap,
68 .poll = drm_poll,
69 .fasync = drm_fasync,
70#ifdef CONFIG_COMPAT
71 .compat_ioctl = r128_compat_ioctl,
72#endif
73 },
74
75 .pci_driver = {
76 .name = DRIVER_NAME,
77 .id_table = pciidlist,
78 },
79
80 .name = DRIVER_NAME,
81 .desc = DRIVER_DESC,
82 .date = DRIVER_DATE,
83 .major = DRIVER_MAJOR,
84 .minor = DRIVER_MINOR,
85 .patchlevel = DRIVER_PATCHLEVEL,
86};
87
88static int __init r128_init(void)
89{
90 driver.num_ioctls = r128_max_ioctl;
91 return drm_init(&driver);
92}
93
94static void __exit r128_exit(void)
95{
96 drm_exit(&driver);
97}
98
99module_init(r128_init);
100module_exit(r128_exit);
101
102MODULE_AUTHOR(DRIVER_AUTHOR);
103MODULE_DESCRIPTION(DRIVER_DESC);
104MODULE_LICENSE("GPL and additional rights");
diff --git a/drivers/char/drm/r128_drv.h b/drivers/char/drm/r128_drv.h
deleted file mode 100644
index 80af9e09e75d..000000000000
--- a/drivers/char/drm/r128_drv.h
+++ /dev/null
@@ -1,525 +0,0 @@
1/* r128_drv.h -- Private header for r128 driver -*- linux-c -*-
2 * Created: Mon Dec 13 09:51:11 1999 by faith@precisioninsight.com
3 */
4/*
5 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
6 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
7 * All rights reserved.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice (including the next
17 * paragraph) shall be included in all copies or substantial portions of the
18 * Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
24 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
25 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 * DEALINGS IN THE SOFTWARE.
27 *
28 * Authors:
29 * Rickard E. (Rik) Faith <faith@valinux.com>
30 * Kevin E. Martin <martin@valinux.com>
31 * Gareth Hughes <gareth@valinux.com>
32 * Michel Dänzer <daenzerm@student.ethz.ch>
33 */
34
35#ifndef __R128_DRV_H__
36#define __R128_DRV_H__
37
38/* General customization:
39 */
40#define DRIVER_AUTHOR "Gareth Hughes, VA Linux Systems Inc."
41
42#define DRIVER_NAME "r128"
43#define DRIVER_DESC "ATI Rage 128"
44#define DRIVER_DATE "20030725"
45
46/* Interface history:
47 *
48 * ?? - ??
49 * 2.4 - Add support for ycbcr textures (no new ioctls)
50 * 2.5 - Add FLIP ioctl, disable FULLSCREEN.
51 */
52#define DRIVER_MAJOR 2
53#define DRIVER_MINOR 5
54#define DRIVER_PATCHLEVEL 0
55
56#define GET_RING_HEAD(dev_priv) R128_READ( R128_PM4_BUFFER_DL_RPTR )
57
58typedef struct drm_r128_freelist {
59 unsigned int age;
60 struct drm_buf *buf;
61 struct drm_r128_freelist *next;
62 struct drm_r128_freelist *prev;
63} drm_r128_freelist_t;
64
65typedef struct drm_r128_ring_buffer {
66 u32 *start;
67 u32 *end;
68 int size;
69 int size_l2qw;
70
71 u32 tail;
72 u32 tail_mask;
73 int space;
74
75 int high_mark;
76} drm_r128_ring_buffer_t;
77
78typedef struct drm_r128_private {
79 drm_r128_ring_buffer_t ring;
80 drm_r128_sarea_t *sarea_priv;
81
82 int cce_mode;
83 int cce_fifo_size;
84 int cce_running;
85
86 drm_r128_freelist_t *head;
87 drm_r128_freelist_t *tail;
88
89 int usec_timeout;
90 int is_pci;
91 unsigned long cce_buffers_offset;
92
93 atomic_t idle_count;
94
95 int page_flipping;
96 int current_page;
97 u32 crtc_offset;
98 u32 crtc_offset_cntl;
99
100 atomic_t vbl_received;
101
102 u32 color_fmt;
103 unsigned int front_offset;
104 unsigned int front_pitch;
105 unsigned int back_offset;
106 unsigned int back_pitch;
107
108 u32 depth_fmt;
109 unsigned int depth_offset;
110 unsigned int depth_pitch;
111 unsigned int span_offset;
112
113 u32 front_pitch_offset_c;
114 u32 back_pitch_offset_c;
115 u32 depth_pitch_offset_c;
116 u32 span_pitch_offset_c;
117
118 drm_local_map_t *sarea;
119 drm_local_map_t *mmio;
120 drm_local_map_t *cce_ring;
121 drm_local_map_t *ring_rptr;
122 drm_local_map_t *agp_textures;
123 struct drm_ati_pcigart_info gart_info;
124} drm_r128_private_t;
125
126typedef struct drm_r128_buf_priv {
127 u32 age;
128 int prim;
129 int discard;
130 int dispatched;
131 drm_r128_freelist_t *list_entry;
132} drm_r128_buf_priv_t;
133
134extern struct drm_ioctl_desc r128_ioctls[];
135extern int r128_max_ioctl;
136
137 /* r128_cce.c */
138extern int r128_cce_init(struct drm_device *dev, void *data, struct drm_file *file_priv);
139extern int r128_cce_start(struct drm_device *dev, void *data, struct drm_file *file_priv);
140extern int r128_cce_stop(struct drm_device *dev, void *data, struct drm_file *file_priv);
141extern int r128_cce_reset(struct drm_device *dev, void *data, struct drm_file *file_priv);
142extern int r128_cce_idle(struct drm_device *dev, void *data, struct drm_file *file_priv);
143extern int r128_engine_reset(struct drm_device *dev, void *data, struct drm_file *file_priv);
144extern int r128_fullscreen(struct drm_device *dev, void *data, struct drm_file *file_priv);
145extern int r128_cce_buffers(struct drm_device *dev, void *data, struct drm_file *file_priv);
146
147extern void r128_freelist_reset(struct drm_device * dev);
148
149extern int r128_wait_ring(drm_r128_private_t * dev_priv, int n);
150
151extern int r128_do_cce_idle(drm_r128_private_t * dev_priv);
152extern int r128_do_cleanup_cce(struct drm_device * dev);
153
154extern int r128_enable_vblank(struct drm_device *dev, int crtc);
155extern void r128_disable_vblank(struct drm_device *dev, int crtc);
156extern u32 r128_get_vblank_counter(struct drm_device *dev, int crtc);
157extern irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS);
158extern void r128_driver_irq_preinstall(struct drm_device * dev);
159extern int r128_driver_irq_postinstall(struct drm_device * dev);
160extern void r128_driver_irq_uninstall(struct drm_device * dev);
161extern void r128_driver_lastclose(struct drm_device * dev);
162extern void r128_driver_preclose(struct drm_device * dev,
163 struct drm_file *file_priv);
164
165extern long r128_compat_ioctl(struct file *filp, unsigned int cmd,
166 unsigned long arg);
167
168/* Register definitions, register access macros and drmAddMap constants
169 * for Rage 128 kernel driver.
170 */
171
172#define R128_AUX_SC_CNTL 0x1660
173# define R128_AUX1_SC_EN (1 << 0)
174# define R128_AUX1_SC_MODE_OR (0 << 1)
175# define R128_AUX1_SC_MODE_NAND (1 << 1)
176# define R128_AUX2_SC_EN (1 << 2)
177# define R128_AUX2_SC_MODE_OR (0 << 3)
178# define R128_AUX2_SC_MODE_NAND (1 << 3)
179# define R128_AUX3_SC_EN (1 << 4)
180# define R128_AUX3_SC_MODE_OR (0 << 5)
181# define R128_AUX3_SC_MODE_NAND (1 << 5)
182#define R128_AUX1_SC_LEFT 0x1664
183#define R128_AUX1_SC_RIGHT 0x1668
184#define R128_AUX1_SC_TOP 0x166c
185#define R128_AUX1_SC_BOTTOM 0x1670
186#define R128_AUX2_SC_LEFT 0x1674
187#define R128_AUX2_SC_RIGHT 0x1678
188#define R128_AUX2_SC_TOP 0x167c
189#define R128_AUX2_SC_BOTTOM 0x1680
190#define R128_AUX3_SC_LEFT 0x1684
191#define R128_AUX3_SC_RIGHT 0x1688
192#define R128_AUX3_SC_TOP 0x168c
193#define R128_AUX3_SC_BOTTOM 0x1690
194
195#define R128_BRUSH_DATA0 0x1480
196#define R128_BUS_CNTL 0x0030
197# define R128_BUS_MASTER_DIS (1 << 6)
198
199#define R128_CLOCK_CNTL_INDEX 0x0008
200#define R128_CLOCK_CNTL_DATA 0x000c
201# define R128_PLL_WR_EN (1 << 7)
202#define R128_CONSTANT_COLOR_C 0x1d34
203#define R128_CRTC_OFFSET 0x0224
204#define R128_CRTC_OFFSET_CNTL 0x0228
205# define R128_CRTC_OFFSET_FLIP_CNTL (1 << 16)
206
207#define R128_DP_GUI_MASTER_CNTL 0x146c
208# define R128_GMC_SRC_PITCH_OFFSET_CNTL (1 << 0)
209# define R128_GMC_DST_PITCH_OFFSET_CNTL (1 << 1)
210# define R128_GMC_BRUSH_SOLID_COLOR (13 << 4)
211# define R128_GMC_BRUSH_NONE (15 << 4)
212# define R128_GMC_DST_16BPP (4 << 8)
213# define R128_GMC_DST_24BPP (5 << 8)
214# define R128_GMC_DST_32BPP (6 << 8)
215# define R128_GMC_DST_DATATYPE_SHIFT 8
216# define R128_GMC_SRC_DATATYPE_COLOR (3 << 12)
217# define R128_DP_SRC_SOURCE_MEMORY (2 << 24)
218# define R128_DP_SRC_SOURCE_HOST_DATA (3 << 24)
219# define R128_GMC_CLR_CMP_CNTL_DIS (1 << 28)
220# define R128_GMC_AUX_CLIP_DIS (1 << 29)
221# define R128_GMC_WR_MSK_DIS (1 << 30)
222# define R128_ROP3_S 0x00cc0000
223# define R128_ROP3_P 0x00f00000
224#define R128_DP_WRITE_MASK 0x16cc
225#define R128_DST_PITCH_OFFSET_C 0x1c80
226# define R128_DST_TILE (1 << 31)
227
228#define R128_GEN_INT_CNTL 0x0040
229# define R128_CRTC_VBLANK_INT_EN (1 << 0)
230#define R128_GEN_INT_STATUS 0x0044
231# define R128_CRTC_VBLANK_INT (1 << 0)
232# define R128_CRTC_VBLANK_INT_AK (1 << 0)
233#define R128_GEN_RESET_CNTL 0x00f0
234# define R128_SOFT_RESET_GUI (1 << 0)
235
236#define R128_GUI_SCRATCH_REG0 0x15e0
237#define R128_GUI_SCRATCH_REG1 0x15e4
238#define R128_GUI_SCRATCH_REG2 0x15e8
239#define R128_GUI_SCRATCH_REG3 0x15ec
240#define R128_GUI_SCRATCH_REG4 0x15f0
241#define R128_GUI_SCRATCH_REG5 0x15f4
242
243#define R128_GUI_STAT 0x1740
244# define R128_GUI_FIFOCNT_MASK 0x0fff
245# define R128_GUI_ACTIVE (1 << 31)
246
247#define R128_MCLK_CNTL 0x000f
248# define R128_FORCE_GCP (1 << 16)
249# define R128_FORCE_PIPE3D_CP (1 << 17)
250# define R128_FORCE_RCP (1 << 18)
251
252#define R128_PC_GUI_CTLSTAT 0x1748
253#define R128_PC_NGUI_CTLSTAT 0x0184
254# define R128_PC_FLUSH_GUI (3 << 0)
255# define R128_PC_RI_GUI (1 << 2)
256# define R128_PC_FLUSH_ALL 0x00ff
257# define R128_PC_BUSY (1 << 31)
258
259#define R128_PCI_GART_PAGE 0x017c
260#define R128_PRIM_TEX_CNTL_C 0x1cb0
261
262#define R128_SCALE_3D_CNTL 0x1a00
263#define R128_SEC_TEX_CNTL_C 0x1d00
264#define R128_SEC_TEXTURE_BORDER_COLOR_C 0x1d3c
265#define R128_SETUP_CNTL 0x1bc4
266#define R128_STEN_REF_MASK_C 0x1d40
267
268#define R128_TEX_CNTL_C 0x1c9c
269# define R128_TEX_CACHE_FLUSH (1 << 23)
270
271#define R128_WAIT_UNTIL 0x1720
272# define R128_EVENT_CRTC_OFFSET (1 << 0)
273#define R128_WINDOW_XY_OFFSET 0x1bcc
274
275/* CCE registers
276 */
277#define R128_PM4_BUFFER_OFFSET 0x0700
278#define R128_PM4_BUFFER_CNTL 0x0704
279# define R128_PM4_MASK (15 << 28)
280# define R128_PM4_NONPM4 (0 << 28)
281# define R128_PM4_192PIO (1 << 28)
282# define R128_PM4_192BM (2 << 28)
283# define R128_PM4_128PIO_64INDBM (3 << 28)
284# define R128_PM4_128BM_64INDBM (4 << 28)
285# define R128_PM4_64PIO_128INDBM (5 << 28)
286# define R128_PM4_64BM_128INDBM (6 << 28)
287# define R128_PM4_64PIO_64VCBM_64INDBM (7 << 28)
288# define R128_PM4_64BM_64VCBM_64INDBM (8 << 28)
289# define R128_PM4_64PIO_64VCPIO_64INDPIO (15 << 28)
290# define R128_PM4_BUFFER_CNTL_NOUPDATE (1 << 27)
291
292#define R128_PM4_BUFFER_WM_CNTL 0x0708
293# define R128_WMA_SHIFT 0
294# define R128_WMB_SHIFT 8
295# define R128_WMC_SHIFT 16
296# define R128_WB_WM_SHIFT 24
297
298#define R128_PM4_BUFFER_DL_RPTR_ADDR 0x070c
299#define R128_PM4_BUFFER_DL_RPTR 0x0710
300#define R128_PM4_BUFFER_DL_WPTR 0x0714
301# define R128_PM4_BUFFER_DL_DONE (1 << 31)
302
303#define R128_PM4_VC_FPU_SETUP 0x071c
304
305#define R128_PM4_IW_INDOFF 0x0738
306#define R128_PM4_IW_INDSIZE 0x073c
307
308#define R128_PM4_STAT 0x07b8
309# define R128_PM4_FIFOCNT_MASK 0x0fff
310# define R128_PM4_BUSY (1 << 16)
311# define R128_PM4_GUI_ACTIVE (1 << 31)
312
313#define R128_PM4_MICROCODE_ADDR 0x07d4
314#define R128_PM4_MICROCODE_RADDR 0x07d8
315#define R128_PM4_MICROCODE_DATAH 0x07dc
316#define R128_PM4_MICROCODE_DATAL 0x07e0
317
318#define R128_PM4_BUFFER_ADDR 0x07f0
319#define R128_PM4_MICRO_CNTL 0x07fc
320# define R128_PM4_MICRO_FREERUN (1 << 30)
321
322#define R128_PM4_FIFO_DATA_EVEN 0x1000
323#define R128_PM4_FIFO_DATA_ODD 0x1004
324
325/* CCE command packets
326 */
327#define R128_CCE_PACKET0 0x00000000
328#define R128_CCE_PACKET1 0x40000000
329#define R128_CCE_PACKET2 0x80000000
330#define R128_CCE_PACKET3 0xC0000000
331# define R128_CNTL_HOSTDATA_BLT 0x00009400
332# define R128_CNTL_PAINT_MULTI 0x00009A00
333# define R128_CNTL_BITBLT_MULTI 0x00009B00
334# define R128_3D_RNDR_GEN_INDX_PRIM 0x00002300
335
336#define R128_CCE_PACKET_MASK 0xC0000000
337#define R128_CCE_PACKET_COUNT_MASK 0x3fff0000
338#define R128_CCE_PACKET0_REG_MASK 0x000007ff
339#define R128_CCE_PACKET1_REG0_MASK 0x000007ff
340#define R128_CCE_PACKET1_REG1_MASK 0x003ff800
341
342#define R128_CCE_VC_CNTL_PRIM_TYPE_NONE 0x00000000
343#define R128_CCE_VC_CNTL_PRIM_TYPE_POINT 0x00000001
344#define R128_CCE_VC_CNTL_PRIM_TYPE_LINE 0x00000002
345#define R128_CCE_VC_CNTL_PRIM_TYPE_POLY_LINE 0x00000003
346#define R128_CCE_VC_CNTL_PRIM_TYPE_TRI_LIST 0x00000004
347#define R128_CCE_VC_CNTL_PRIM_TYPE_TRI_FAN 0x00000005
348#define R128_CCE_VC_CNTL_PRIM_TYPE_TRI_STRIP 0x00000006
349#define R128_CCE_VC_CNTL_PRIM_TYPE_TRI_TYPE2 0x00000007
350#define R128_CCE_VC_CNTL_PRIM_WALK_IND 0x00000010
351#define R128_CCE_VC_CNTL_PRIM_WALK_LIST 0x00000020
352#define R128_CCE_VC_CNTL_PRIM_WALK_RING 0x00000030
353#define R128_CCE_VC_CNTL_NUM_SHIFT 16
354
355#define R128_DATATYPE_VQ 0
356#define R128_DATATYPE_CI4 1
357#define R128_DATATYPE_CI8 2
358#define R128_DATATYPE_ARGB1555 3
359#define R128_DATATYPE_RGB565 4
360#define R128_DATATYPE_RGB888 5
361#define R128_DATATYPE_ARGB8888 6
362#define R128_DATATYPE_RGB332 7
363#define R128_DATATYPE_Y8 8
364#define R128_DATATYPE_RGB8 9
365#define R128_DATATYPE_CI16 10
366#define R128_DATATYPE_YVYU422 11
367#define R128_DATATYPE_VYUY422 12
368#define R128_DATATYPE_AYUV444 14
369#define R128_DATATYPE_ARGB4444 15
370
371/* Constants */
372#define R128_AGP_OFFSET 0x02000000
373
374#define R128_WATERMARK_L 16
375#define R128_WATERMARK_M 8
376#define R128_WATERMARK_N 8
377#define R128_WATERMARK_K 128
378
379#define R128_MAX_USEC_TIMEOUT 100000 /* 100 ms */
380
381#define R128_LAST_FRAME_REG R128_GUI_SCRATCH_REG0
382#define R128_LAST_DISPATCH_REG R128_GUI_SCRATCH_REG1
383#define R128_MAX_VB_AGE 0x7fffffff
384#define R128_MAX_VB_VERTS (0xffff)
385
386#define R128_RING_HIGH_MARK 128
387
388#define R128_PERFORMANCE_BOXES 0
389
390#define R128_PCIGART_TABLE_SIZE 32768
391
392#define R128_READ(reg) DRM_READ32( dev_priv->mmio, (reg) )
393#define R128_WRITE(reg,val) DRM_WRITE32( dev_priv->mmio, (reg), (val) )
394#define R128_READ8(reg) DRM_READ8( dev_priv->mmio, (reg) )
395#define R128_WRITE8(reg,val) DRM_WRITE8( dev_priv->mmio, (reg), (val) )
396
397#define R128_WRITE_PLL(addr,val) \
398do { \
399 R128_WRITE8(R128_CLOCK_CNTL_INDEX, \
400 ((addr) & 0x1f) | R128_PLL_WR_EN); \
401 R128_WRITE(R128_CLOCK_CNTL_DATA, (val)); \
402} while (0)
403
404#define CCE_PACKET0( reg, n ) (R128_CCE_PACKET0 | \
405 ((n) << 16) | ((reg) >> 2))
406#define CCE_PACKET1( reg0, reg1 ) (R128_CCE_PACKET1 | \
407 (((reg1) >> 2) << 11) | ((reg0) >> 2))
408#define CCE_PACKET2() (R128_CCE_PACKET2)
409#define CCE_PACKET3( pkt, n ) (R128_CCE_PACKET3 | \
410 (pkt) | ((n) << 16))
411
412static __inline__ void r128_update_ring_snapshot(drm_r128_private_t * dev_priv)
413{
414 drm_r128_ring_buffer_t *ring = &dev_priv->ring;
415 ring->space = (GET_RING_HEAD(dev_priv) - ring->tail) * sizeof(u32);
416 if (ring->space <= 0)
417 ring->space += ring->size;
418}
419
420/* ================================================================
421 * Misc helper macros
422 */
423
424#define RING_SPACE_TEST_WITH_RETURN( dev_priv ) \
425do { \
426 drm_r128_ring_buffer_t *ring = &dev_priv->ring; int i; \
427 if ( ring->space < ring->high_mark ) { \
428 for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) { \
429 r128_update_ring_snapshot( dev_priv ); \
430 if ( ring->space >= ring->high_mark ) \
431 goto __ring_space_done; \
432 DRM_UDELAY(1); \
433 } \
434 DRM_ERROR( "ring space check failed!\n" ); \
435 return -EBUSY; \
436 } \
437 __ring_space_done: \
438 ; \
439} while (0)
440
441#define VB_AGE_TEST_WITH_RETURN( dev_priv ) \
442do { \
443 drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv; \
444 if ( sarea_priv->last_dispatch >= R128_MAX_VB_AGE ) { \
445 int __ret = r128_do_cce_idle( dev_priv ); \
446 if ( __ret ) return __ret; \
447 sarea_priv->last_dispatch = 0; \
448 r128_freelist_reset( dev ); \
449 } \
450} while (0)
451
452#define R128_WAIT_UNTIL_PAGE_FLIPPED() do { \
453 OUT_RING( CCE_PACKET0( R128_WAIT_UNTIL, 0 ) ); \
454 OUT_RING( R128_EVENT_CRTC_OFFSET ); \
455} while (0)
456
457/* ================================================================
458 * Ring control
459 */
460
461#define R128_VERBOSE 0
462
463#define RING_LOCALS \
464 int write, _nr; unsigned int tail_mask; volatile u32 *ring;
465
466#define BEGIN_RING( n ) do { \
467 if ( R128_VERBOSE ) { \
468 DRM_INFO( "BEGIN_RING( %d )\n", (n)); \
469 } \
470 if ( dev_priv->ring.space <= (n) * sizeof(u32) ) { \
471 COMMIT_RING(); \
472 r128_wait_ring( dev_priv, (n) * sizeof(u32) ); \
473 } \
474 _nr = n; dev_priv->ring.space -= (n) * sizeof(u32); \
475 ring = dev_priv->ring.start; \
476 write = dev_priv->ring.tail; \
477 tail_mask = dev_priv->ring.tail_mask; \
478} while (0)
479
480/* You can set this to zero if you want. If the card locks up, you'll
481 * need to keep this set. It works around a bug in early revs of the
482 * Rage 128 chipset, where the CCE would read 32 dwords past the end of
483 * the ring buffer before wrapping around.
484 */
485#define R128_BROKEN_CCE 1
486
487#define ADVANCE_RING() do { \
488 if ( R128_VERBOSE ) { \
489 DRM_INFO( "ADVANCE_RING() wr=0x%06x tail=0x%06x\n", \
490 write, dev_priv->ring.tail ); \
491 } \
492 if ( R128_BROKEN_CCE && write < 32 ) { \
493 memcpy( dev_priv->ring.end, \
494 dev_priv->ring.start, \
495 write * sizeof(u32) ); \
496 } \
497 if (((dev_priv->ring.tail + _nr) & tail_mask) != write) { \
498 DRM_ERROR( \
499 "ADVANCE_RING(): mismatch: nr: %x write: %x line: %d\n", \
500 ((dev_priv->ring.tail + _nr) & tail_mask), \
501 write, __LINE__); \
502 } else \
503 dev_priv->ring.tail = write; \
504} while (0)
505
506#define COMMIT_RING() do { \
507 if ( R128_VERBOSE ) { \
508 DRM_INFO( "COMMIT_RING() tail=0x%06x\n", \
509 dev_priv->ring.tail ); \
510 } \
511 DRM_MEMORYBARRIER(); \
512 R128_WRITE( R128_PM4_BUFFER_DL_WPTR, dev_priv->ring.tail ); \
513 R128_READ( R128_PM4_BUFFER_DL_WPTR ); \
514} while (0)
515
516#define OUT_RING( x ) do { \
517 if ( R128_VERBOSE ) { \
518 DRM_INFO( " OUT_RING( 0x%08x ) at 0x%x\n", \
519 (unsigned int)(x), write ); \
520 } \
521 ring[write++] = cpu_to_le32( x ); \
522 write &= tail_mask; \
523} while (0)
524
525#endif /* __R128_DRV_H__ */
diff --git a/drivers/char/drm/r128_ioc32.c b/drivers/char/drm/r128_ioc32.c
deleted file mode 100644
index d3cb676eee84..000000000000
--- a/drivers/char/drm/r128_ioc32.c
+++ /dev/null
@@ -1,221 +0,0 @@
1/**
2 * \file r128_ioc32.c
3 *
4 * 32-bit ioctl compatibility routines for the R128 DRM.
5 *
6 * \author Dave Airlie <airlied@linux.ie> with code from patches by Egbert Eich
7 *
8 * Copyright (C) Paul Mackerras 2005
9 * Copyright (C) Egbert Eich 2003,2004
10 * Copyright (C) Dave Airlie 2005
11 * All Rights Reserved.
12 *
13 * Permission is hereby granted, free of charge, to any person obtaining a
14 * copy of this software and associated documentation files (the "Software"),
15 * to deal in the Software without restriction, including without limitation
16 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
17 * and/or sell copies of the Software, and to permit persons to whom the
18 * Software is furnished to do so, subject to the following conditions:
19 *
20 * The above copyright notice and this permission notice (including the next
21 * paragraph) shall be included in all copies or substantial portions of the
22 * Software.
23 *
24 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
27 * THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
28 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
30 * IN THE SOFTWARE.
31 */
32#include <linux/compat.h>
33
34#include "drmP.h"
35#include "drm.h"
36#include "r128_drm.h"
37
38typedef struct drm_r128_init32 {
39 int func;
40 unsigned int sarea_priv_offset;
41 int is_pci;
42 int cce_mode;
43 int cce_secure;
44 int ring_size;
45 int usec_timeout;
46
47 unsigned int fb_bpp;
48 unsigned int front_offset, front_pitch;
49 unsigned int back_offset, back_pitch;
50 unsigned int depth_bpp;
51 unsigned int depth_offset, depth_pitch;
52 unsigned int span_offset;
53
54 unsigned int fb_offset;
55 unsigned int mmio_offset;
56 unsigned int ring_offset;
57 unsigned int ring_rptr_offset;
58 unsigned int buffers_offset;
59 unsigned int agp_textures_offset;
60} drm_r128_init32_t;
61
62static int compat_r128_init(struct file *file, unsigned int cmd,
63 unsigned long arg)
64{
65 drm_r128_init32_t init32;
66 drm_r128_init_t __user *init;
67
68 if (copy_from_user(&init32, (void __user *)arg, sizeof(init32)))
69 return -EFAULT;
70
71 init = compat_alloc_user_space(sizeof(*init));
72 if (!access_ok(VERIFY_WRITE, init, sizeof(*init))
73 || __put_user(init32.func, &init->func)
74 || __put_user(init32.sarea_priv_offset, &init->sarea_priv_offset)
75 || __put_user(init32.is_pci, &init->is_pci)
76 || __put_user(init32.cce_mode, &init->cce_mode)
77 || __put_user(init32.cce_secure, &init->cce_secure)
78 || __put_user(init32.ring_size, &init->ring_size)
79 || __put_user(init32.usec_timeout, &init->usec_timeout)
80 || __put_user(init32.fb_bpp, &init->fb_bpp)
81 || __put_user(init32.front_offset, &init->front_offset)
82 || __put_user(init32.front_pitch, &init->front_pitch)
83 || __put_user(init32.back_offset, &init->back_offset)
84 || __put_user(init32.back_pitch, &init->back_pitch)
85 || __put_user(init32.depth_bpp, &init->depth_bpp)
86 || __put_user(init32.depth_offset, &init->depth_offset)
87 || __put_user(init32.depth_pitch, &init->depth_pitch)
88 || __put_user(init32.span_offset, &init->span_offset)
89 || __put_user(init32.fb_offset, &init->fb_offset)
90 || __put_user(init32.mmio_offset, &init->mmio_offset)
91 || __put_user(init32.ring_offset, &init->ring_offset)
92 || __put_user(init32.ring_rptr_offset, &init->ring_rptr_offset)
93 || __put_user(init32.buffers_offset, &init->buffers_offset)
94 || __put_user(init32.agp_textures_offset,
95 &init->agp_textures_offset))
96 return -EFAULT;
97
98 return drm_ioctl(file->f_path.dentry->d_inode, file,
99 DRM_IOCTL_R128_INIT, (unsigned long)init);
100}
101
102typedef struct drm_r128_depth32 {
103 int func;
104 int n;
105 u32 x;
106 u32 y;
107 u32 buffer;
108 u32 mask;
109} drm_r128_depth32_t;
110
111static int compat_r128_depth(struct file *file, unsigned int cmd,
112 unsigned long arg)
113{
114 drm_r128_depth32_t depth32;
115 drm_r128_depth_t __user *depth;
116
117 if (copy_from_user(&depth32, (void __user *)arg, sizeof(depth32)))
118 return -EFAULT;
119
120 depth = compat_alloc_user_space(sizeof(*depth));
121 if (!access_ok(VERIFY_WRITE, depth, sizeof(*depth))
122 || __put_user(depth32.func, &depth->func)
123 || __put_user(depth32.n, &depth->n)
124 || __put_user((int __user *)(unsigned long)depth32.x, &depth->x)
125 || __put_user((int __user *)(unsigned long)depth32.y, &depth->y)
126 || __put_user((unsigned int __user *)(unsigned long)depth32.buffer,
127 &depth->buffer)
128 || __put_user((unsigned char __user *)(unsigned long)depth32.mask,
129 &depth->mask))
130 return -EFAULT;
131
132 return drm_ioctl(file->f_path.dentry->d_inode, file,
133 DRM_IOCTL_R128_DEPTH, (unsigned long)depth);
134
135}
136
137typedef struct drm_r128_stipple32 {
138 u32 mask;
139} drm_r128_stipple32_t;
140
141static int compat_r128_stipple(struct file *file, unsigned int cmd,
142 unsigned long arg)
143{
144 drm_r128_stipple32_t stipple32;
145 drm_r128_stipple_t __user *stipple;
146
147 if (copy_from_user(&stipple32, (void __user *)arg, sizeof(stipple32)))
148 return -EFAULT;
149
150 stipple = compat_alloc_user_space(sizeof(*stipple));
151 if (!access_ok(VERIFY_WRITE, stipple, sizeof(*stipple))
152 || __put_user((unsigned int __user *)(unsigned long)stipple32.mask,
153 &stipple->mask))
154 return -EFAULT;
155
156 return drm_ioctl(file->f_path.dentry->d_inode, file,
157 DRM_IOCTL_R128_STIPPLE, (unsigned long)stipple);
158}
159
160typedef struct drm_r128_getparam32 {
161 int param;
162 u32 value;
163} drm_r128_getparam32_t;
164
165static int compat_r128_getparam(struct file *file, unsigned int cmd,
166 unsigned long arg)
167{
168 drm_r128_getparam32_t getparam32;
169 drm_r128_getparam_t __user *getparam;
170
171 if (copy_from_user(&getparam32, (void __user *)arg, sizeof(getparam32)))
172 return -EFAULT;
173
174 getparam = compat_alloc_user_space(sizeof(*getparam));
175 if (!access_ok(VERIFY_WRITE, getparam, sizeof(*getparam))
176 || __put_user(getparam32.param, &getparam->param)
177 || __put_user((void __user *)(unsigned long)getparam32.value,
178 &getparam->value))
179 return -EFAULT;
180
181 return drm_ioctl(file->f_path.dentry->d_inode, file,
182 DRM_IOCTL_R128_GETPARAM, (unsigned long)getparam);
183}
184
185drm_ioctl_compat_t *r128_compat_ioctls[] = {
186 [DRM_R128_INIT] = compat_r128_init,
187 [DRM_R128_DEPTH] = compat_r128_depth,
188 [DRM_R128_STIPPLE] = compat_r128_stipple,
189 [DRM_R128_GETPARAM] = compat_r128_getparam,
190};
191
192/**
193 * Called whenever a 32-bit process running under a 64-bit kernel
194 * performs an ioctl on /dev/dri/card<n>.
195 *
196 * \param filp file pointer.
197 * \param cmd command.
198 * \param arg user argument.
199 * \return zero on success or negative number on failure.
200 */
201long r128_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
202{
203 unsigned int nr = DRM_IOCTL_NR(cmd);
204 drm_ioctl_compat_t *fn = NULL;
205 int ret;
206
207 if (nr < DRM_COMMAND_BASE)
208 return drm_compat_ioctl(filp, cmd, arg);
209
210 if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(r128_compat_ioctls))
211 fn = r128_compat_ioctls[nr - DRM_COMMAND_BASE];
212
213 lock_kernel(); /* XXX for now */
214 if (fn != NULL)
215 ret = (*fn) (filp, cmd, arg);
216 else
217 ret = drm_ioctl(filp->f_path.dentry->d_inode, filp, cmd, arg);
218 unlock_kernel();
219
220 return ret;
221}
diff --git a/drivers/char/drm/r128_irq.c b/drivers/char/drm/r128_irq.c
deleted file mode 100644
index 5b95bd898f95..000000000000
--- a/drivers/char/drm/r128_irq.c
+++ /dev/null
@@ -1,116 +0,0 @@
1/* r128_irq.c -- IRQ handling for radeon -*- linux-c -*- */
2/*
3 * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
4 *
5 * The Weather Channel (TM) funded Tungsten Graphics to develop the
6 * initial release of the Radeon 8500 driver under the XFree86 license.
7 * This notice must be preserved.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice (including the next
17 * paragraph) shall be included in all copies or substantial portions of the
18 * Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
24 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
25 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 * DEALINGS IN THE SOFTWARE.
27 *
28 * Authors:
29 * Keith Whitwell <keith@tungstengraphics.com>
30 * Eric Anholt <anholt@FreeBSD.org>
31 */
32
33#include "drmP.h"
34#include "drm.h"
35#include "r128_drm.h"
36#include "r128_drv.h"
37
38u32 r128_get_vblank_counter(struct drm_device *dev, int crtc)
39{
40 const drm_r128_private_t *dev_priv = dev->dev_private;
41
42 if (crtc != 0)
43 return 0;
44
45 return atomic_read(&dev_priv->vbl_received);
46}
47
48irqreturn_t r128_driver_irq_handler(DRM_IRQ_ARGS)
49{
50 struct drm_device *dev = (struct drm_device *) arg;
51 drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private;
52 int status;
53
54 status = R128_READ(R128_GEN_INT_STATUS);
55
56 /* VBLANK interrupt */
57 if (status & R128_CRTC_VBLANK_INT) {
58 R128_WRITE(R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK);
59 atomic_inc(&dev_priv->vbl_received);
60 drm_handle_vblank(dev, 0);
61 return IRQ_HANDLED;
62 }
63 return IRQ_NONE;
64}
65
66int r128_enable_vblank(struct drm_device *dev, int crtc)
67{
68 drm_r128_private_t *dev_priv = dev->dev_private;
69
70 if (crtc != 0) {
71 DRM_ERROR("%s: bad crtc %d\n", __FUNCTION__, crtc);
72 return -EINVAL;
73 }
74
75 R128_WRITE(R128_GEN_INT_CNTL, R128_CRTC_VBLANK_INT_EN);
76 return 0;
77}
78
79void r128_disable_vblank(struct drm_device *dev, int crtc)
80{
81 if (crtc != 0)
82 DRM_ERROR("%s: bad crtc %d\n", __FUNCTION__, crtc);
83
84 /*
85 * FIXME: implement proper interrupt disable by using the vblank
86 * counter register (if available)
87 *
88 * R128_WRITE(R128_GEN_INT_CNTL,
89 * R128_READ(R128_GEN_INT_CNTL) & ~R128_CRTC_VBLANK_INT_EN);
90 */
91}
92
93void r128_driver_irq_preinstall(struct drm_device * dev)
94{
95 drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private;
96
97 /* Disable *all* interrupts */
98 R128_WRITE(R128_GEN_INT_CNTL, 0);
99 /* Clear vblank bit if it's already high */
100 R128_WRITE(R128_GEN_INT_STATUS, R128_CRTC_VBLANK_INT_AK);
101}
102
103int r128_driver_irq_postinstall(struct drm_device * dev)
104{
105 return drm_vblank_init(dev, 1);
106}
107
108void r128_driver_irq_uninstall(struct drm_device * dev)
109{
110 drm_r128_private_t *dev_priv = (drm_r128_private_t *) dev->dev_private;
111 if (!dev_priv)
112 return;
113
114 /* Disable *all* interrupts */
115 R128_WRITE(R128_GEN_INT_CNTL, 0);
116}
diff --git a/drivers/char/drm/r128_state.c b/drivers/char/drm/r128_state.c
deleted file mode 100644
index 51a9afce7b9b..000000000000
--- a/drivers/char/drm/r128_state.c
+++ /dev/null
@@ -1,1681 +0,0 @@
1/* r128_state.c -- State support for r128 -*- linux-c -*-
2 * Created: Thu Jan 27 02:53:43 2000 by gareth@valinux.com
3 */
4/*
5 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
6 * All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice (including the next
16 * paragraph) shall be included in all copies or substantial portions of the
17 * Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
23 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 * DEALINGS IN THE SOFTWARE.
26 *
27 * Authors:
28 * Gareth Hughes <gareth@valinux.com>
29 */
30
31#include "drmP.h"
32#include "drm.h"
33#include "r128_drm.h"
34#include "r128_drv.h"
35
36/* ================================================================
37 * CCE hardware state programming functions
38 */
39
40static void r128_emit_clip_rects(drm_r128_private_t * dev_priv,
41 struct drm_clip_rect * boxes, int count)
42{
43 u32 aux_sc_cntl = 0x00000000;
44 RING_LOCALS;
45 DRM_DEBUG("\n");
46
47 BEGIN_RING((count < 3 ? count : 3) * 5 + 2);
48
49 if (count >= 1) {
50 OUT_RING(CCE_PACKET0(R128_AUX1_SC_LEFT, 3));
51 OUT_RING(boxes[0].x1);
52 OUT_RING(boxes[0].x2 - 1);
53 OUT_RING(boxes[0].y1);
54 OUT_RING(boxes[0].y2 - 1);
55
56 aux_sc_cntl |= (R128_AUX1_SC_EN | R128_AUX1_SC_MODE_OR);
57 }
58 if (count >= 2) {
59 OUT_RING(CCE_PACKET0(R128_AUX2_SC_LEFT, 3));
60 OUT_RING(boxes[1].x1);
61 OUT_RING(boxes[1].x2 - 1);
62 OUT_RING(boxes[1].y1);
63 OUT_RING(boxes[1].y2 - 1);
64
65 aux_sc_cntl |= (R128_AUX2_SC_EN | R128_AUX2_SC_MODE_OR);
66 }
67 if (count >= 3) {
68 OUT_RING(CCE_PACKET0(R128_AUX3_SC_LEFT, 3));
69 OUT_RING(boxes[2].x1);
70 OUT_RING(boxes[2].x2 - 1);
71 OUT_RING(boxes[2].y1);
72 OUT_RING(boxes[2].y2 - 1);
73
74 aux_sc_cntl |= (R128_AUX3_SC_EN | R128_AUX3_SC_MODE_OR);
75 }
76
77 OUT_RING(CCE_PACKET0(R128_AUX_SC_CNTL, 0));
78 OUT_RING(aux_sc_cntl);
79
80 ADVANCE_RING();
81}
82
83static __inline__ void r128_emit_core(drm_r128_private_t * dev_priv)
84{
85 drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
86 drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
87 RING_LOCALS;
88 DRM_DEBUG("\n");
89
90 BEGIN_RING(2);
91
92 OUT_RING(CCE_PACKET0(R128_SCALE_3D_CNTL, 0));
93 OUT_RING(ctx->scale_3d_cntl);
94
95 ADVANCE_RING();
96}
97
98static __inline__ void r128_emit_context(drm_r128_private_t * dev_priv)
99{
100 drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
101 drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
102 RING_LOCALS;
103 DRM_DEBUG("\n");
104
105 BEGIN_RING(13);
106
107 OUT_RING(CCE_PACKET0(R128_DST_PITCH_OFFSET_C, 11));
108 OUT_RING(ctx->dst_pitch_offset_c);
109 OUT_RING(ctx->dp_gui_master_cntl_c);
110 OUT_RING(ctx->sc_top_left_c);
111 OUT_RING(ctx->sc_bottom_right_c);
112 OUT_RING(ctx->z_offset_c);
113 OUT_RING(ctx->z_pitch_c);
114 OUT_RING(ctx->z_sten_cntl_c);
115 OUT_RING(ctx->tex_cntl_c);
116 OUT_RING(ctx->misc_3d_state_cntl_reg);
117 OUT_RING(ctx->texture_clr_cmp_clr_c);
118 OUT_RING(ctx->texture_clr_cmp_msk_c);
119 OUT_RING(ctx->fog_color_c);
120
121 ADVANCE_RING();
122}
123
124static __inline__ void r128_emit_setup(drm_r128_private_t * dev_priv)
125{
126 drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
127 drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
128 RING_LOCALS;
129 DRM_DEBUG("\n");
130
131 BEGIN_RING(3);
132
133 OUT_RING(CCE_PACKET1(R128_SETUP_CNTL, R128_PM4_VC_FPU_SETUP));
134 OUT_RING(ctx->setup_cntl);
135 OUT_RING(ctx->pm4_vc_fpu_setup);
136
137 ADVANCE_RING();
138}
139
140static __inline__ void r128_emit_masks(drm_r128_private_t * dev_priv)
141{
142 drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
143 drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
144 RING_LOCALS;
145 DRM_DEBUG("\n");
146
147 BEGIN_RING(5);
148
149 OUT_RING(CCE_PACKET0(R128_DP_WRITE_MASK, 0));
150 OUT_RING(ctx->dp_write_mask);
151
152 OUT_RING(CCE_PACKET0(R128_STEN_REF_MASK_C, 1));
153 OUT_RING(ctx->sten_ref_mask_c);
154 OUT_RING(ctx->plane_3d_mask_c);
155
156 ADVANCE_RING();
157}
158
159static __inline__ void r128_emit_window(drm_r128_private_t * dev_priv)
160{
161 drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
162 drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
163 RING_LOCALS;
164 DRM_DEBUG("\n");
165
166 BEGIN_RING(2);
167
168 OUT_RING(CCE_PACKET0(R128_WINDOW_XY_OFFSET, 0));
169 OUT_RING(ctx->window_xy_offset);
170
171 ADVANCE_RING();
172}
173
174static __inline__ void r128_emit_tex0(drm_r128_private_t * dev_priv)
175{
176 drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
177 drm_r128_context_regs_t *ctx = &sarea_priv->context_state;
178 drm_r128_texture_regs_t *tex = &sarea_priv->tex_state[0];
179 int i;
180 RING_LOCALS;
181 DRM_DEBUG("\n");
182
183 BEGIN_RING(7 + R128_MAX_TEXTURE_LEVELS);
184
185 OUT_RING(CCE_PACKET0(R128_PRIM_TEX_CNTL_C,
186 2 + R128_MAX_TEXTURE_LEVELS));
187 OUT_RING(tex->tex_cntl);
188 OUT_RING(tex->tex_combine_cntl);
189 OUT_RING(ctx->tex_size_pitch_c);
190 for (i = 0; i < R128_MAX_TEXTURE_LEVELS; i++) {
191 OUT_RING(tex->tex_offset[i]);
192 }
193
194 OUT_RING(CCE_PACKET0(R128_CONSTANT_COLOR_C, 1));
195 OUT_RING(ctx->constant_color_c);
196 OUT_RING(tex->tex_border_color);
197
198 ADVANCE_RING();
199}
200
201static __inline__ void r128_emit_tex1(drm_r128_private_t * dev_priv)
202{
203 drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
204 drm_r128_texture_regs_t *tex = &sarea_priv->tex_state[1];
205 int i;
206 RING_LOCALS;
207 DRM_DEBUG("\n");
208
209 BEGIN_RING(5 + R128_MAX_TEXTURE_LEVELS);
210
211 OUT_RING(CCE_PACKET0(R128_SEC_TEX_CNTL_C, 1 + R128_MAX_TEXTURE_LEVELS));
212 OUT_RING(tex->tex_cntl);
213 OUT_RING(tex->tex_combine_cntl);
214 for (i = 0; i < R128_MAX_TEXTURE_LEVELS; i++) {
215 OUT_RING(tex->tex_offset[i]);
216 }
217
218 OUT_RING(CCE_PACKET0(R128_SEC_TEXTURE_BORDER_COLOR_C, 0));
219 OUT_RING(tex->tex_border_color);
220
221 ADVANCE_RING();
222}
223
224static void r128_emit_state(drm_r128_private_t * dev_priv)
225{
226 drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
227 unsigned int dirty = sarea_priv->dirty;
228
229 DRM_DEBUG("dirty=0x%08x\n", dirty);
230
231 if (dirty & R128_UPLOAD_CORE) {
232 r128_emit_core(dev_priv);
233 sarea_priv->dirty &= ~R128_UPLOAD_CORE;
234 }
235
236 if (dirty & R128_UPLOAD_CONTEXT) {
237 r128_emit_context(dev_priv);
238 sarea_priv->dirty &= ~R128_UPLOAD_CONTEXT;
239 }
240
241 if (dirty & R128_UPLOAD_SETUP) {
242 r128_emit_setup(dev_priv);
243 sarea_priv->dirty &= ~R128_UPLOAD_SETUP;
244 }
245
246 if (dirty & R128_UPLOAD_MASKS) {
247 r128_emit_masks(dev_priv);
248 sarea_priv->dirty &= ~R128_UPLOAD_MASKS;
249 }
250
251 if (dirty & R128_UPLOAD_WINDOW) {
252 r128_emit_window(dev_priv);
253 sarea_priv->dirty &= ~R128_UPLOAD_WINDOW;
254 }
255
256 if (dirty & R128_UPLOAD_TEX0) {
257 r128_emit_tex0(dev_priv);
258 sarea_priv->dirty &= ~R128_UPLOAD_TEX0;
259 }
260
261 if (dirty & R128_UPLOAD_TEX1) {
262 r128_emit_tex1(dev_priv);
263 sarea_priv->dirty &= ~R128_UPLOAD_TEX1;
264 }
265
266 /* Turn off the texture cache flushing */
267 sarea_priv->context_state.tex_cntl_c &= ~R128_TEX_CACHE_FLUSH;
268
269 sarea_priv->dirty &= ~R128_REQUIRE_QUIESCENCE;
270}
271
272#if R128_PERFORMANCE_BOXES
273/* ================================================================
274 * Performance monitoring functions
275 */
276
277static void r128_clear_box(drm_r128_private_t * dev_priv,
278 int x, int y, int w, int h, int r, int g, int b)
279{
280 u32 pitch, offset;
281 u32 fb_bpp, color;
282 RING_LOCALS;
283
284 switch (dev_priv->fb_bpp) {
285 case 16:
286 fb_bpp = R128_GMC_DST_16BPP;
287 color = (((r & 0xf8) << 8) |
288 ((g & 0xfc) << 3) | ((b & 0xf8) >> 3));
289 break;
290 case 24:
291 fb_bpp = R128_GMC_DST_24BPP;
292 color = ((r << 16) | (g << 8) | b);
293 break;
294 case 32:
295 fb_bpp = R128_GMC_DST_32BPP;
296 color = (((0xff) << 24) | (r << 16) | (g << 8) | b);
297 break;
298 default:
299 return;
300 }
301
302 offset = dev_priv->back_offset;
303 pitch = dev_priv->back_pitch >> 3;
304
305 BEGIN_RING(6);
306
307 OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4));
308 OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL |
309 R128_GMC_BRUSH_SOLID_COLOR |
310 fb_bpp |
311 R128_GMC_SRC_DATATYPE_COLOR |
312 R128_ROP3_P |
313 R128_GMC_CLR_CMP_CNTL_DIS | R128_GMC_AUX_CLIP_DIS);
314
315 OUT_RING((pitch << 21) | (offset >> 5));
316 OUT_RING(color);
317
318 OUT_RING((x << 16) | y);
319 OUT_RING((w << 16) | h);
320
321 ADVANCE_RING();
322}
323
324static void r128_cce_performance_boxes(drm_r128_private_t * dev_priv)
325{
326 if (atomic_read(&dev_priv->idle_count) == 0) {
327 r128_clear_box(dev_priv, 64, 4, 8, 8, 0, 255, 0);
328 } else {
329 atomic_set(&dev_priv->idle_count, 0);
330 }
331}
332
333#endif
334
335/* ================================================================
336 * CCE command dispatch functions
337 */
338
339static void r128_print_dirty(const char *msg, unsigned int flags)
340{
341 DRM_INFO("%s: (0x%x) %s%s%s%s%s%s%s%s%s\n",
342 msg,
343 flags,
344 (flags & R128_UPLOAD_CORE) ? "core, " : "",
345 (flags & R128_UPLOAD_CONTEXT) ? "context, " : "",
346 (flags & R128_UPLOAD_SETUP) ? "setup, " : "",
347 (flags & R128_UPLOAD_TEX0) ? "tex0, " : "",
348 (flags & R128_UPLOAD_TEX1) ? "tex1, " : "",
349 (flags & R128_UPLOAD_MASKS) ? "masks, " : "",
350 (flags & R128_UPLOAD_WINDOW) ? "window, " : "",
351 (flags & R128_UPLOAD_CLIPRECTS) ? "cliprects, " : "",
352 (flags & R128_REQUIRE_QUIESCENCE) ? "quiescence, " : "");
353}
354
355static void r128_cce_dispatch_clear(struct drm_device * dev,
356 drm_r128_clear_t * clear)
357{
358 drm_r128_private_t *dev_priv = dev->dev_private;
359 drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
360 int nbox = sarea_priv->nbox;
361 struct drm_clip_rect *pbox = sarea_priv->boxes;
362 unsigned int flags = clear->flags;
363 int i;
364 RING_LOCALS;
365 DRM_DEBUG("\n");
366
367 if (dev_priv->page_flipping && dev_priv->current_page == 1) {
368 unsigned int tmp = flags;
369
370 flags &= ~(R128_FRONT | R128_BACK);
371 if (tmp & R128_FRONT)
372 flags |= R128_BACK;
373 if (tmp & R128_BACK)
374 flags |= R128_FRONT;
375 }
376
377 for (i = 0; i < nbox; i++) {
378 int x = pbox[i].x1;
379 int y = pbox[i].y1;
380 int w = pbox[i].x2 - x;
381 int h = pbox[i].y2 - y;
382
383 DRM_DEBUG("dispatch clear %d,%d-%d,%d flags 0x%x\n",
384 pbox[i].x1, pbox[i].y1, pbox[i].x2,
385 pbox[i].y2, flags);
386
387 if (flags & (R128_FRONT | R128_BACK)) {
388 BEGIN_RING(2);
389
390 OUT_RING(CCE_PACKET0(R128_DP_WRITE_MASK, 0));
391 OUT_RING(clear->color_mask);
392
393 ADVANCE_RING();
394 }
395
396 if (flags & R128_FRONT) {
397 BEGIN_RING(6);
398
399 OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4));
400 OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL |
401 R128_GMC_BRUSH_SOLID_COLOR |
402 (dev_priv->color_fmt << 8) |
403 R128_GMC_SRC_DATATYPE_COLOR |
404 R128_ROP3_P |
405 R128_GMC_CLR_CMP_CNTL_DIS |
406 R128_GMC_AUX_CLIP_DIS);
407
408 OUT_RING(dev_priv->front_pitch_offset_c);
409 OUT_RING(clear->clear_color);
410
411 OUT_RING((x << 16) | y);
412 OUT_RING((w << 16) | h);
413
414 ADVANCE_RING();
415 }
416
417 if (flags & R128_BACK) {
418 BEGIN_RING(6);
419
420 OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4));
421 OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL |
422 R128_GMC_BRUSH_SOLID_COLOR |
423 (dev_priv->color_fmt << 8) |
424 R128_GMC_SRC_DATATYPE_COLOR |
425 R128_ROP3_P |
426 R128_GMC_CLR_CMP_CNTL_DIS |
427 R128_GMC_AUX_CLIP_DIS);
428
429 OUT_RING(dev_priv->back_pitch_offset_c);
430 OUT_RING(clear->clear_color);
431
432 OUT_RING((x << 16) | y);
433 OUT_RING((w << 16) | h);
434
435 ADVANCE_RING();
436 }
437
438 if (flags & R128_DEPTH) {
439 BEGIN_RING(6);
440
441 OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4));
442 OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL |
443 R128_GMC_BRUSH_SOLID_COLOR |
444 (dev_priv->depth_fmt << 8) |
445 R128_GMC_SRC_DATATYPE_COLOR |
446 R128_ROP3_P |
447 R128_GMC_CLR_CMP_CNTL_DIS |
448 R128_GMC_AUX_CLIP_DIS | R128_GMC_WR_MSK_DIS);
449
450 OUT_RING(dev_priv->depth_pitch_offset_c);
451 OUT_RING(clear->clear_depth);
452
453 OUT_RING((x << 16) | y);
454 OUT_RING((w << 16) | h);
455
456 ADVANCE_RING();
457 }
458 }
459}
460
461static void r128_cce_dispatch_swap(struct drm_device * dev)
462{
463 drm_r128_private_t *dev_priv = dev->dev_private;
464 drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
465 int nbox = sarea_priv->nbox;
466 struct drm_clip_rect *pbox = sarea_priv->boxes;
467 int i;
468 RING_LOCALS;
469 DRM_DEBUG("\n");
470
471#if R128_PERFORMANCE_BOXES
472 /* Do some trivial performance monitoring...
473 */
474 r128_cce_performance_boxes(dev_priv);
475#endif
476
477 for (i = 0; i < nbox; i++) {
478 int x = pbox[i].x1;
479 int y = pbox[i].y1;
480 int w = pbox[i].x2 - x;
481 int h = pbox[i].y2 - y;
482
483 BEGIN_RING(7);
484
485 OUT_RING(CCE_PACKET3(R128_CNTL_BITBLT_MULTI, 5));
486 OUT_RING(R128_GMC_SRC_PITCH_OFFSET_CNTL |
487 R128_GMC_DST_PITCH_OFFSET_CNTL |
488 R128_GMC_BRUSH_NONE |
489 (dev_priv->color_fmt << 8) |
490 R128_GMC_SRC_DATATYPE_COLOR |
491 R128_ROP3_S |
492 R128_DP_SRC_SOURCE_MEMORY |
493 R128_GMC_CLR_CMP_CNTL_DIS |
494 R128_GMC_AUX_CLIP_DIS | R128_GMC_WR_MSK_DIS);
495
496 /* Make this work even if front & back are flipped:
497 */
498 if (dev_priv->current_page == 0) {
499 OUT_RING(dev_priv->back_pitch_offset_c);
500 OUT_RING(dev_priv->front_pitch_offset_c);
501 } else {
502 OUT_RING(dev_priv->front_pitch_offset_c);
503 OUT_RING(dev_priv->back_pitch_offset_c);
504 }
505
506 OUT_RING((x << 16) | y);
507 OUT_RING((x << 16) | y);
508 OUT_RING((w << 16) | h);
509
510 ADVANCE_RING();
511 }
512
513 /* Increment the frame counter. The client-side 3D driver must
514 * throttle the framerate by waiting for this value before
515 * performing the swapbuffer ioctl.
516 */
517 dev_priv->sarea_priv->last_frame++;
518
519 BEGIN_RING(2);
520
521 OUT_RING(CCE_PACKET0(R128_LAST_FRAME_REG, 0));
522 OUT_RING(dev_priv->sarea_priv->last_frame);
523
524 ADVANCE_RING();
525}
526
527static void r128_cce_dispatch_flip(struct drm_device * dev)
528{
529 drm_r128_private_t *dev_priv = dev->dev_private;
530 RING_LOCALS;
531 DRM_DEBUG("page=%d pfCurrentPage=%d\n",
532 dev_priv->current_page, dev_priv->sarea_priv->pfCurrentPage);
533
534#if R128_PERFORMANCE_BOXES
535 /* Do some trivial performance monitoring...
536 */
537 r128_cce_performance_boxes(dev_priv);
538#endif
539
540 BEGIN_RING(4);
541
542 R128_WAIT_UNTIL_PAGE_FLIPPED();
543 OUT_RING(CCE_PACKET0(R128_CRTC_OFFSET, 0));
544
545 if (dev_priv->current_page == 0) {
546 OUT_RING(dev_priv->back_offset);
547 } else {
548 OUT_RING(dev_priv->front_offset);
549 }
550
551 ADVANCE_RING();
552
553 /* Increment the frame counter. The client-side 3D driver must
554 * throttle the framerate by waiting for this value before
555 * performing the swapbuffer ioctl.
556 */
557 dev_priv->sarea_priv->last_frame++;
558 dev_priv->sarea_priv->pfCurrentPage = dev_priv->current_page =
559 1 - dev_priv->current_page;
560
561 BEGIN_RING(2);
562
563 OUT_RING(CCE_PACKET0(R128_LAST_FRAME_REG, 0));
564 OUT_RING(dev_priv->sarea_priv->last_frame);
565
566 ADVANCE_RING();
567}
568
569static void r128_cce_dispatch_vertex(struct drm_device * dev, struct drm_buf * buf)
570{
571 drm_r128_private_t *dev_priv = dev->dev_private;
572 drm_r128_buf_priv_t *buf_priv = buf->dev_private;
573 drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
574 int format = sarea_priv->vc_format;
575 int offset = buf->bus_address;
576 int size = buf->used;
577 int prim = buf_priv->prim;
578 int i = 0;
579 RING_LOCALS;
580 DRM_DEBUG("buf=%d nbox=%d\n", buf->idx, sarea_priv->nbox);
581
582 if (0)
583 r128_print_dirty("dispatch_vertex", sarea_priv->dirty);
584
585 if (buf->used) {
586 buf_priv->dispatched = 1;
587
588 if (sarea_priv->dirty & ~R128_UPLOAD_CLIPRECTS) {
589 r128_emit_state(dev_priv);
590 }
591
592 do {
593 /* Emit the next set of up to three cliprects */
594 if (i < sarea_priv->nbox) {
595 r128_emit_clip_rects(dev_priv,
596 &sarea_priv->boxes[i],
597 sarea_priv->nbox - i);
598 }
599
600 /* Emit the vertex buffer rendering commands */
601 BEGIN_RING(5);
602
603 OUT_RING(CCE_PACKET3(R128_3D_RNDR_GEN_INDX_PRIM, 3));
604 OUT_RING(offset);
605 OUT_RING(size);
606 OUT_RING(format);
607 OUT_RING(prim | R128_CCE_VC_CNTL_PRIM_WALK_LIST |
608 (size << R128_CCE_VC_CNTL_NUM_SHIFT));
609
610 ADVANCE_RING();
611
612 i += 3;
613 } while (i < sarea_priv->nbox);
614 }
615
616 if (buf_priv->discard) {
617 buf_priv->age = dev_priv->sarea_priv->last_dispatch;
618
619 /* Emit the vertex buffer age */
620 BEGIN_RING(2);
621
622 OUT_RING(CCE_PACKET0(R128_LAST_DISPATCH_REG, 0));
623 OUT_RING(buf_priv->age);
624
625 ADVANCE_RING();
626
627 buf->pending = 1;
628 buf->used = 0;
629 /* FIXME: Check dispatched field */
630 buf_priv->dispatched = 0;
631 }
632
633 dev_priv->sarea_priv->last_dispatch++;
634
635 sarea_priv->dirty &= ~R128_UPLOAD_CLIPRECTS;
636 sarea_priv->nbox = 0;
637}
638
639static void r128_cce_dispatch_indirect(struct drm_device * dev,
640 struct drm_buf * buf, int start, int end)
641{
642 drm_r128_private_t *dev_priv = dev->dev_private;
643 drm_r128_buf_priv_t *buf_priv = buf->dev_private;
644 RING_LOCALS;
645 DRM_DEBUG("indirect: buf=%d s=0x%x e=0x%x\n", buf->idx, start, end);
646
647 if (start != end) {
648 int offset = buf->bus_address + start;
649 int dwords = (end - start + 3) / sizeof(u32);
650
651 /* Indirect buffer data must be an even number of
652 * dwords, so if we've been given an odd number we must
653 * pad the data with a Type-2 CCE packet.
654 */
655 if (dwords & 1) {
656 u32 *data = (u32 *)
657 ((char *)dev->agp_buffer_map->handle
658 + buf->offset + start);
659 data[dwords++] = cpu_to_le32(R128_CCE_PACKET2);
660 }
661
662 buf_priv->dispatched = 1;
663
664 /* Fire off the indirect buffer */
665 BEGIN_RING(3);
666
667 OUT_RING(CCE_PACKET0(R128_PM4_IW_INDOFF, 1));
668 OUT_RING(offset);
669 OUT_RING(dwords);
670
671 ADVANCE_RING();
672 }
673
674 if (buf_priv->discard) {
675 buf_priv->age = dev_priv->sarea_priv->last_dispatch;
676
677 /* Emit the indirect buffer age */
678 BEGIN_RING(2);
679
680 OUT_RING(CCE_PACKET0(R128_LAST_DISPATCH_REG, 0));
681 OUT_RING(buf_priv->age);
682
683 ADVANCE_RING();
684
685 buf->pending = 1;
686 buf->used = 0;
687 /* FIXME: Check dispatched field */
688 buf_priv->dispatched = 0;
689 }
690
691 dev_priv->sarea_priv->last_dispatch++;
692}
693
694static void r128_cce_dispatch_indices(struct drm_device * dev,
695 struct drm_buf * buf,
696 int start, int end, int count)
697{
698 drm_r128_private_t *dev_priv = dev->dev_private;
699 drm_r128_buf_priv_t *buf_priv = buf->dev_private;
700 drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
701 int format = sarea_priv->vc_format;
702 int offset = dev->agp_buffer_map->offset - dev_priv->cce_buffers_offset;
703 int prim = buf_priv->prim;
704 u32 *data;
705 int dwords;
706 int i = 0;
707 RING_LOCALS;
708 DRM_DEBUG("indices: s=%d e=%d c=%d\n", start, end, count);
709
710 if (0)
711 r128_print_dirty("dispatch_indices", sarea_priv->dirty);
712
713 if (start != end) {
714 buf_priv->dispatched = 1;
715
716 if (sarea_priv->dirty & ~R128_UPLOAD_CLIPRECTS) {
717 r128_emit_state(dev_priv);
718 }
719
720 dwords = (end - start + 3) / sizeof(u32);
721
722 data = (u32 *) ((char *)dev->agp_buffer_map->handle
723 + buf->offset + start);
724
725 data[0] = cpu_to_le32(CCE_PACKET3(R128_3D_RNDR_GEN_INDX_PRIM,
726 dwords - 2));
727
728 data[1] = cpu_to_le32(offset);
729 data[2] = cpu_to_le32(R128_MAX_VB_VERTS);
730 data[3] = cpu_to_le32(format);
731 data[4] = cpu_to_le32((prim | R128_CCE_VC_CNTL_PRIM_WALK_IND |
732 (count << 16)));
733
734 if (count & 0x1) {
735#ifdef __LITTLE_ENDIAN
736 data[dwords - 1] &= 0x0000ffff;
737#else
738 data[dwords - 1] &= 0xffff0000;
739#endif
740 }
741
742 do {
743 /* Emit the next set of up to three cliprects */
744 if (i < sarea_priv->nbox) {
745 r128_emit_clip_rects(dev_priv,
746 &sarea_priv->boxes[i],
747 sarea_priv->nbox - i);
748 }
749
750 r128_cce_dispatch_indirect(dev, buf, start, end);
751
752 i += 3;
753 } while (i < sarea_priv->nbox);
754 }
755
756 if (buf_priv->discard) {
757 buf_priv->age = dev_priv->sarea_priv->last_dispatch;
758
759 /* Emit the vertex buffer age */
760 BEGIN_RING(2);
761
762 OUT_RING(CCE_PACKET0(R128_LAST_DISPATCH_REG, 0));
763 OUT_RING(buf_priv->age);
764
765 ADVANCE_RING();
766
767 buf->pending = 1;
768 /* FIXME: Check dispatched field */
769 buf_priv->dispatched = 0;
770 }
771
772 dev_priv->sarea_priv->last_dispatch++;
773
774 sarea_priv->dirty &= ~R128_UPLOAD_CLIPRECTS;
775 sarea_priv->nbox = 0;
776}
777
778static int r128_cce_dispatch_blit(struct drm_device * dev,
779 struct drm_file *file_priv,
780 drm_r128_blit_t * blit)
781{
782 drm_r128_private_t *dev_priv = dev->dev_private;
783 struct drm_device_dma *dma = dev->dma;
784 struct drm_buf *buf;
785 drm_r128_buf_priv_t *buf_priv;
786 u32 *data;
787 int dword_shift, dwords;
788 RING_LOCALS;
789 DRM_DEBUG("\n");
790
791 /* The compiler won't optimize away a division by a variable,
792 * even if the only legal values are powers of two. Thus, we'll
793 * use a shift instead.
794 */
795 switch (blit->format) {
796 case R128_DATATYPE_ARGB8888:
797 dword_shift = 0;
798 break;
799 case R128_DATATYPE_ARGB1555:
800 case R128_DATATYPE_RGB565:
801 case R128_DATATYPE_ARGB4444:
802 case R128_DATATYPE_YVYU422:
803 case R128_DATATYPE_VYUY422:
804 dword_shift = 1;
805 break;
806 case R128_DATATYPE_CI8:
807 case R128_DATATYPE_RGB8:
808 dword_shift = 2;
809 break;
810 default:
811 DRM_ERROR("invalid blit format %d\n", blit->format);
812 return -EINVAL;
813 }
814
815 /* Flush the pixel cache, and mark the contents as Read Invalid.
816 * This ensures no pixel data gets mixed up with the texture
817 * data from the host data blit, otherwise part of the texture
818 * image may be corrupted.
819 */
820 BEGIN_RING(2);
821
822 OUT_RING(CCE_PACKET0(R128_PC_GUI_CTLSTAT, 0));
823 OUT_RING(R128_PC_RI_GUI | R128_PC_FLUSH_GUI);
824
825 ADVANCE_RING();
826
827 /* Dispatch the indirect buffer.
828 */
829 buf = dma->buflist[blit->idx];
830 buf_priv = buf->dev_private;
831
832 if (buf->file_priv != file_priv) {
833 DRM_ERROR("process %d using buffer owned by %p\n",
834 DRM_CURRENTPID, buf->file_priv);
835 return -EINVAL;
836 }
837 if (buf->pending) {
838 DRM_ERROR("sending pending buffer %d\n", blit->idx);
839 return -EINVAL;
840 }
841
842 buf_priv->discard = 1;
843
844 dwords = (blit->width * blit->height) >> dword_shift;
845
846 data = (u32 *) ((char *)dev->agp_buffer_map->handle + buf->offset);
847
848 data[0] = cpu_to_le32(CCE_PACKET3(R128_CNTL_HOSTDATA_BLT, dwords + 6));
849 data[1] = cpu_to_le32((R128_GMC_DST_PITCH_OFFSET_CNTL |
850 R128_GMC_BRUSH_NONE |
851 (blit->format << 8) |
852 R128_GMC_SRC_DATATYPE_COLOR |
853 R128_ROP3_S |
854 R128_DP_SRC_SOURCE_HOST_DATA |
855 R128_GMC_CLR_CMP_CNTL_DIS |
856 R128_GMC_AUX_CLIP_DIS | R128_GMC_WR_MSK_DIS));
857
858 data[2] = cpu_to_le32((blit->pitch << 21) | (blit->offset >> 5));
859 data[3] = cpu_to_le32(0xffffffff);
860 data[4] = cpu_to_le32(0xffffffff);
861 data[5] = cpu_to_le32((blit->y << 16) | blit->x);
862 data[6] = cpu_to_le32((blit->height << 16) | blit->width);
863 data[7] = cpu_to_le32(dwords);
864
865 buf->used = (dwords + 8) * sizeof(u32);
866
867 r128_cce_dispatch_indirect(dev, buf, 0, buf->used);
868
869 /* Flush the pixel cache after the blit completes. This ensures
870 * the texture data is written out to memory before rendering
871 * continues.
872 */
873 BEGIN_RING(2);
874
875 OUT_RING(CCE_PACKET0(R128_PC_GUI_CTLSTAT, 0));
876 OUT_RING(R128_PC_FLUSH_GUI);
877
878 ADVANCE_RING();
879
880 return 0;
881}
882
883/* ================================================================
884 * Tiled depth buffer management
885 *
886 * FIXME: These should all set the destination write mask for when we
887 * have hardware stencil support.
888 */
889
890static int r128_cce_dispatch_write_span(struct drm_device * dev,
891 drm_r128_depth_t * depth)
892{
893 drm_r128_private_t *dev_priv = dev->dev_private;
894 int count, x, y;
895 u32 *buffer;
896 u8 *mask;
897 int i, buffer_size, mask_size;
898 RING_LOCALS;
899 DRM_DEBUG("\n");
900
901 count = depth->n;
902 if (count > 4096 || count <= 0)
903 return -EMSGSIZE;
904
905 if (DRM_COPY_FROM_USER(&x, depth->x, sizeof(x))) {
906 return -EFAULT;
907 }
908 if (DRM_COPY_FROM_USER(&y, depth->y, sizeof(y))) {
909 return -EFAULT;
910 }
911
912 buffer_size = depth->n * sizeof(u32);
913 buffer = drm_alloc(buffer_size, DRM_MEM_BUFS);
914 if (buffer == NULL)
915 return -ENOMEM;
916 if (DRM_COPY_FROM_USER(buffer, depth->buffer, buffer_size)) {
917 drm_free(buffer, buffer_size, DRM_MEM_BUFS);
918 return -EFAULT;
919 }
920
921 mask_size = depth->n * sizeof(u8);
922 if (depth->mask) {
923 mask = drm_alloc(mask_size, DRM_MEM_BUFS);
924 if (mask == NULL) {
925 drm_free(buffer, buffer_size, DRM_MEM_BUFS);
926 return -ENOMEM;
927 }
928 if (DRM_COPY_FROM_USER(mask, depth->mask, mask_size)) {
929 drm_free(buffer, buffer_size, DRM_MEM_BUFS);
930 drm_free(mask, mask_size, DRM_MEM_BUFS);
931 return -EFAULT;
932 }
933
934 for (i = 0; i < count; i++, x++) {
935 if (mask[i]) {
936 BEGIN_RING(6);
937
938 OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4));
939 OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL |
940 R128_GMC_BRUSH_SOLID_COLOR |
941 (dev_priv->depth_fmt << 8) |
942 R128_GMC_SRC_DATATYPE_COLOR |
943 R128_ROP3_P |
944 R128_GMC_CLR_CMP_CNTL_DIS |
945 R128_GMC_WR_MSK_DIS);
946
947 OUT_RING(dev_priv->depth_pitch_offset_c);
948 OUT_RING(buffer[i]);
949
950 OUT_RING((x << 16) | y);
951 OUT_RING((1 << 16) | 1);
952
953 ADVANCE_RING();
954 }
955 }
956
957 drm_free(mask, mask_size, DRM_MEM_BUFS);
958 } else {
959 for (i = 0; i < count; i++, x++) {
960 BEGIN_RING(6);
961
962 OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4));
963 OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL |
964 R128_GMC_BRUSH_SOLID_COLOR |
965 (dev_priv->depth_fmt << 8) |
966 R128_GMC_SRC_DATATYPE_COLOR |
967 R128_ROP3_P |
968 R128_GMC_CLR_CMP_CNTL_DIS |
969 R128_GMC_WR_MSK_DIS);
970
971 OUT_RING(dev_priv->depth_pitch_offset_c);
972 OUT_RING(buffer[i]);
973
974 OUT_RING((x << 16) | y);
975 OUT_RING((1 << 16) | 1);
976
977 ADVANCE_RING();
978 }
979 }
980
981 drm_free(buffer, buffer_size, DRM_MEM_BUFS);
982
983 return 0;
984}
985
986static int r128_cce_dispatch_write_pixels(struct drm_device * dev,
987 drm_r128_depth_t * depth)
988{
989 drm_r128_private_t *dev_priv = dev->dev_private;
990 int count, *x, *y;
991 u32 *buffer;
992 u8 *mask;
993 int i, xbuf_size, ybuf_size, buffer_size, mask_size;
994 RING_LOCALS;
995 DRM_DEBUG("\n");
996
997 count = depth->n;
998 if (count > 4096 || count <= 0)
999 return -EMSGSIZE;
1000
1001 xbuf_size = count * sizeof(*x);
1002 ybuf_size = count * sizeof(*y);
1003 x = drm_alloc(xbuf_size, DRM_MEM_BUFS);
1004 if (x == NULL) {
1005 return -ENOMEM;
1006 }
1007 y = drm_alloc(ybuf_size, DRM_MEM_BUFS);
1008 if (y == NULL) {
1009 drm_free(x, xbuf_size, DRM_MEM_BUFS);
1010 return -ENOMEM;
1011 }
1012 if (DRM_COPY_FROM_USER(x, depth->x, xbuf_size)) {
1013 drm_free(x, xbuf_size, DRM_MEM_BUFS);
1014 drm_free(y, ybuf_size, DRM_MEM_BUFS);
1015 return -EFAULT;
1016 }
1017 if (DRM_COPY_FROM_USER(y, depth->y, xbuf_size)) {
1018 drm_free(x, xbuf_size, DRM_MEM_BUFS);
1019 drm_free(y, ybuf_size, DRM_MEM_BUFS);
1020 return -EFAULT;
1021 }
1022
1023 buffer_size = depth->n * sizeof(u32);
1024 buffer = drm_alloc(buffer_size, DRM_MEM_BUFS);
1025 if (buffer == NULL) {
1026 drm_free(x, xbuf_size, DRM_MEM_BUFS);
1027 drm_free(y, ybuf_size, DRM_MEM_BUFS);
1028 return -ENOMEM;
1029 }
1030 if (DRM_COPY_FROM_USER(buffer, depth->buffer, buffer_size)) {
1031 drm_free(x, xbuf_size, DRM_MEM_BUFS);
1032 drm_free(y, ybuf_size, DRM_MEM_BUFS);
1033 drm_free(buffer, buffer_size, DRM_MEM_BUFS);
1034 return -EFAULT;
1035 }
1036
1037 if (depth->mask) {
1038 mask_size = depth->n * sizeof(u8);
1039 mask = drm_alloc(mask_size, DRM_MEM_BUFS);
1040 if (mask == NULL) {
1041 drm_free(x, xbuf_size, DRM_MEM_BUFS);
1042 drm_free(y, ybuf_size, DRM_MEM_BUFS);
1043 drm_free(buffer, buffer_size, DRM_MEM_BUFS);
1044 return -ENOMEM;
1045 }
1046 if (DRM_COPY_FROM_USER(mask, depth->mask, mask_size)) {
1047 drm_free(x, xbuf_size, DRM_MEM_BUFS);
1048 drm_free(y, ybuf_size, DRM_MEM_BUFS);
1049 drm_free(buffer, buffer_size, DRM_MEM_BUFS);
1050 drm_free(mask, mask_size, DRM_MEM_BUFS);
1051 return -EFAULT;
1052 }
1053
1054 for (i = 0; i < count; i++) {
1055 if (mask[i]) {
1056 BEGIN_RING(6);
1057
1058 OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4));
1059 OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL |
1060 R128_GMC_BRUSH_SOLID_COLOR |
1061 (dev_priv->depth_fmt << 8) |
1062 R128_GMC_SRC_DATATYPE_COLOR |
1063 R128_ROP3_P |
1064 R128_GMC_CLR_CMP_CNTL_DIS |
1065 R128_GMC_WR_MSK_DIS);
1066
1067 OUT_RING(dev_priv->depth_pitch_offset_c);
1068 OUT_RING(buffer[i]);
1069
1070 OUT_RING((x[i] << 16) | y[i]);
1071 OUT_RING((1 << 16) | 1);
1072
1073 ADVANCE_RING();
1074 }
1075 }
1076
1077 drm_free(mask, mask_size, DRM_MEM_BUFS);
1078 } else {
1079 for (i = 0; i < count; i++) {
1080 BEGIN_RING(6);
1081
1082 OUT_RING(CCE_PACKET3(R128_CNTL_PAINT_MULTI, 4));
1083 OUT_RING(R128_GMC_DST_PITCH_OFFSET_CNTL |
1084 R128_GMC_BRUSH_SOLID_COLOR |
1085 (dev_priv->depth_fmt << 8) |
1086 R128_GMC_SRC_DATATYPE_COLOR |
1087 R128_ROP3_P |
1088 R128_GMC_CLR_CMP_CNTL_DIS |
1089 R128_GMC_WR_MSK_DIS);
1090
1091 OUT_RING(dev_priv->depth_pitch_offset_c);
1092 OUT_RING(buffer[i]);
1093
1094 OUT_RING((x[i] << 16) | y[i]);
1095 OUT_RING((1 << 16) | 1);
1096
1097 ADVANCE_RING();
1098 }
1099 }
1100
1101 drm_free(x, xbuf_size, DRM_MEM_BUFS);
1102 drm_free(y, ybuf_size, DRM_MEM_BUFS);
1103 drm_free(buffer, buffer_size, DRM_MEM_BUFS);
1104
1105 return 0;
1106}
1107
1108static int r128_cce_dispatch_read_span(struct drm_device * dev,
1109 drm_r128_depth_t * depth)
1110{
1111 drm_r128_private_t *dev_priv = dev->dev_private;
1112 int count, x, y;
1113 RING_LOCALS;
1114 DRM_DEBUG("\n");
1115
1116 count = depth->n;
1117 if (count > 4096 || count <= 0)
1118 return -EMSGSIZE;
1119
1120 if (DRM_COPY_FROM_USER(&x, depth->x, sizeof(x))) {
1121 return -EFAULT;
1122 }
1123 if (DRM_COPY_FROM_USER(&y, depth->y, sizeof(y))) {
1124 return -EFAULT;
1125 }
1126
1127 BEGIN_RING(7);
1128
1129 OUT_RING(CCE_PACKET3(R128_CNTL_BITBLT_MULTI, 5));
1130 OUT_RING(R128_GMC_SRC_PITCH_OFFSET_CNTL |
1131 R128_GMC_DST_PITCH_OFFSET_CNTL |
1132 R128_GMC_BRUSH_NONE |
1133 (dev_priv->depth_fmt << 8) |
1134 R128_GMC_SRC_DATATYPE_COLOR |
1135 R128_ROP3_S |
1136 R128_DP_SRC_SOURCE_MEMORY |
1137 R128_GMC_CLR_CMP_CNTL_DIS | R128_GMC_WR_MSK_DIS);
1138
1139 OUT_RING(dev_priv->depth_pitch_offset_c);
1140 OUT_RING(dev_priv->span_pitch_offset_c);
1141
1142 OUT_RING((x << 16) | y);
1143 OUT_RING((0 << 16) | 0);
1144 OUT_RING((count << 16) | 1);
1145
1146 ADVANCE_RING();
1147
1148 return 0;
1149}
1150
1151static int r128_cce_dispatch_read_pixels(struct drm_device * dev,
1152 drm_r128_depth_t * depth)
1153{
1154 drm_r128_private_t *dev_priv = dev->dev_private;
1155 int count, *x, *y;
1156 int i, xbuf_size, ybuf_size;
1157 RING_LOCALS;
1158 DRM_DEBUG("\n");
1159
1160 count = depth->n;
1161 if (count > 4096 || count <= 0)
1162 return -EMSGSIZE;
1163
1164 if (count > dev_priv->depth_pitch) {
1165 count = dev_priv->depth_pitch;
1166 }
1167
1168 xbuf_size = count * sizeof(*x);
1169 ybuf_size = count * sizeof(*y);
1170 x = drm_alloc(xbuf_size, DRM_MEM_BUFS);
1171 if (x == NULL) {
1172 return -ENOMEM;
1173 }
1174 y = drm_alloc(ybuf_size, DRM_MEM_BUFS);
1175 if (y == NULL) {
1176 drm_free(x, xbuf_size, DRM_MEM_BUFS);
1177 return -ENOMEM;
1178 }
1179 if (DRM_COPY_FROM_USER(x, depth->x, xbuf_size)) {
1180 drm_free(x, xbuf_size, DRM_MEM_BUFS);
1181 drm_free(y, ybuf_size, DRM_MEM_BUFS);
1182 return -EFAULT;
1183 }
1184 if (DRM_COPY_FROM_USER(y, depth->y, ybuf_size)) {
1185 drm_free(x, xbuf_size, DRM_MEM_BUFS);
1186 drm_free(y, ybuf_size, DRM_MEM_BUFS);
1187 return -EFAULT;
1188 }
1189
1190 for (i = 0; i < count; i++) {
1191 BEGIN_RING(7);
1192
1193 OUT_RING(CCE_PACKET3(R128_CNTL_BITBLT_MULTI, 5));
1194 OUT_RING(R128_GMC_SRC_PITCH_OFFSET_CNTL |
1195 R128_GMC_DST_PITCH_OFFSET_CNTL |
1196 R128_GMC_BRUSH_NONE |
1197 (dev_priv->depth_fmt << 8) |
1198 R128_GMC_SRC_DATATYPE_COLOR |
1199 R128_ROP3_S |
1200 R128_DP_SRC_SOURCE_MEMORY |
1201 R128_GMC_CLR_CMP_CNTL_DIS | R128_GMC_WR_MSK_DIS);
1202
1203 OUT_RING(dev_priv->depth_pitch_offset_c);
1204 OUT_RING(dev_priv->span_pitch_offset_c);
1205
1206 OUT_RING((x[i] << 16) | y[i]);
1207 OUT_RING((i << 16) | 0);
1208 OUT_RING((1 << 16) | 1);
1209
1210 ADVANCE_RING();
1211 }
1212
1213 drm_free(x, xbuf_size, DRM_MEM_BUFS);
1214 drm_free(y, ybuf_size, DRM_MEM_BUFS);
1215
1216 return 0;
1217}
1218
1219/* ================================================================
1220 * Polygon stipple
1221 */
1222
1223static void r128_cce_dispatch_stipple(struct drm_device * dev, u32 * stipple)
1224{
1225 drm_r128_private_t *dev_priv = dev->dev_private;
1226 int i;
1227 RING_LOCALS;
1228 DRM_DEBUG("\n");
1229
1230 BEGIN_RING(33);
1231
1232 OUT_RING(CCE_PACKET0(R128_BRUSH_DATA0, 31));
1233 for (i = 0; i < 32; i++) {
1234 OUT_RING(stipple[i]);
1235 }
1236
1237 ADVANCE_RING();
1238}
1239
1240/* ================================================================
1241 * IOCTL functions
1242 */
1243
1244static int r128_cce_clear(struct drm_device *dev, void *data, struct drm_file *file_priv)
1245{
1246 drm_r128_private_t *dev_priv = dev->dev_private;
1247 drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
1248 drm_r128_clear_t *clear = data;
1249 DRM_DEBUG("\n");
1250
1251 LOCK_TEST_WITH_RETURN(dev, file_priv);
1252
1253 RING_SPACE_TEST_WITH_RETURN(dev_priv);
1254
1255 if (sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS)
1256 sarea_priv->nbox = R128_NR_SAREA_CLIPRECTS;
1257
1258 r128_cce_dispatch_clear(dev, clear);
1259 COMMIT_RING();
1260
1261 /* Make sure we restore the 3D state next time.
1262 */
1263 dev_priv->sarea_priv->dirty |= R128_UPLOAD_CONTEXT | R128_UPLOAD_MASKS;
1264
1265 return 0;
1266}
1267
1268static int r128_do_init_pageflip(struct drm_device * dev)
1269{
1270 drm_r128_private_t *dev_priv = dev->dev_private;
1271 DRM_DEBUG("\n");
1272
1273 dev_priv->crtc_offset = R128_READ(R128_CRTC_OFFSET);
1274 dev_priv->crtc_offset_cntl = R128_READ(R128_CRTC_OFFSET_CNTL);
1275
1276 R128_WRITE(R128_CRTC_OFFSET, dev_priv->front_offset);
1277 R128_WRITE(R128_CRTC_OFFSET_CNTL,
1278 dev_priv->crtc_offset_cntl | R128_CRTC_OFFSET_FLIP_CNTL);
1279
1280 dev_priv->page_flipping = 1;
1281 dev_priv->current_page = 0;
1282 dev_priv->sarea_priv->pfCurrentPage = dev_priv->current_page;
1283
1284 return 0;
1285}
1286
1287static int r128_do_cleanup_pageflip(struct drm_device * dev)
1288{
1289 drm_r128_private_t *dev_priv = dev->dev_private;
1290 DRM_DEBUG("\n");
1291
1292 R128_WRITE(R128_CRTC_OFFSET, dev_priv->crtc_offset);
1293 R128_WRITE(R128_CRTC_OFFSET_CNTL, dev_priv->crtc_offset_cntl);
1294
1295 if (dev_priv->current_page != 0) {
1296 r128_cce_dispatch_flip(dev);
1297 COMMIT_RING();
1298 }
1299
1300 dev_priv->page_flipping = 0;
1301 return 0;
1302}
1303
1304/* Swapping and flipping are different operations, need different ioctls.
1305 * They can & should be intermixed to support multiple 3d windows.
1306 */
1307
1308static int r128_cce_flip(struct drm_device *dev, void *data, struct drm_file *file_priv)
1309{
1310 drm_r128_private_t *dev_priv = dev->dev_private;
1311 DRM_DEBUG("\n");
1312
1313 LOCK_TEST_WITH_RETURN(dev, file_priv);
1314
1315 RING_SPACE_TEST_WITH_RETURN(dev_priv);
1316
1317 if (!dev_priv->page_flipping)
1318 r128_do_init_pageflip(dev);
1319
1320 r128_cce_dispatch_flip(dev);
1321
1322 COMMIT_RING();
1323 return 0;
1324}
1325
1326static int r128_cce_swap(struct drm_device *dev, void *data, struct drm_file *file_priv)
1327{
1328 drm_r128_private_t *dev_priv = dev->dev_private;
1329 drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
1330 DRM_DEBUG("\n");
1331
1332 LOCK_TEST_WITH_RETURN(dev, file_priv);
1333
1334 RING_SPACE_TEST_WITH_RETURN(dev_priv);
1335
1336 if (sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS)
1337 sarea_priv->nbox = R128_NR_SAREA_CLIPRECTS;
1338
1339 r128_cce_dispatch_swap(dev);
1340 dev_priv->sarea_priv->dirty |= (R128_UPLOAD_CONTEXT |
1341 R128_UPLOAD_MASKS);
1342
1343 COMMIT_RING();
1344 return 0;
1345}
1346
1347static int r128_cce_vertex(struct drm_device *dev, void *data, struct drm_file *file_priv)
1348{
1349 drm_r128_private_t *dev_priv = dev->dev_private;
1350 struct drm_device_dma *dma = dev->dma;
1351 struct drm_buf *buf;
1352 drm_r128_buf_priv_t *buf_priv;
1353 drm_r128_vertex_t *vertex = data;
1354
1355 LOCK_TEST_WITH_RETURN(dev, file_priv);
1356
1357 if (!dev_priv) {
1358 DRM_ERROR("called with no initialization\n");
1359 return -EINVAL;
1360 }
1361
1362 DRM_DEBUG("pid=%d index=%d count=%d discard=%d\n",
1363 DRM_CURRENTPID, vertex->idx, vertex->count, vertex->discard);
1364
1365 if (vertex->idx < 0 || vertex->idx >= dma->buf_count) {
1366 DRM_ERROR("buffer index %d (of %d max)\n",
1367 vertex->idx, dma->buf_count - 1);
1368 return -EINVAL;
1369 }
1370 if (vertex->prim < 0 ||
1371 vertex->prim > R128_CCE_VC_CNTL_PRIM_TYPE_TRI_TYPE2) {
1372 DRM_ERROR("buffer prim %d\n", vertex->prim);
1373 return -EINVAL;
1374 }
1375
1376 RING_SPACE_TEST_WITH_RETURN(dev_priv);
1377 VB_AGE_TEST_WITH_RETURN(dev_priv);
1378
1379 buf = dma->buflist[vertex->idx];
1380 buf_priv = buf->dev_private;
1381
1382 if (buf->file_priv != file_priv) {
1383 DRM_ERROR("process %d using buffer owned by %p\n",
1384 DRM_CURRENTPID, buf->file_priv);
1385 return -EINVAL;
1386 }
1387 if (buf->pending) {
1388 DRM_ERROR("sending pending buffer %d\n", vertex->idx);
1389 return -EINVAL;
1390 }
1391
1392 buf->used = vertex->count;
1393 buf_priv->prim = vertex->prim;
1394 buf_priv->discard = vertex->discard;
1395
1396 r128_cce_dispatch_vertex(dev, buf);
1397
1398 COMMIT_RING();
1399 return 0;
1400}
1401
1402static int r128_cce_indices(struct drm_device *dev, void *data, struct drm_file *file_priv)
1403{
1404 drm_r128_private_t *dev_priv = dev->dev_private;
1405 struct drm_device_dma *dma = dev->dma;
1406 struct drm_buf *buf;
1407 drm_r128_buf_priv_t *buf_priv;
1408 drm_r128_indices_t *elts = data;
1409 int count;
1410
1411 LOCK_TEST_WITH_RETURN(dev, file_priv);
1412
1413 if (!dev_priv) {
1414 DRM_ERROR("called with no initialization\n");
1415 return -EINVAL;
1416 }
1417
1418 DRM_DEBUG("pid=%d buf=%d s=%d e=%d d=%d\n", DRM_CURRENTPID,
1419 elts->idx, elts->start, elts->end, elts->discard);
1420
1421 if (elts->idx < 0 || elts->idx >= dma->buf_count) {
1422 DRM_ERROR("buffer index %d (of %d max)\n",
1423 elts->idx, dma->buf_count - 1);
1424 return -EINVAL;
1425 }
1426 if (elts->prim < 0 ||
1427 elts->prim > R128_CCE_VC_CNTL_PRIM_TYPE_TRI_TYPE2) {
1428 DRM_ERROR("buffer prim %d\n", elts->prim);
1429 return -EINVAL;
1430 }
1431
1432 RING_SPACE_TEST_WITH_RETURN(dev_priv);
1433 VB_AGE_TEST_WITH_RETURN(dev_priv);
1434
1435 buf = dma->buflist[elts->idx];
1436 buf_priv = buf->dev_private;
1437
1438 if (buf->file_priv != file_priv) {
1439 DRM_ERROR("process %d using buffer owned by %p\n",
1440 DRM_CURRENTPID, buf->file_priv);
1441 return -EINVAL;
1442 }
1443 if (buf->pending) {
1444 DRM_ERROR("sending pending buffer %d\n", elts->idx);
1445 return -EINVAL;
1446 }
1447
1448 count = (elts->end - elts->start) / sizeof(u16);
1449 elts->start -= R128_INDEX_PRIM_OFFSET;
1450
1451 if (elts->start & 0x7) {
1452 DRM_ERROR("misaligned buffer 0x%x\n", elts->start);
1453 return -EINVAL;
1454 }
1455 if (elts->start < buf->used) {
1456 DRM_ERROR("no header 0x%x - 0x%x\n", elts->start, buf->used);
1457 return -EINVAL;
1458 }
1459
1460 buf->used = elts->end;
1461 buf_priv->prim = elts->prim;
1462 buf_priv->discard = elts->discard;
1463
1464 r128_cce_dispatch_indices(dev, buf, elts->start, elts->end, count);
1465
1466 COMMIT_RING();
1467 return 0;
1468}
1469
1470static int r128_cce_blit(struct drm_device *dev, void *data, struct drm_file *file_priv)
1471{
1472 struct drm_device_dma *dma = dev->dma;
1473 drm_r128_private_t *dev_priv = dev->dev_private;
1474 drm_r128_blit_t *blit = data;
1475 int ret;
1476
1477 LOCK_TEST_WITH_RETURN(dev, file_priv);
1478
1479 DRM_DEBUG("pid=%d index=%d\n", DRM_CURRENTPID, blit->idx);
1480
1481 if (blit->idx < 0 || blit->idx >= dma->buf_count) {
1482 DRM_ERROR("buffer index %d (of %d max)\n",
1483 blit->idx, dma->buf_count - 1);
1484 return -EINVAL;
1485 }
1486
1487 RING_SPACE_TEST_WITH_RETURN(dev_priv);
1488 VB_AGE_TEST_WITH_RETURN(dev_priv);
1489
1490 ret = r128_cce_dispatch_blit(dev, file_priv, blit);
1491
1492 COMMIT_RING();
1493 return ret;
1494}
1495
1496static int r128_cce_depth(struct drm_device *dev, void *data, struct drm_file *file_priv)
1497{
1498 drm_r128_private_t *dev_priv = dev->dev_private;
1499 drm_r128_depth_t *depth = data;
1500 int ret;
1501
1502 LOCK_TEST_WITH_RETURN(dev, file_priv);
1503
1504 RING_SPACE_TEST_WITH_RETURN(dev_priv);
1505
1506 ret = -EINVAL;
1507 switch (depth->func) {
1508 case R128_WRITE_SPAN:
1509 ret = r128_cce_dispatch_write_span(dev, depth);
1510 break;
1511 case R128_WRITE_PIXELS:
1512 ret = r128_cce_dispatch_write_pixels(dev, depth);
1513 break;
1514 case R128_READ_SPAN:
1515 ret = r128_cce_dispatch_read_span(dev, depth);
1516 break;
1517 case R128_READ_PIXELS:
1518 ret = r128_cce_dispatch_read_pixels(dev, depth);
1519 break;
1520 }
1521
1522 COMMIT_RING();
1523 return ret;
1524}
1525
1526static int r128_cce_stipple(struct drm_device *dev, void *data, struct drm_file *file_priv)
1527{
1528 drm_r128_private_t *dev_priv = dev->dev_private;
1529 drm_r128_stipple_t *stipple = data;
1530 u32 mask[32];
1531
1532 LOCK_TEST_WITH_RETURN(dev, file_priv);
1533
1534 if (DRM_COPY_FROM_USER(&mask, stipple->mask, 32 * sizeof(u32)))
1535 return -EFAULT;
1536
1537 RING_SPACE_TEST_WITH_RETURN(dev_priv);
1538
1539 r128_cce_dispatch_stipple(dev, mask);
1540
1541 COMMIT_RING();
1542 return 0;
1543}
1544
1545static int r128_cce_indirect(struct drm_device *dev, void *data, struct drm_file *file_priv)
1546{
1547 drm_r128_private_t *dev_priv = dev->dev_private;
1548 struct drm_device_dma *dma = dev->dma;
1549 struct drm_buf *buf;
1550 drm_r128_buf_priv_t *buf_priv;
1551 drm_r128_indirect_t *indirect = data;
1552#if 0
1553 RING_LOCALS;
1554#endif
1555
1556 LOCK_TEST_WITH_RETURN(dev, file_priv);
1557
1558 if (!dev_priv) {
1559 DRM_ERROR("called with no initialization\n");
1560 return -EINVAL;
1561 }
1562
1563 DRM_DEBUG("idx=%d s=%d e=%d d=%d\n",
1564 indirect->idx, indirect->start, indirect->end,
1565 indirect->discard);
1566
1567 if (indirect->idx < 0 || indirect->idx >= dma->buf_count) {
1568 DRM_ERROR("buffer index %d (of %d max)\n",
1569 indirect->idx, dma->buf_count - 1);
1570 return -EINVAL;
1571 }
1572
1573 buf = dma->buflist[indirect->idx];
1574 buf_priv = buf->dev_private;
1575
1576 if (buf->file_priv != file_priv) {
1577 DRM_ERROR("process %d using buffer owned by %p\n",
1578 DRM_CURRENTPID, buf->file_priv);
1579 return -EINVAL;
1580 }
1581 if (buf->pending) {
1582 DRM_ERROR("sending pending buffer %d\n", indirect->idx);
1583 return -EINVAL;
1584 }
1585
1586 if (indirect->start < buf->used) {
1587 DRM_ERROR("reusing indirect: start=0x%x actual=0x%x\n",
1588 indirect->start, buf->used);
1589 return -EINVAL;
1590 }
1591
1592 RING_SPACE_TEST_WITH_RETURN(dev_priv);
1593 VB_AGE_TEST_WITH_RETURN(dev_priv);
1594
1595 buf->used = indirect->end;
1596 buf_priv->discard = indirect->discard;
1597
1598#if 0
1599 /* Wait for the 3D stream to idle before the indirect buffer
1600 * containing 2D acceleration commands is processed.
1601 */
1602 BEGIN_RING(2);
1603 RADEON_WAIT_UNTIL_3D_IDLE();
1604 ADVANCE_RING();
1605#endif
1606
1607 /* Dispatch the indirect buffer full of commands from the
1608 * X server. This is insecure and is thus only available to
1609 * privileged clients.
1610 */
1611 r128_cce_dispatch_indirect(dev, buf, indirect->start, indirect->end);
1612
1613 COMMIT_RING();
1614 return 0;
1615}
1616
1617static int r128_getparam(struct drm_device *dev, void *data, struct drm_file *file_priv)
1618{
1619 drm_r128_private_t *dev_priv = dev->dev_private;
1620 drm_r128_getparam_t *param = data;
1621 int value;
1622
1623 if (!dev_priv) {
1624 DRM_ERROR("called with no initialization\n");
1625 return -EINVAL;
1626 }
1627
1628 DRM_DEBUG("pid=%d\n", DRM_CURRENTPID);
1629
1630 switch (param->param) {
1631 case R128_PARAM_IRQ_NR:
1632 value = dev->irq;
1633 break;
1634 default:
1635 return -EINVAL;
1636 }
1637
1638 if (DRM_COPY_TO_USER(param->value, &value, sizeof(int))) {
1639 DRM_ERROR("copy_to_user\n");
1640 return -EFAULT;
1641 }
1642
1643 return 0;
1644}
1645
1646void r128_driver_preclose(struct drm_device * dev, struct drm_file *file_priv)
1647{
1648 if (dev->dev_private) {
1649 drm_r128_private_t *dev_priv = dev->dev_private;
1650 if (dev_priv->page_flipping) {
1651 r128_do_cleanup_pageflip(dev);
1652 }
1653 }
1654}
1655
1656void r128_driver_lastclose(struct drm_device * dev)
1657{
1658 r128_do_cleanup_cce(dev);
1659}
1660
1661struct drm_ioctl_desc r128_ioctls[] = {
1662 DRM_IOCTL_DEF(DRM_R128_INIT, r128_cce_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
1663 DRM_IOCTL_DEF(DRM_R128_CCE_START, r128_cce_start, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
1664 DRM_IOCTL_DEF(DRM_R128_CCE_STOP, r128_cce_stop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
1665 DRM_IOCTL_DEF(DRM_R128_CCE_RESET, r128_cce_reset, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
1666 DRM_IOCTL_DEF(DRM_R128_CCE_IDLE, r128_cce_idle, DRM_AUTH),
1667 DRM_IOCTL_DEF(DRM_R128_RESET, r128_engine_reset, DRM_AUTH),
1668 DRM_IOCTL_DEF(DRM_R128_FULLSCREEN, r128_fullscreen, DRM_AUTH),
1669 DRM_IOCTL_DEF(DRM_R128_SWAP, r128_cce_swap, DRM_AUTH),
1670 DRM_IOCTL_DEF(DRM_R128_FLIP, r128_cce_flip, DRM_AUTH),
1671 DRM_IOCTL_DEF(DRM_R128_CLEAR, r128_cce_clear, DRM_AUTH),
1672 DRM_IOCTL_DEF(DRM_R128_VERTEX, r128_cce_vertex, DRM_AUTH),
1673 DRM_IOCTL_DEF(DRM_R128_INDICES, r128_cce_indices, DRM_AUTH),
1674 DRM_IOCTL_DEF(DRM_R128_BLIT, r128_cce_blit, DRM_AUTH),
1675 DRM_IOCTL_DEF(DRM_R128_DEPTH, r128_cce_depth, DRM_AUTH),
1676 DRM_IOCTL_DEF(DRM_R128_STIPPLE, r128_cce_stipple, DRM_AUTH),
1677 DRM_IOCTL_DEF(DRM_R128_INDIRECT, r128_cce_indirect, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
1678 DRM_IOCTL_DEF(DRM_R128_GETPARAM, r128_getparam, DRM_AUTH),
1679};
1680
1681int r128_max_ioctl = DRM_ARRAY_SIZE(r128_ioctls);
diff --git a/drivers/char/drm/r300_cmdbuf.c b/drivers/char/drm/r300_cmdbuf.c
deleted file mode 100644
index f535812e4057..000000000000
--- a/drivers/char/drm/r300_cmdbuf.c
+++ /dev/null
@@ -1,998 +0,0 @@
1/* r300_cmdbuf.c -- Command buffer emission for R300 -*- linux-c -*-
2 *
3 * Copyright (C) The Weather Channel, Inc. 2002.
4 * Copyright (C) 2004 Nicolai Haehnle.
5 * All Rights Reserved.
6 *
7 * The Weather Channel (TM) funded Tungsten Graphics to develop the
8 * initial release of the Radeon 8500 driver under the XFree86 license.
9 * This notice must be preserved.
10 *
11 * Permission is hereby granted, free of charge, to any person obtaining a
12 * copy of this software and associated documentation files (the "Software"),
13 * to deal in the Software without restriction, including without limitation
14 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 * and/or sell copies of the Software, and to permit persons to whom the
16 * Software is furnished to do so, subject to the following conditions:
17 *
18 * The above copyright notice and this permission notice (including the next
19 * paragraph) shall be included in all copies or substantial portions of the
20 * Software.
21 *
22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
26 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
27 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
28 * DEALINGS IN THE SOFTWARE.
29 *
30 * Authors:
31 * Nicolai Haehnle <prefect_@gmx.net>
32 */
33
34#include "drmP.h"
35#include "drm.h"
36#include "radeon_drm.h"
37#include "radeon_drv.h"
38#include "r300_reg.h"
39
40#define R300_SIMULTANEOUS_CLIPRECTS 4
41
42/* Values for R300_RE_CLIPRECT_CNTL depending on the number of cliprects
43 */
44static const int r300_cliprect_cntl[4] = {
45 0xAAAA,
46 0xEEEE,
47 0xFEFE,
48 0xFFFE
49};
50
51/**
52 * Emit up to R300_SIMULTANEOUS_CLIPRECTS cliprects from the given command
53 * buffer, starting with index n.
54 */
55static int r300_emit_cliprects(drm_radeon_private_t *dev_priv,
56 drm_radeon_kcmd_buffer_t *cmdbuf, int n)
57{
58 struct drm_clip_rect box;
59 int nr;
60 int i;
61 RING_LOCALS;
62
63 nr = cmdbuf->nbox - n;
64 if (nr > R300_SIMULTANEOUS_CLIPRECTS)
65 nr = R300_SIMULTANEOUS_CLIPRECTS;
66
67 DRM_DEBUG("%i cliprects\n", nr);
68
69 if (nr) {
70 BEGIN_RING(6 + nr * 2);
71 OUT_RING(CP_PACKET0(R300_RE_CLIPRECT_TL_0, nr * 2 - 1));
72
73 for (i = 0; i < nr; ++i) {
74 if (DRM_COPY_FROM_USER_UNCHECKED
75 (&box, &cmdbuf->boxes[n + i], sizeof(box))) {
76 DRM_ERROR("copy cliprect faulted\n");
77 return -EFAULT;
78 }
79
80 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV515) {
81 box.x1 = (box.x1) &
82 R300_CLIPRECT_MASK;
83 box.y1 = (box.y1) &
84 R300_CLIPRECT_MASK;
85 box.x2 = (box.x2) &
86 R300_CLIPRECT_MASK;
87 box.y2 = (box.y2) &
88 R300_CLIPRECT_MASK;
89 } else {
90 box.x1 = (box.x1 + R300_CLIPRECT_OFFSET) &
91 R300_CLIPRECT_MASK;
92 box.y1 = (box.y1 + R300_CLIPRECT_OFFSET) &
93 R300_CLIPRECT_MASK;
94 box.x2 = (box.x2 + R300_CLIPRECT_OFFSET) &
95 R300_CLIPRECT_MASK;
96 box.y2 = (box.y2 + R300_CLIPRECT_OFFSET) &
97 R300_CLIPRECT_MASK;
98
99 }
100 OUT_RING((box.x1 << R300_CLIPRECT_X_SHIFT) |
101 (box.y1 << R300_CLIPRECT_Y_SHIFT));
102 OUT_RING((box.x2 << R300_CLIPRECT_X_SHIFT) |
103 (box.y2 << R300_CLIPRECT_Y_SHIFT));
104
105 }
106
107 OUT_RING_REG(R300_RE_CLIPRECT_CNTL, r300_cliprect_cntl[nr - 1]);
108
109 /* TODO/SECURITY: Force scissors to a safe value, otherwise the
110 * client might be able to trample over memory.
111 * The impact should be very limited, but I'd rather be safe than
112 * sorry.
113 */
114 OUT_RING(CP_PACKET0(R300_RE_SCISSORS_TL, 1));
115 OUT_RING(0);
116 OUT_RING(R300_SCISSORS_X_MASK | R300_SCISSORS_Y_MASK);
117 ADVANCE_RING();
118 } else {
119 /* Why we allow zero cliprect rendering:
120 * There are some commands in a command buffer that must be submitted
121 * even when there are no cliprects, e.g. DMA buffer discard
122 * or state setting (though state setting could be avoided by
123 * simulating a loss of context).
124 *
125 * Now since the cmdbuf interface is so chaotic right now (and is
126 * bound to remain that way for a bit until things settle down),
127 * it is basically impossible to filter out the commands that are
128 * necessary and those that aren't.
129 *
130 * So I choose the safe way and don't do any filtering at all;
131 * instead, I simply set up the engine so that all rendering
132 * can't produce any fragments.
133 */
134 BEGIN_RING(2);
135 OUT_RING_REG(R300_RE_CLIPRECT_CNTL, 0);
136 ADVANCE_RING();
137 }
138
139 return 0;
140}
141
142static u8 r300_reg_flags[0x10000 >> 2];
143
144void r300_init_reg_flags(struct drm_device *dev)
145{
146 int i;
147 drm_radeon_private_t *dev_priv = dev->dev_private;
148
149 memset(r300_reg_flags, 0, 0x10000 >> 2);
150#define ADD_RANGE_MARK(reg, count,mark) \
151 for(i=((reg)>>2);i<((reg)>>2)+(count);i++)\
152 r300_reg_flags[i]|=(mark);
153
154#define MARK_SAFE 1
155#define MARK_CHECK_OFFSET 2
156
157#define ADD_RANGE(reg, count) ADD_RANGE_MARK(reg, count, MARK_SAFE)
158
159 /* these match cmducs() command in r300_driver/r300/r300_cmdbuf.c */
160 ADD_RANGE(R300_SE_VPORT_XSCALE, 6);
161 ADD_RANGE(R300_VAP_CNTL, 1);
162 ADD_RANGE(R300_SE_VTE_CNTL, 2);
163 ADD_RANGE(0x2134, 2);
164 ADD_RANGE(R300_VAP_CNTL_STATUS, 1);
165 ADD_RANGE(R300_VAP_INPUT_CNTL_0, 2);
166 ADD_RANGE(0x21DC, 1);
167 ADD_RANGE(R300_VAP_UNKNOWN_221C, 1);
168 ADD_RANGE(R300_VAP_CLIP_X_0, 4);
169 ADD_RANGE(R300_VAP_PVS_WAITIDLE, 1);
170 ADD_RANGE(R300_VAP_UNKNOWN_2288, 1);
171 ADD_RANGE(R300_VAP_OUTPUT_VTX_FMT_0, 2);
172 ADD_RANGE(R300_VAP_PVS_CNTL_1, 3);
173 ADD_RANGE(R300_GB_ENABLE, 1);
174 ADD_RANGE(R300_GB_MSPOS0, 5);
175 ADD_RANGE(R300_TX_CNTL, 1);
176 ADD_RANGE(R300_TX_ENABLE, 1);
177 ADD_RANGE(0x4200, 4);
178 ADD_RANGE(0x4214, 1);
179 ADD_RANGE(R300_RE_POINTSIZE, 1);
180 ADD_RANGE(0x4230, 3);
181 ADD_RANGE(R300_RE_LINE_CNT, 1);
182 ADD_RANGE(R300_RE_UNK4238, 1);
183 ADD_RANGE(0x4260, 3);
184 ADD_RANGE(R300_RE_SHADE, 4);
185 ADD_RANGE(R300_RE_POLYGON_MODE, 5);
186 ADD_RANGE(R300_RE_ZBIAS_CNTL, 1);
187 ADD_RANGE(R300_RE_ZBIAS_T_FACTOR, 4);
188 ADD_RANGE(R300_RE_OCCLUSION_CNTL, 1);
189 ADD_RANGE(R300_RE_CULL_CNTL, 1);
190 ADD_RANGE(0x42C0, 2);
191 ADD_RANGE(R300_RS_CNTL_0, 2);
192 ADD_RANGE(R300_RS_INTERP_0, 8);
193 ADD_RANGE(R300_RS_ROUTE_0, 8);
194 ADD_RANGE(0x43A4, 2);
195 ADD_RANGE(0x43E8, 1);
196 ADD_RANGE(R300_PFS_CNTL_0, 3);
197 ADD_RANGE(R300_PFS_NODE_0, 4);
198 ADD_RANGE(R300_PFS_TEXI_0, 64);
199 ADD_RANGE(0x46A4, 5);
200 ADD_RANGE(R300_PFS_INSTR0_0, 64);
201 ADD_RANGE(R300_PFS_INSTR1_0, 64);
202 ADD_RANGE(R300_PFS_INSTR2_0, 64);
203 ADD_RANGE(R300_PFS_INSTR3_0, 64);
204 ADD_RANGE(R300_RE_FOG_STATE, 1);
205 ADD_RANGE(R300_FOG_COLOR_R, 3);
206 ADD_RANGE(R300_PP_ALPHA_TEST, 2);
207 ADD_RANGE(0x4BD8, 1);
208 ADD_RANGE(R300_PFS_PARAM_0_X, 64);
209 ADD_RANGE(0x4E00, 1);
210 ADD_RANGE(R300_RB3D_CBLEND, 2);
211 ADD_RANGE(R300_RB3D_COLORMASK, 1);
212 ADD_RANGE(R300_RB3D_BLEND_COLOR, 3);
213 ADD_RANGE_MARK(R300_RB3D_COLOROFFSET0, 1, MARK_CHECK_OFFSET); /* check offset */
214 ADD_RANGE(R300_RB3D_COLORPITCH0, 1);
215 ADD_RANGE(0x4E50, 9);
216 ADD_RANGE(0x4E88, 1);
217 ADD_RANGE(0x4EA0, 2);
218 ADD_RANGE(R300_RB3D_ZSTENCIL_CNTL_0, 3);
219 ADD_RANGE(R300_RB3D_ZSTENCIL_FORMAT, 4);
220 ADD_RANGE_MARK(R300_RB3D_DEPTHOFFSET, 1, MARK_CHECK_OFFSET); /* check offset */
221 ADD_RANGE(R300_RB3D_DEPTHPITCH, 1);
222 ADD_RANGE(0x4F28, 1);
223 ADD_RANGE(0x4F30, 2);
224 ADD_RANGE(0x4F44, 1);
225 ADD_RANGE(0x4F54, 1);
226
227 ADD_RANGE(R300_TX_FILTER_0, 16);
228 ADD_RANGE(R300_TX_FILTER1_0, 16);
229 ADD_RANGE(R300_TX_SIZE_0, 16);
230 ADD_RANGE(R300_TX_FORMAT_0, 16);
231 ADD_RANGE(R300_TX_PITCH_0, 16);
232 /* Texture offset is dangerous and needs more checking */
233 ADD_RANGE_MARK(R300_TX_OFFSET_0, 16, MARK_CHECK_OFFSET);
234 ADD_RANGE(R300_TX_CHROMA_KEY_0, 16);
235 ADD_RANGE(R300_TX_BORDER_COLOR_0, 16);
236
237 /* Sporadic registers used as primitives are emitted */
238 ADD_RANGE(R300_RB3D_ZCACHE_CTLSTAT, 1);
239 ADD_RANGE(R300_RB3D_DSTCACHE_CTLSTAT, 1);
240 ADD_RANGE(R300_VAP_INPUT_ROUTE_0_0, 8);
241 ADD_RANGE(R300_VAP_INPUT_ROUTE_1_0, 8);
242
243 if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RV515) {
244 ADD_RANGE(0x4074, 16);
245 }
246}
247
248static __inline__ int r300_check_range(unsigned reg, int count)
249{
250 int i;
251 if (reg & ~0xffff)
252 return -1;
253 for (i = (reg >> 2); i < (reg >> 2) + count; i++)
254 if (r300_reg_flags[i] != MARK_SAFE)
255 return 1;
256 return 0;
257}
258
259static __inline__ int r300_emit_carefully_checked_packet0(drm_radeon_private_t *
260 dev_priv,
261 drm_radeon_kcmd_buffer_t
262 * cmdbuf,
263 drm_r300_cmd_header_t
264 header)
265{
266 int reg;
267 int sz;
268 int i;
269 int values[64];
270 RING_LOCALS;
271
272 sz = header.packet0.count;
273 reg = (header.packet0.reghi << 8) | header.packet0.reglo;
274
275 if ((sz > 64) || (sz < 0)) {
276 DRM_ERROR
277 ("Cannot emit more than 64 values at a time (reg=%04x sz=%d)\n",
278 reg, sz);
279 return -EINVAL;
280 }
281 for (i = 0; i < sz; i++) {
282 values[i] = ((int *)cmdbuf->buf)[i];
283 switch (r300_reg_flags[(reg >> 2) + i]) {
284 case MARK_SAFE:
285 break;
286 case MARK_CHECK_OFFSET:
287 if (!radeon_check_offset(dev_priv, (u32) values[i])) {
288 DRM_ERROR
289 ("Offset failed range check (reg=%04x sz=%d)\n",
290 reg, sz);
291 return -EINVAL;
292 }
293 break;
294 default:
295 DRM_ERROR("Register %04x failed check as flag=%02x\n",
296 reg + i * 4, r300_reg_flags[(reg >> 2) + i]);
297 return -EINVAL;
298 }
299 }
300
301 BEGIN_RING(1 + sz);
302 OUT_RING(CP_PACKET0(reg, sz - 1));
303 OUT_RING_TABLE(values, sz);
304 ADVANCE_RING();
305
306 cmdbuf->buf += sz * 4;
307 cmdbuf->bufsz -= sz * 4;
308
309 return 0;
310}
311
312/**
313 * Emits a packet0 setting arbitrary registers.
314 * Called by r300_do_cp_cmdbuf.
315 *
316 * Note that checks are performed on contents and addresses of the registers
317 */
318static __inline__ int r300_emit_packet0(drm_radeon_private_t *dev_priv,
319 drm_radeon_kcmd_buffer_t *cmdbuf,
320 drm_r300_cmd_header_t header)
321{
322 int reg;
323 int sz;
324 RING_LOCALS;
325
326 sz = header.packet0.count;
327 reg = (header.packet0.reghi << 8) | header.packet0.reglo;
328
329 if (!sz)
330 return 0;
331
332 if (sz * 4 > cmdbuf->bufsz)
333 return -EINVAL;
334
335 if (reg + sz * 4 >= 0x10000) {
336 DRM_ERROR("No such registers in hardware reg=%04x sz=%d\n", reg,
337 sz);
338 return -EINVAL;
339 }
340
341 if (r300_check_range(reg, sz)) {
342 /* go and check everything */
343 return r300_emit_carefully_checked_packet0(dev_priv, cmdbuf,
344 header);
345 }
346 /* the rest of the data is safe to emit, whatever the values the user passed */
347
348 BEGIN_RING(1 + sz);
349 OUT_RING(CP_PACKET0(reg, sz - 1));
350 OUT_RING_TABLE((int *)cmdbuf->buf, sz);
351 ADVANCE_RING();
352
353 cmdbuf->buf += sz * 4;
354 cmdbuf->bufsz -= sz * 4;
355
356 return 0;
357}
358
359/**
360 * Uploads user-supplied vertex program instructions or parameters onto
361 * the graphics card.
362 * Called by r300_do_cp_cmdbuf.
363 */
364static __inline__ int r300_emit_vpu(drm_radeon_private_t *dev_priv,
365 drm_radeon_kcmd_buffer_t *cmdbuf,
366 drm_r300_cmd_header_t header)
367{
368 int sz;
369 int addr;
370 RING_LOCALS;
371
372 sz = header.vpu.count;
373 addr = (header.vpu.adrhi << 8) | header.vpu.adrlo;
374
375 if (!sz)
376 return 0;
377 if (sz * 16 > cmdbuf->bufsz)
378 return -EINVAL;
379
380 BEGIN_RING(5 + sz * 4);
381 /* Wait for VAP to come to senses.. */
382 /* there is no need to emit it multiple times, (only once before VAP is programmed,
383 but this optimization is for later */
384 OUT_RING_REG(R300_VAP_PVS_WAITIDLE, 0);
385 OUT_RING_REG(R300_VAP_PVS_UPLOAD_ADDRESS, addr);
386 OUT_RING(CP_PACKET0_TABLE(R300_VAP_PVS_UPLOAD_DATA, sz * 4 - 1));
387 OUT_RING_TABLE((int *)cmdbuf->buf, sz * 4);
388
389 ADVANCE_RING();
390
391 cmdbuf->buf += sz * 16;
392 cmdbuf->bufsz -= sz * 16;
393
394 return 0;
395}
396
397/**
398 * Emit a clear packet from userspace.
399 * Called by r300_emit_packet3.
400 */
401static __inline__ int r300_emit_clear(drm_radeon_private_t *dev_priv,
402 drm_radeon_kcmd_buffer_t *cmdbuf)
403{
404 RING_LOCALS;
405
406 if (8 * 4 > cmdbuf->bufsz)
407 return -EINVAL;
408
409 BEGIN_RING(10);
410 OUT_RING(CP_PACKET3(R200_3D_DRAW_IMMD_2, 8));
411 OUT_RING(R300_PRIM_TYPE_POINT | R300_PRIM_WALK_RING |
412 (1 << R300_PRIM_NUM_VERTICES_SHIFT));
413 OUT_RING_TABLE((int *)cmdbuf->buf, 8);
414 ADVANCE_RING();
415
416 cmdbuf->buf += 8 * 4;
417 cmdbuf->bufsz -= 8 * 4;
418
419 return 0;
420}
421
422static __inline__ int r300_emit_3d_load_vbpntr(drm_radeon_private_t *dev_priv,
423 drm_radeon_kcmd_buffer_t *cmdbuf,
424 u32 header)
425{
426 int count, i, k;
427#define MAX_ARRAY_PACKET 64
428 u32 payload[MAX_ARRAY_PACKET];
429 u32 narrays;
430 RING_LOCALS;
431
432 count = (header >> 16) & 0x3fff;
433
434 if ((count + 1) > MAX_ARRAY_PACKET) {
435 DRM_ERROR("Too large payload in 3D_LOAD_VBPNTR (count=%d)\n",
436 count);
437 return -EINVAL;
438 }
439 memset(payload, 0, MAX_ARRAY_PACKET * 4);
440 memcpy(payload, cmdbuf->buf + 4, (count + 1) * 4);
441
442 /* carefully check packet contents */
443
444 narrays = payload[0];
445 k = 0;
446 i = 1;
447 while ((k < narrays) && (i < (count + 1))) {
448 i++; /* skip attribute field */
449 if (!radeon_check_offset(dev_priv, payload[i])) {
450 DRM_ERROR
451 ("Offset failed range check (k=%d i=%d) while processing 3D_LOAD_VBPNTR packet.\n",
452 k, i);
453 return -EINVAL;
454 }
455 k++;
456 i++;
457 if (k == narrays)
458 break;
459 /* have one more to process, they come in pairs */
460 if (!radeon_check_offset(dev_priv, payload[i])) {
461 DRM_ERROR
462 ("Offset failed range check (k=%d i=%d) while processing 3D_LOAD_VBPNTR packet.\n",
463 k, i);
464 return -EINVAL;
465 }
466 k++;
467 i++;
468 }
469 /* do the counts match what we expect ? */
470 if ((k != narrays) || (i != (count + 1))) {
471 DRM_ERROR
472 ("Malformed 3D_LOAD_VBPNTR packet (k=%d i=%d narrays=%d count+1=%d).\n",
473 k, i, narrays, count + 1);
474 return -EINVAL;
475 }
476
477 /* all clear, output packet */
478
479 BEGIN_RING(count + 2);
480 OUT_RING(header);
481 OUT_RING_TABLE(payload, count + 1);
482 ADVANCE_RING();
483
484 cmdbuf->buf += (count + 2) * 4;
485 cmdbuf->bufsz -= (count + 2) * 4;
486
487 return 0;
488}
489
490static __inline__ int r300_emit_bitblt_multi(drm_radeon_private_t *dev_priv,
491 drm_radeon_kcmd_buffer_t *cmdbuf)
492{
493 u32 *cmd = (u32 *) cmdbuf->buf;
494 int count, ret;
495 RING_LOCALS;
496
497 count=(cmd[0]>>16) & 0x3fff;
498
499 if (cmd[0] & 0x8000) {
500 u32 offset;
501
502 if (cmd[1] & (RADEON_GMC_SRC_PITCH_OFFSET_CNTL
503 | RADEON_GMC_DST_PITCH_OFFSET_CNTL)) {
504 offset = cmd[2] << 10;
505 ret = !radeon_check_offset(dev_priv, offset);
506 if (ret) {
507 DRM_ERROR("Invalid bitblt first offset is %08X\n", offset);
508 return -EINVAL;
509 }
510 }
511
512 if ((cmd[1] & RADEON_GMC_SRC_PITCH_OFFSET_CNTL) &&
513 (cmd[1] & RADEON_GMC_DST_PITCH_OFFSET_CNTL)) {
514 offset = cmd[3] << 10;
515 ret = !radeon_check_offset(dev_priv, offset);
516 if (ret) {
517 DRM_ERROR("Invalid bitblt second offset is %08X\n", offset);
518 return -EINVAL;
519 }
520
521 }
522 }
523
524 BEGIN_RING(count+2);
525 OUT_RING(cmd[0]);
526 OUT_RING_TABLE((int *)(cmdbuf->buf + 4), count + 1);
527 ADVANCE_RING();
528
529 cmdbuf->buf += (count+2)*4;
530 cmdbuf->bufsz -= (count+2)*4;
531
532 return 0;
533}
534
535static __inline__ int r300_emit_indx_buffer(drm_radeon_private_t *dev_priv,
536 drm_radeon_kcmd_buffer_t *cmdbuf)
537{
538 u32 *cmd = (u32 *) cmdbuf->buf;
539 int count, ret;
540 RING_LOCALS;
541
542 count=(cmd[0]>>16) & 0x3fff;
543
544 if ((cmd[1] & 0x8000ffff) != 0x80000810) {
545 DRM_ERROR("Invalid indx_buffer reg address %08X\n", cmd[1]);
546 return -EINVAL;
547 }
548 ret = !radeon_check_offset(dev_priv, cmd[2]);
549 if (ret) {
550 DRM_ERROR("Invalid indx_buffer offset is %08X\n", cmd[2]);
551 return -EINVAL;
552 }
553
554 BEGIN_RING(count+2);
555 OUT_RING(cmd[0]);
556 OUT_RING_TABLE((int *)(cmdbuf->buf + 4), count + 1);
557 ADVANCE_RING();
558
559 cmdbuf->buf += (count+2)*4;
560 cmdbuf->bufsz -= (count+2)*4;
561
562 return 0;
563}
564
565static __inline__ int r300_emit_raw_packet3(drm_radeon_private_t *dev_priv,
566 drm_radeon_kcmd_buffer_t *cmdbuf)
567{
568 u32 header;
569 int count;
570 RING_LOCALS;
571
572 if (4 > cmdbuf->bufsz)
573 return -EINVAL;
574
575 /* Fixme !! This simply emits a packet without much checking.
576 We need to be smarter. */
577
578 /* obtain first word - actual packet3 header */
579 header = *(u32 *) cmdbuf->buf;
580
581 /* Is it packet 3 ? */
582 if ((header >> 30) != 0x3) {
583 DRM_ERROR("Not a packet3 header (0x%08x)\n", header);
584 return -EINVAL;
585 }
586
587 count = (header >> 16) & 0x3fff;
588
589 /* Check again now that we know how much data to expect */
590 if ((count + 2) * 4 > cmdbuf->bufsz) {
591 DRM_ERROR
592 ("Expected packet3 of length %d but have only %d bytes left\n",
593 (count + 2) * 4, cmdbuf->bufsz);
594 return -EINVAL;
595 }
596
597 /* Is it a packet type we know about ? */
598 switch (header & 0xff00) {
599 case RADEON_3D_LOAD_VBPNTR: /* load vertex array pointers */
600 return r300_emit_3d_load_vbpntr(dev_priv, cmdbuf, header);
601
602 case RADEON_CNTL_BITBLT_MULTI:
603 return r300_emit_bitblt_multi(dev_priv, cmdbuf);
604
605 case RADEON_CP_INDX_BUFFER: /* DRAW_INDX_2 without INDX_BUFFER seems to lock up the gpu */
606 return r300_emit_indx_buffer(dev_priv, cmdbuf);
607 case RADEON_CP_3D_DRAW_IMMD_2: /* triggers drawing using in-packet vertex data */
608 case RADEON_CP_3D_DRAW_VBUF_2: /* triggers drawing of vertex buffers setup elsewhere */
609 case RADEON_CP_3D_DRAW_INDX_2: /* triggers drawing using indices to vertex buffer */
610 case RADEON_WAIT_FOR_IDLE:
611 case RADEON_CP_NOP:
612 /* these packets are safe */
613 break;
614 default:
615 DRM_ERROR("Unknown packet3 header (0x%08x)\n", header);
616 return -EINVAL;
617 }
618
619 BEGIN_RING(count + 2);
620 OUT_RING(header);
621 OUT_RING_TABLE((int *)(cmdbuf->buf + 4), count + 1);
622 ADVANCE_RING();
623
624 cmdbuf->buf += (count + 2) * 4;
625 cmdbuf->bufsz -= (count + 2) * 4;
626
627 return 0;
628}
629
630/**
631 * Emit a rendering packet3 from userspace.
632 * Called by r300_do_cp_cmdbuf.
633 */
634static __inline__ int r300_emit_packet3(drm_radeon_private_t *dev_priv,
635 drm_radeon_kcmd_buffer_t *cmdbuf,
636 drm_r300_cmd_header_t header)
637{
638 int n;
639 int ret;
640 char *orig_buf = cmdbuf->buf;
641 int orig_bufsz = cmdbuf->bufsz;
642
643 /* This is a do-while-loop so that we run the interior at least once,
644 * even if cmdbuf->nbox is 0. Compare r300_emit_cliprects for rationale.
645 */
646 n = 0;
647 do {
648 if (cmdbuf->nbox > R300_SIMULTANEOUS_CLIPRECTS) {
649 ret = r300_emit_cliprects(dev_priv, cmdbuf, n);
650 if (ret)
651 return ret;
652
653 cmdbuf->buf = orig_buf;
654 cmdbuf->bufsz = orig_bufsz;
655 }
656
657 switch (header.packet3.packet) {
658 case R300_CMD_PACKET3_CLEAR:
659 DRM_DEBUG("R300_CMD_PACKET3_CLEAR\n");
660 ret = r300_emit_clear(dev_priv, cmdbuf);
661 if (ret) {
662 DRM_ERROR("r300_emit_clear failed\n");
663 return ret;
664 }
665 break;
666
667 case R300_CMD_PACKET3_RAW:
668 DRM_DEBUG("R300_CMD_PACKET3_RAW\n");
669 ret = r300_emit_raw_packet3(dev_priv, cmdbuf);
670 if (ret) {
671 DRM_ERROR("r300_emit_raw_packet3 failed\n");
672 return ret;
673 }
674 break;
675
676 default:
677 DRM_ERROR("bad packet3 type %i at %p\n",
678 header.packet3.packet,
679 cmdbuf->buf - sizeof(header));
680 return -EINVAL;
681 }
682
683 n += R300_SIMULTANEOUS_CLIPRECTS;
684 } while (n < cmdbuf->nbox);
685
686 return 0;
687}
688
689/* Some of the R300 chips seem to be extremely touchy about the two registers
690 * that are configured in r300_pacify.
691 * Among the worst offenders seems to be the R300 ND (0x4E44): When userspace
692 * sends a command buffer that contains only state setting commands and a
693 * vertex program/parameter upload sequence, this will eventually lead to a
694 * lockup, unless the sequence is bracketed by calls to r300_pacify.
695 * So we should take great care to *always* call r300_pacify before
696 * *anything* 3D related, and again afterwards. This is what the
697 * call bracket in r300_do_cp_cmdbuf is for.
698 */
699
700/**
701 * Emit the sequence to pacify R300.
702 */
703static __inline__ void r300_pacify(drm_radeon_private_t *dev_priv)
704{
705 RING_LOCALS;
706
707 BEGIN_RING(6);
708 OUT_RING(CP_PACKET0(R300_RB3D_DSTCACHE_CTLSTAT, 0));
709 OUT_RING(R300_RB3D_DSTCACHE_UNKNOWN_0A);
710 OUT_RING(CP_PACKET0(R300_RB3D_ZCACHE_CTLSTAT, 0));
711 OUT_RING(R300_RB3D_ZCACHE_UNKNOWN_03);
712 OUT_RING(CP_PACKET3(RADEON_CP_NOP, 0));
713 OUT_RING(0x0);
714 ADVANCE_RING();
715}
716
717/**
718 * Called by r300_do_cp_cmdbuf to update the internal buffer age and state.
719 * The actual age emit is done by r300_do_cp_cmdbuf, which is why you must
720 * be careful about how this function is called.
721 */
722static void r300_discard_buffer(struct drm_device * dev, struct drm_buf * buf)
723{
724 drm_radeon_private_t *dev_priv = dev->dev_private;
725 drm_radeon_buf_priv_t *buf_priv = buf->dev_private;
726
727 buf_priv->age = ++dev_priv->sarea_priv->last_dispatch;
728 buf->pending = 1;
729 buf->used = 0;
730}
731
732static void r300_cmd_wait(drm_radeon_private_t * dev_priv,
733 drm_r300_cmd_header_t header)
734{
735 u32 wait_until;
736 RING_LOCALS;
737
738 if (!header.wait.flags)
739 return;
740
741 wait_until = 0;
742
743 switch(header.wait.flags) {
744 case R300_WAIT_2D:
745 wait_until = RADEON_WAIT_2D_IDLE;
746 break;
747 case R300_WAIT_3D:
748 wait_until = RADEON_WAIT_3D_IDLE;
749 break;
750 case R300_NEW_WAIT_2D_3D:
751 wait_until = RADEON_WAIT_2D_IDLE|RADEON_WAIT_3D_IDLE;
752 break;
753 case R300_NEW_WAIT_2D_2D_CLEAN:
754 wait_until = RADEON_WAIT_2D_IDLE|RADEON_WAIT_2D_IDLECLEAN;
755 break;
756 case R300_NEW_WAIT_3D_3D_CLEAN:
757 wait_until = RADEON_WAIT_3D_IDLE|RADEON_WAIT_3D_IDLECLEAN;
758 break;
759 case R300_NEW_WAIT_2D_2D_CLEAN_3D_3D_CLEAN:
760 wait_until = RADEON_WAIT_2D_IDLE|RADEON_WAIT_2D_IDLECLEAN;
761 wait_until |= RADEON_WAIT_3D_IDLE|RADEON_WAIT_3D_IDLECLEAN;
762 break;
763 default:
764 return;
765 }
766
767 BEGIN_RING(2);
768 OUT_RING(CP_PACKET0(RADEON_WAIT_UNTIL, 0));
769 OUT_RING(wait_until);
770 ADVANCE_RING();
771}
772
773static int r300_scratch(drm_radeon_private_t *dev_priv,
774 drm_radeon_kcmd_buffer_t *cmdbuf,
775 drm_r300_cmd_header_t header)
776{
777 u32 *ref_age_base;
778 u32 i, buf_idx, h_pending;
779 RING_LOCALS;
780
781 if (cmdbuf->bufsz <
782 (sizeof(u64) + header.scratch.n_bufs * sizeof(buf_idx))) {
783 return -EINVAL;
784 }
785
786 if (header.scratch.reg >= 5) {
787 return -EINVAL;
788 }
789
790 dev_priv->scratch_ages[header.scratch.reg]++;
791
792 ref_age_base = (u32 *)(unsigned long)*((uint64_t *)cmdbuf->buf);
793
794 cmdbuf->buf += sizeof(u64);
795 cmdbuf->bufsz -= sizeof(u64);
796
797 for (i=0; i < header.scratch.n_bufs; i++) {
798 buf_idx = *(u32 *)cmdbuf->buf;
799 buf_idx *= 2; /* 8 bytes per buf */
800
801 if (DRM_COPY_TO_USER(ref_age_base + buf_idx, &dev_priv->scratch_ages[header.scratch.reg], sizeof(u32))) {
802 return -EINVAL;
803 }
804
805 if (DRM_COPY_FROM_USER(&h_pending, ref_age_base + buf_idx + 1, sizeof(u32))) {
806 return -EINVAL;
807 }
808
809 if (h_pending == 0) {
810 return -EINVAL;
811 }
812
813 h_pending--;
814
815 if (DRM_COPY_TO_USER(ref_age_base + buf_idx + 1, &h_pending, sizeof(u32))) {
816 return -EINVAL;
817 }
818
819 cmdbuf->buf += sizeof(buf_idx);
820 cmdbuf->bufsz -= sizeof(buf_idx);
821 }
822
823 BEGIN_RING(2);
824 OUT_RING( CP_PACKET0( RADEON_SCRATCH_REG0 + header.scratch.reg * 4, 0 ) );
825 OUT_RING( dev_priv->scratch_ages[header.scratch.reg] );
826 ADVANCE_RING();
827
828 return 0;
829}
830
831/**
832 * Parses and validates a user-supplied command buffer and emits appropriate
833 * commands on the DMA ring buffer.
834 * Called by the ioctl handler function radeon_cp_cmdbuf.
835 */
836int r300_do_cp_cmdbuf(struct drm_device *dev,
837 struct drm_file *file_priv,
838 drm_radeon_kcmd_buffer_t *cmdbuf)
839{
840 drm_radeon_private_t *dev_priv = dev->dev_private;
841 struct drm_device_dma *dma = dev->dma;
842 struct drm_buf *buf = NULL;
843 int emit_dispatch_age = 0;
844 int ret = 0;
845
846 DRM_DEBUG("\n");
847
848 /* See the comment above r300_emit_begin3d for why this call must be here,
849 * and what the cleanup gotos are for. */
850 r300_pacify(dev_priv);
851
852 if (cmdbuf->nbox <= R300_SIMULTANEOUS_CLIPRECTS) {
853 ret = r300_emit_cliprects(dev_priv, cmdbuf, 0);
854 if (ret)
855 goto cleanup;
856 }
857
858 while (cmdbuf->bufsz >= sizeof(drm_r300_cmd_header_t)) {
859 int idx;
860 drm_r300_cmd_header_t header;
861
862 header.u = *(unsigned int *)cmdbuf->buf;
863
864 cmdbuf->buf += sizeof(header);
865 cmdbuf->bufsz -= sizeof(header);
866
867 switch (header.header.cmd_type) {
868 case R300_CMD_PACKET0:
869 DRM_DEBUG("R300_CMD_PACKET0\n");
870 ret = r300_emit_packet0(dev_priv, cmdbuf, header);
871 if (ret) {
872 DRM_ERROR("r300_emit_packet0 failed\n");
873 goto cleanup;
874 }
875 break;
876
877 case R300_CMD_VPU:
878 DRM_DEBUG("R300_CMD_VPU\n");
879 ret = r300_emit_vpu(dev_priv, cmdbuf, header);
880 if (ret) {
881 DRM_ERROR("r300_emit_vpu failed\n");
882 goto cleanup;
883 }
884 break;
885
886 case R300_CMD_PACKET3:
887 DRM_DEBUG("R300_CMD_PACKET3\n");
888 ret = r300_emit_packet3(dev_priv, cmdbuf, header);
889 if (ret) {
890 DRM_ERROR("r300_emit_packet3 failed\n");
891 goto cleanup;
892 }
893 break;
894
895 case R300_CMD_END3D:
896 DRM_DEBUG("R300_CMD_END3D\n");
897 /* TODO:
898 Ideally userspace driver should not need to issue this call,
899 i.e. the drm driver should issue it automatically and prevent
900 lockups.
901
902 In practice, we do not understand why this call is needed and what
903 it does (except for some vague guesses that it has to do with cache
904 coherence) and so the user space driver does it.
905
906 Once we are sure which uses prevent lockups the code could be moved
907 into the kernel and the userspace driver will not
908 need to use this command.
909
910 Note that issuing this command does not hurt anything
911 except, possibly, performance */
912 r300_pacify(dev_priv);
913 break;
914
915 case R300_CMD_CP_DELAY:
916 /* simple enough, we can do it here */
917 DRM_DEBUG("R300_CMD_CP_DELAY\n");
918 {
919 int i;
920 RING_LOCALS;
921
922 BEGIN_RING(header.delay.count);
923 for (i = 0; i < header.delay.count; i++)
924 OUT_RING(RADEON_CP_PACKET2);
925 ADVANCE_RING();
926 }
927 break;
928
929 case R300_CMD_DMA_DISCARD:
930 DRM_DEBUG("RADEON_CMD_DMA_DISCARD\n");
931 idx = header.dma.buf_idx;
932 if (idx < 0 || idx >= dma->buf_count) {
933 DRM_ERROR("buffer index %d (of %d max)\n",
934 idx, dma->buf_count - 1);
935 ret = -EINVAL;
936 goto cleanup;
937 }
938
939 buf = dma->buflist[idx];
940 if (buf->file_priv != file_priv || buf->pending) {
941 DRM_ERROR("bad buffer %p %p %d\n",
942 buf->file_priv, file_priv,
943 buf->pending);
944 ret = -EINVAL;
945 goto cleanup;
946 }
947
948 emit_dispatch_age = 1;
949 r300_discard_buffer(dev, buf);
950 break;
951
952 case R300_CMD_WAIT:
953 DRM_DEBUG("R300_CMD_WAIT\n");
954 r300_cmd_wait(dev_priv, header);
955 break;
956
957 case R300_CMD_SCRATCH:
958 DRM_DEBUG("R300_CMD_SCRATCH\n");
959 ret = r300_scratch(dev_priv, cmdbuf, header);
960 if (ret) {
961 DRM_ERROR("r300_scratch failed\n");
962 goto cleanup;
963 }
964 break;
965
966 default:
967 DRM_ERROR("bad cmd_type %i at %p\n",
968 header.header.cmd_type,
969 cmdbuf->buf - sizeof(header));
970 ret = -EINVAL;
971 goto cleanup;
972 }
973 }
974
975 DRM_DEBUG("END\n");
976
977 cleanup:
978 r300_pacify(dev_priv);
979
980 /* We emit the vertex buffer age here, outside the pacifier "brackets"
981 * for two reasons:
982 * (1) This may coalesce multiple age emissions into a single one and
983 * (2) more importantly, some chips lock up hard when scratch registers
984 * are written inside the pacifier bracket.
985 */
986 if (emit_dispatch_age) {
987 RING_LOCALS;
988
989 /* Emit the vertex buffer age */
990 BEGIN_RING(2);
991 RADEON_DISPATCH_AGE(dev_priv->sarea_priv->last_dispatch);
992 ADVANCE_RING();
993 }
994
995 COMMIT_RING();
996
997 return ret;
998}
diff --git a/drivers/char/drm/r300_reg.h b/drivers/char/drm/r300_reg.h
deleted file mode 100644
index 8f664af9c4a4..000000000000
--- a/drivers/char/drm/r300_reg.h
+++ /dev/null
@@ -1,1626 +0,0 @@
1/**************************************************************************
2
3Copyright (C) 2004-2005 Nicolai Haehnle et al.
4
5Permission is hereby granted, free of charge, to any person obtaining a
6copy of this software and associated documentation files (the "Software"),
7to deal in the Software without restriction, including without limitation
8on the rights to use, copy, modify, merge, publish, distribute, sub
9license, and/or sell copies of the Software, and to permit persons to whom
10the Software is furnished to do so, subject to the following conditions:
11
12The above copyright notice and this permission notice (including the next
13paragraph) shall be included in all copies or substantial portions of the
14Software.
15
16THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19THE AUTHOR(S) AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
20DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
22USE OR OTHER DEALINGS IN THE SOFTWARE.
23
24**************************************************************************/
25
26#ifndef _R300_REG_H
27#define _R300_REG_H
28
29#define R300_MC_INIT_MISC_LAT_TIMER 0x180
30# define R300_MC_MISC__MC_CPR_INIT_LAT_SHIFT 0
31# define R300_MC_MISC__MC_VF_INIT_LAT_SHIFT 4
32# define R300_MC_MISC__MC_DISP0R_INIT_LAT_SHIFT 8
33# define R300_MC_MISC__MC_DISP1R_INIT_LAT_SHIFT 12
34# define R300_MC_MISC__MC_FIXED_INIT_LAT_SHIFT 16
35# define R300_MC_MISC__MC_E2R_INIT_LAT_SHIFT 20
36# define R300_MC_MISC__MC_SAME_PAGE_PRIO_SHIFT 24
37# define R300_MC_MISC__MC_GLOBW_INIT_LAT_SHIFT 28
38
39#define R300_MC_INIT_GFX_LAT_TIMER 0x154
40# define R300_MC_MISC__MC_G3D0R_INIT_LAT_SHIFT 0
41# define R300_MC_MISC__MC_G3D1R_INIT_LAT_SHIFT 4
42# define R300_MC_MISC__MC_G3D2R_INIT_LAT_SHIFT 8
43# define R300_MC_MISC__MC_G3D3R_INIT_LAT_SHIFT 12
44# define R300_MC_MISC__MC_TX0R_INIT_LAT_SHIFT 16
45# define R300_MC_MISC__MC_TX1R_INIT_LAT_SHIFT 20
46# define R300_MC_MISC__MC_GLOBR_INIT_LAT_SHIFT 24
47# define R300_MC_MISC__MC_GLOBW_FULL_LAT_SHIFT 28
48
49/*
50 * This file contains registers and constants for the R300. They have been
51 * found mostly by examining command buffers captured using glxtest, as well
52 * as by extrapolating some known registers and constants from the R200.
53 * I am fairly certain that they are correct unless stated otherwise
54 * in comments.
55 */
56
57#define R300_SE_VPORT_XSCALE 0x1D98
58#define R300_SE_VPORT_XOFFSET 0x1D9C
59#define R300_SE_VPORT_YSCALE 0x1DA0
60#define R300_SE_VPORT_YOFFSET 0x1DA4
61#define R300_SE_VPORT_ZSCALE 0x1DA8
62#define R300_SE_VPORT_ZOFFSET 0x1DAC
63
64
65/*
66 * Vertex Array Processing (VAP) Control
67 * Stolen from r200 code from Christoph Brill (It's a guess!)
68 */
69#define R300_VAP_CNTL 0x2080
70
71/* This register is written directly and also starts data section
72 * in many 3d CP_PACKET3's
73 */
74#define R300_VAP_VF_CNTL 0x2084
75# define R300_VAP_VF_CNTL__PRIM_TYPE__SHIFT 0
76# define R300_VAP_VF_CNTL__PRIM_NONE (0<<0)
77# define R300_VAP_VF_CNTL__PRIM_POINTS (1<<0)
78# define R300_VAP_VF_CNTL__PRIM_LINES (2<<0)
79# define R300_VAP_VF_CNTL__PRIM_LINE_STRIP (3<<0)
80# define R300_VAP_VF_CNTL__PRIM_TRIANGLES (4<<0)
81# define R300_VAP_VF_CNTL__PRIM_TRIANGLE_FAN (5<<0)
82# define R300_VAP_VF_CNTL__PRIM_TRIANGLE_STRIP (6<<0)
83# define R300_VAP_VF_CNTL__PRIM_LINE_LOOP (12<<0)
84# define R300_VAP_VF_CNTL__PRIM_QUADS (13<<0)
85# define R300_VAP_VF_CNTL__PRIM_QUAD_STRIP (14<<0)
86# define R300_VAP_VF_CNTL__PRIM_POLYGON (15<<0)
87
88# define R300_VAP_VF_CNTL__PRIM_WALK__SHIFT 4
89 /* State based - direct writes to registers trigger vertex
90 generation */
91# define R300_VAP_VF_CNTL__PRIM_WALK_STATE_BASED (0<<4)
92# define R300_VAP_VF_CNTL__PRIM_WALK_INDICES (1<<4)
93# define R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST (2<<4)
94# define R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_EMBEDDED (3<<4)
95
96 /* I don't think I saw these three used.. */
97# define R300_VAP_VF_CNTL__COLOR_ORDER__SHIFT 6
98# define R300_VAP_VF_CNTL__TCL_OUTPUT_CTL_ENA__SHIFT 9
99# define R300_VAP_VF_CNTL__PROG_STREAM_ENA__SHIFT 10
100
101 /* index size - when not set the indices are assumed to be 16 bit */
102# define R300_VAP_VF_CNTL__INDEX_SIZE_32bit (1<<11)
103 /* number of vertices */
104# define R300_VAP_VF_CNTL__NUM_VERTICES__SHIFT 16
105
106/* BEGIN: Wild guesses */
107#define R300_VAP_OUTPUT_VTX_FMT_0 0x2090
108# define R300_VAP_OUTPUT_VTX_FMT_0__POS_PRESENT (1<<0)
109# define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_PRESENT (1<<1)
110# define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_1_PRESENT (1<<2) /* GUESS */
111# define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_2_PRESENT (1<<3) /* GUESS */
112# define R300_VAP_OUTPUT_VTX_FMT_0__COLOR_3_PRESENT (1<<4) /* GUESS */
113# define R300_VAP_OUTPUT_VTX_FMT_0__PT_SIZE_PRESENT (1<<16) /* GUESS */
114
115#define R300_VAP_OUTPUT_VTX_FMT_1 0x2094
116 /* each of the following is 3 bits wide, specifies number
117 of components */
118# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_0_COMP_CNT_SHIFT 0
119# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_1_COMP_CNT_SHIFT 3
120# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_2_COMP_CNT_SHIFT 6
121# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_3_COMP_CNT_SHIFT 9
122# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_4_COMP_CNT_SHIFT 12
123# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_5_COMP_CNT_SHIFT 15
124# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_6_COMP_CNT_SHIFT 18
125# define R300_VAP_OUTPUT_VTX_FMT_1__TEX_7_COMP_CNT_SHIFT 21
126/* END: Wild guesses */
127
128#define R300_SE_VTE_CNTL 0x20b0
129# define R300_VPORT_X_SCALE_ENA 0x00000001
130# define R300_VPORT_X_OFFSET_ENA 0x00000002
131# define R300_VPORT_Y_SCALE_ENA 0x00000004
132# define R300_VPORT_Y_OFFSET_ENA 0x00000008
133# define R300_VPORT_Z_SCALE_ENA 0x00000010
134# define R300_VPORT_Z_OFFSET_ENA 0x00000020
135# define R300_VTX_XY_FMT 0x00000100
136# define R300_VTX_Z_FMT 0x00000200
137# define R300_VTX_W0_FMT 0x00000400
138# define R300_VTX_W0_NORMALIZE 0x00000800
139# define R300_VTX_ST_DENORMALIZED 0x00001000
140
141/* BEGIN: Vertex data assembly - lots of uncertainties */
142
143/* gap */
144
145#define R300_VAP_CNTL_STATUS 0x2140
146# define R300_VC_NO_SWAP (0 << 0)
147# define R300_VC_16BIT_SWAP (1 << 0)
148# define R300_VC_32BIT_SWAP (2 << 0)
149# define R300_VAP_TCL_BYPASS (1 << 8)
150
151/* gap */
152
153/* Where do we get our vertex data?
154 *
155 * Vertex data either comes either from immediate mode registers or from
156 * vertex arrays.
157 * There appears to be no mixed mode (though we can force the pitch of
158 * vertex arrays to 0, effectively reusing the same element over and over
159 * again).
160 *
161 * Immediate mode is controlled by the INPUT_CNTL registers. I am not sure
162 * if these registers influence vertex array processing.
163 *
164 * Vertex arrays are controlled via the 3D_LOAD_VBPNTR packet3.
165 *
166 * In both cases, vertex attributes are then passed through INPUT_ROUTE.
167 *
168 * Beginning with INPUT_ROUTE_0_0 is a list of WORDs that route vertex data
169 * into the vertex processor's input registers.
170 * The first word routes the first input, the second word the second, etc.
171 * The corresponding input is routed into the register with the given index.
172 * The list is ended by a word with INPUT_ROUTE_END set.
173 *
174 * Always set COMPONENTS_4 in immediate mode.
175 */
176
177#define R300_VAP_INPUT_ROUTE_0_0 0x2150
178# define R300_INPUT_ROUTE_COMPONENTS_1 (0 << 0)
179# define R300_INPUT_ROUTE_COMPONENTS_2 (1 << 0)
180# define R300_INPUT_ROUTE_COMPONENTS_3 (2 << 0)
181# define R300_INPUT_ROUTE_COMPONENTS_4 (3 << 0)
182# define R300_INPUT_ROUTE_COMPONENTS_RGBA (4 << 0) /* GUESS */
183# define R300_VAP_INPUT_ROUTE_IDX_SHIFT 8
184# define R300_VAP_INPUT_ROUTE_IDX_MASK (31 << 8) /* GUESS */
185# define R300_VAP_INPUT_ROUTE_END (1 << 13)
186# define R300_INPUT_ROUTE_IMMEDIATE_MODE (0 << 14) /* GUESS */
187# define R300_INPUT_ROUTE_FLOAT (1 << 14) /* GUESS */
188# define R300_INPUT_ROUTE_UNSIGNED_BYTE (2 << 14) /* GUESS */
189# define R300_INPUT_ROUTE_FLOAT_COLOR (3 << 14) /* GUESS */
190#define R300_VAP_INPUT_ROUTE_0_1 0x2154
191#define R300_VAP_INPUT_ROUTE_0_2 0x2158
192#define R300_VAP_INPUT_ROUTE_0_3 0x215C
193#define R300_VAP_INPUT_ROUTE_0_4 0x2160
194#define R300_VAP_INPUT_ROUTE_0_5 0x2164
195#define R300_VAP_INPUT_ROUTE_0_6 0x2168
196#define R300_VAP_INPUT_ROUTE_0_7 0x216C
197
198/* gap */
199
200/* Notes:
201 * - always set up to produce at least two attributes:
202 * if vertex program uses only position, fglrx will set normal, too
203 * - INPUT_CNTL_0_COLOR and INPUT_CNTL_COLOR bits are always equal.
204 */
205#define R300_VAP_INPUT_CNTL_0 0x2180
206# define R300_INPUT_CNTL_0_COLOR 0x00000001
207#define R300_VAP_INPUT_CNTL_1 0x2184
208# define R300_INPUT_CNTL_POS 0x00000001
209# define R300_INPUT_CNTL_NORMAL 0x00000002
210# define R300_INPUT_CNTL_COLOR 0x00000004
211# define R300_INPUT_CNTL_TC0 0x00000400
212# define R300_INPUT_CNTL_TC1 0x00000800
213# define R300_INPUT_CNTL_TC2 0x00001000 /* GUESS */
214# define R300_INPUT_CNTL_TC3 0x00002000 /* GUESS */
215# define R300_INPUT_CNTL_TC4 0x00004000 /* GUESS */
216# define R300_INPUT_CNTL_TC5 0x00008000 /* GUESS */
217# define R300_INPUT_CNTL_TC6 0x00010000 /* GUESS */
218# define R300_INPUT_CNTL_TC7 0x00020000 /* GUESS */
219
220/* gap */
221
222/* Words parallel to INPUT_ROUTE_0; All words that are active in INPUT_ROUTE_0
223 * are set to a swizzling bit pattern, other words are 0.
224 *
225 * In immediate mode, the pattern is always set to xyzw. In vertex array
226 * mode, the swizzling pattern is e.g. used to set zw components in texture
227 * coordinates with only tweo components.
228 */
229#define R300_VAP_INPUT_ROUTE_1_0 0x21E0
230# define R300_INPUT_ROUTE_SELECT_X 0
231# define R300_INPUT_ROUTE_SELECT_Y 1
232# define R300_INPUT_ROUTE_SELECT_Z 2
233# define R300_INPUT_ROUTE_SELECT_W 3
234# define R300_INPUT_ROUTE_SELECT_ZERO 4
235# define R300_INPUT_ROUTE_SELECT_ONE 5
236# define R300_INPUT_ROUTE_SELECT_MASK 7
237# define R300_INPUT_ROUTE_X_SHIFT 0
238# define R300_INPUT_ROUTE_Y_SHIFT 3
239# define R300_INPUT_ROUTE_Z_SHIFT 6
240# define R300_INPUT_ROUTE_W_SHIFT 9
241# define R300_INPUT_ROUTE_ENABLE (15 << 12)
242#define R300_VAP_INPUT_ROUTE_1_1 0x21E4
243#define R300_VAP_INPUT_ROUTE_1_2 0x21E8
244#define R300_VAP_INPUT_ROUTE_1_3 0x21EC
245#define R300_VAP_INPUT_ROUTE_1_4 0x21F0
246#define R300_VAP_INPUT_ROUTE_1_5 0x21F4
247#define R300_VAP_INPUT_ROUTE_1_6 0x21F8
248#define R300_VAP_INPUT_ROUTE_1_7 0x21FC
249
250/* END: Vertex data assembly */
251
252/* gap */
253
254/* BEGIN: Upload vertex program and data */
255
256/*
257 * The programmable vertex shader unit has a memory bank of unknown size
258 * that can be written to in 16 byte units by writing the address into
259 * UPLOAD_ADDRESS, followed by data in UPLOAD_DATA (multiples of 4 DWORDs).
260 *
261 * Pointers into the memory bank are always in multiples of 16 bytes.
262 *
263 * The memory bank is divided into areas with fixed meaning.
264 *
265 * Starting at address UPLOAD_PROGRAM: Vertex program instructions.
266 * Native limits reported by drivers from ATI suggest size 256 (i.e. 4KB),
267 * whereas the difference between known addresses suggests size 512.
268 *
269 * Starting at address UPLOAD_PARAMETERS: Vertex program parameters.
270 * Native reported limits and the VPI layout suggest size 256, whereas
271 * difference between known addresses suggests size 512.
272 *
273 * At address UPLOAD_POINTSIZE is a vector (0, 0, ps, 0), where ps is the
274 * floating point pointsize. The exact purpose of this state is uncertain,
275 * as there is also the R300_RE_POINTSIZE register.
276 *
277 * Multiple vertex programs and parameter sets can be loaded at once,
278 * which could explain the size discrepancy.
279 */
280#define R300_VAP_PVS_UPLOAD_ADDRESS 0x2200
281# define R300_PVS_UPLOAD_PROGRAM 0x00000000
282# define R300_PVS_UPLOAD_PARAMETERS 0x00000200
283# define R300_PVS_UPLOAD_POINTSIZE 0x00000406
284
285/* gap */
286
287#define R300_VAP_PVS_UPLOAD_DATA 0x2208
288
289/* END: Upload vertex program and data */
290
291/* gap */
292
293/* I do not know the purpose of this register. However, I do know that
294 * it is set to 221C_CLEAR for clear operations and to 221C_NORMAL
295 * for normal rendering.
296 */
297#define R300_VAP_UNKNOWN_221C 0x221C
298# define R300_221C_NORMAL 0x00000000
299# define R300_221C_CLEAR 0x0001C000
300
301/* These seem to be per-pixel and per-vertex X and Y clipping planes. The first
302 * plane is per-pixel and the second plane is per-vertex.
303 *
304 * This was determined by experimentation alone but I believe it is correct.
305 *
306 * These registers are called X_QUAD0_1_FL to X_QUAD0_4_FL by glxtest.
307 */
308#define R300_VAP_CLIP_X_0 0x2220
309#define R300_VAP_CLIP_X_1 0x2224
310#define R300_VAP_CLIP_Y_0 0x2228
311#define R300_VAP_CLIP_Y_1 0x2230
312
313/* gap */
314
315/* Sometimes, END_OF_PKT and 0x2284=0 are the only commands sent between
316 * rendering commands and overwriting vertex program parameters.
317 * Therefore, I suspect writing zero to 0x2284 synchronizes the engine and
318 * avoids bugs caused by still running shaders reading bad data from memory.
319 */
320#define R300_VAP_PVS_WAITIDLE 0x2284 /* GUESS */
321
322/* Absolutely no clue what this register is about. */
323#define R300_VAP_UNKNOWN_2288 0x2288
324# define R300_2288_R300 0x00750000 /* -- nh */
325# define R300_2288_RV350 0x0000FFFF /* -- Vladimir */
326
327/* gap */
328
329/* Addresses are relative to the vertex program instruction area of the
330 * memory bank. PROGRAM_END points to the last instruction of the active
331 * program
332 *
333 * The meaning of the two UNKNOWN fields is obviously not known. However,
334 * experiments so far have shown that both *must* point to an instruction
335 * inside the vertex program, otherwise the GPU locks up.
336 *
337 * fglrx usually sets CNTL_3_UNKNOWN to the end of the program and
338 * R300_PVS_CNTL_1_POS_END_SHIFT points to instruction where last write to
339 * position takes place.
340 *
341 * Most likely this is used to ignore rest of the program in cases
342 * where group of verts arent visible. For some reason this "section"
343 * is sometimes accepted other instruction that have no relationship with
344 * position calculations.
345 */
346#define R300_VAP_PVS_CNTL_1 0x22D0
347# define R300_PVS_CNTL_1_PROGRAM_START_SHIFT 0
348# define R300_PVS_CNTL_1_POS_END_SHIFT 10
349# define R300_PVS_CNTL_1_PROGRAM_END_SHIFT 20
350/* Addresses are relative the the vertex program parameters area. */
351#define R300_VAP_PVS_CNTL_2 0x22D4
352# define R300_PVS_CNTL_2_PARAM_OFFSET_SHIFT 0
353# define R300_PVS_CNTL_2_PARAM_COUNT_SHIFT 16
354#define R300_VAP_PVS_CNTL_3 0x22D8
355# define R300_PVS_CNTL_3_PROGRAM_UNKNOWN_SHIFT 10
356# define R300_PVS_CNTL_3_PROGRAM_UNKNOWN2_SHIFT 0
357
358/* The entire range from 0x2300 to 0x2AC inclusive seems to be used for
359 * immediate vertices
360 */
361#define R300_VAP_VTX_COLOR_R 0x2464
362#define R300_VAP_VTX_COLOR_G 0x2468
363#define R300_VAP_VTX_COLOR_B 0x246C
364#define R300_VAP_VTX_POS_0_X_1 0x2490 /* used for glVertex2*() */
365#define R300_VAP_VTX_POS_0_Y_1 0x2494
366#define R300_VAP_VTX_COLOR_PKD 0x249C /* RGBA */
367#define R300_VAP_VTX_POS_0_X_2 0x24A0 /* used for glVertex3*() */
368#define R300_VAP_VTX_POS_0_Y_2 0x24A4
369#define R300_VAP_VTX_POS_0_Z_2 0x24A8
370/* write 0 to indicate end of packet? */
371#define R300_VAP_VTX_END_OF_PKT 0x24AC
372
373/* gap */
374
375/* These are values from r300_reg/r300_reg.h - they are known to be correct
376 * and are here so we can use one register file instead of several
377 * - Vladimir
378 */
379#define R300_GB_VAP_RASTER_VTX_FMT_0 0x4000
380# define R300_GB_VAP_RASTER_VTX_FMT_0__POS_PRESENT (1<<0)
381# define R300_GB_VAP_RASTER_VTX_FMT_0__COLOR_0_PRESENT (1<<1)
382# define R300_GB_VAP_RASTER_VTX_FMT_0__COLOR_1_PRESENT (1<<2)
383# define R300_GB_VAP_RASTER_VTX_FMT_0__COLOR_2_PRESENT (1<<3)
384# define R300_GB_VAP_RASTER_VTX_FMT_0__COLOR_3_PRESENT (1<<4)
385# define R300_GB_VAP_RASTER_VTX_FMT_0__COLOR_SPACE (0xf<<5)
386# define R300_GB_VAP_RASTER_VTX_FMT_0__PT_SIZE_PRESENT (0x1<<16)
387
388#define R300_GB_VAP_RASTER_VTX_FMT_1 0x4004
389 /* each of the following is 3 bits wide, specifies number
390 of components */
391# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_0_COMP_CNT_SHIFT 0
392# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_1_COMP_CNT_SHIFT 3
393# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_2_COMP_CNT_SHIFT 6
394# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_3_COMP_CNT_SHIFT 9
395# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_4_COMP_CNT_SHIFT 12
396# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_5_COMP_CNT_SHIFT 15
397# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_6_COMP_CNT_SHIFT 18
398# define R300_GB_VAP_RASTER_VTX_FMT_1__TEX_7_COMP_CNT_SHIFT 21
399
400/* UNK30 seems to enables point to quad transformation on textures
401 * (or something closely related to that).
402 * This bit is rather fatal at the time being due to lackings at pixel
403 * shader side
404 */
405#define R300_GB_ENABLE 0x4008
406# define R300_GB_POINT_STUFF_ENABLE (1<<0)
407# define R300_GB_LINE_STUFF_ENABLE (1<<1)
408# define R300_GB_TRIANGLE_STUFF_ENABLE (1<<2)
409# define R300_GB_STENCIL_AUTO_ENABLE (1<<4)
410# define R300_GB_UNK31 (1<<31)
411 /* each of the following is 2 bits wide */
412#define R300_GB_TEX_REPLICATE 0
413#define R300_GB_TEX_ST 1
414#define R300_GB_TEX_STR 2
415# define R300_GB_TEX0_SOURCE_SHIFT 16
416# define R300_GB_TEX1_SOURCE_SHIFT 18
417# define R300_GB_TEX2_SOURCE_SHIFT 20
418# define R300_GB_TEX3_SOURCE_SHIFT 22
419# define R300_GB_TEX4_SOURCE_SHIFT 24
420# define R300_GB_TEX5_SOURCE_SHIFT 26
421# define R300_GB_TEX6_SOURCE_SHIFT 28
422# define R300_GB_TEX7_SOURCE_SHIFT 30
423
424/* MSPOS - positions for multisample antialiasing (?) */
425#define R300_GB_MSPOS0 0x4010
426 /* shifts - each of the fields is 4 bits */
427# define R300_GB_MSPOS0__MS_X0_SHIFT 0
428# define R300_GB_MSPOS0__MS_Y0_SHIFT 4
429# define R300_GB_MSPOS0__MS_X1_SHIFT 8
430# define R300_GB_MSPOS0__MS_Y1_SHIFT 12
431# define R300_GB_MSPOS0__MS_X2_SHIFT 16
432# define R300_GB_MSPOS0__MS_Y2_SHIFT 20
433# define R300_GB_MSPOS0__MSBD0_Y 24
434# define R300_GB_MSPOS0__MSBD0_X 28
435
436#define R300_GB_MSPOS1 0x4014
437# define R300_GB_MSPOS1__MS_X3_SHIFT 0
438# define R300_GB_MSPOS1__MS_Y3_SHIFT 4
439# define R300_GB_MSPOS1__MS_X4_SHIFT 8
440# define R300_GB_MSPOS1__MS_Y4_SHIFT 12
441# define R300_GB_MSPOS1__MS_X5_SHIFT 16
442# define R300_GB_MSPOS1__MS_Y5_SHIFT 20
443# define R300_GB_MSPOS1__MSBD1 24
444
445
446#define R300_GB_TILE_CONFIG 0x4018
447# define R300_GB_TILE_ENABLE (1<<0)
448# define R300_GB_TILE_PIPE_COUNT_RV300 0
449# define R300_GB_TILE_PIPE_COUNT_R300 (3<<1)
450# define R300_GB_TILE_PIPE_COUNT_R420 (7<<1)
451# define R300_GB_TILE_PIPE_COUNT_RV410 (3<<1)
452# define R300_GB_TILE_SIZE_8 0
453# define R300_GB_TILE_SIZE_16 (1<<4)
454# define R300_GB_TILE_SIZE_32 (2<<4)
455# define R300_GB_SUPER_SIZE_1 (0<<6)
456# define R300_GB_SUPER_SIZE_2 (1<<6)
457# define R300_GB_SUPER_SIZE_4 (2<<6)
458# define R300_GB_SUPER_SIZE_8 (3<<6)
459# define R300_GB_SUPER_SIZE_16 (4<<6)
460# define R300_GB_SUPER_SIZE_32 (5<<6)
461# define R300_GB_SUPER_SIZE_64 (6<<6)
462# define R300_GB_SUPER_SIZE_128 (7<<6)
463# define R300_GB_SUPER_X_SHIFT 9 /* 3 bits wide */
464# define R300_GB_SUPER_Y_SHIFT 12 /* 3 bits wide */
465# define R300_GB_SUPER_TILE_A 0
466# define R300_GB_SUPER_TILE_B (1<<15)
467# define R300_GB_SUBPIXEL_1_12 0
468# define R300_GB_SUBPIXEL_1_16 (1<<16)
469
470#define R300_GB_FIFO_SIZE 0x4024
471 /* each of the following is 2 bits wide */
472#define R300_GB_FIFO_SIZE_32 0
473#define R300_GB_FIFO_SIZE_64 1
474#define R300_GB_FIFO_SIZE_128 2
475#define R300_GB_FIFO_SIZE_256 3
476# define R300_SC_IFIFO_SIZE_SHIFT 0
477# define R300_SC_TZFIFO_SIZE_SHIFT 2
478# define R300_SC_BFIFO_SIZE_SHIFT 4
479
480# define R300_US_OFIFO_SIZE_SHIFT 12
481# define R300_US_WFIFO_SIZE_SHIFT 14
482 /* the following use the same constants as above, but meaning is
483 is times 2 (i.e. instead of 32 words it means 64 */
484# define R300_RS_TFIFO_SIZE_SHIFT 6
485# define R300_RS_CFIFO_SIZE_SHIFT 8
486# define R300_US_RAM_SIZE_SHIFT 10
487 /* watermarks, 3 bits wide */
488# define R300_RS_HIGHWATER_COL_SHIFT 16
489# define R300_RS_HIGHWATER_TEX_SHIFT 19
490# define R300_OFIFO_HIGHWATER_SHIFT 22 /* two bits only */
491# define R300_CUBE_FIFO_HIGHWATER_COL_SHIFT 24
492
493#define R300_GB_SELECT 0x401C
494# define R300_GB_FOG_SELECT_C0A 0
495# define R300_GB_FOG_SELECT_C1A 1
496# define R300_GB_FOG_SELECT_C2A 2
497# define R300_GB_FOG_SELECT_C3A 3
498# define R300_GB_FOG_SELECT_1_1_W 4
499# define R300_GB_FOG_SELECT_Z 5
500# define R300_GB_DEPTH_SELECT_Z 0
501# define R300_GB_DEPTH_SELECT_1_1_W (1<<3)
502# define R300_GB_W_SELECT_1_W 0
503# define R300_GB_W_SELECT_1 (1<<4)
504
505#define R300_GB_AA_CONFIG 0x4020
506# define R300_AA_DISABLE 0x00
507# define R300_AA_ENABLE 0x01
508# define R300_AA_SUBSAMPLES_2 0
509# define R300_AA_SUBSAMPLES_3 (1<<1)
510# define R300_AA_SUBSAMPLES_4 (2<<1)
511# define R300_AA_SUBSAMPLES_6 (3<<1)
512
513/* gap */
514
515/* Zero to flush caches. */
516#define R300_TX_CNTL 0x4100
517#define R300_TX_FLUSH 0x0
518
519/* The upper enable bits are guessed, based on fglrx reported limits. */
520#define R300_TX_ENABLE 0x4104
521# define R300_TX_ENABLE_0 (1 << 0)
522# define R300_TX_ENABLE_1 (1 << 1)
523# define R300_TX_ENABLE_2 (1 << 2)
524# define R300_TX_ENABLE_3 (1 << 3)
525# define R300_TX_ENABLE_4 (1 << 4)
526# define R300_TX_ENABLE_5 (1 << 5)
527# define R300_TX_ENABLE_6 (1 << 6)
528# define R300_TX_ENABLE_7 (1 << 7)
529# define R300_TX_ENABLE_8 (1 << 8)
530# define R300_TX_ENABLE_9 (1 << 9)
531# define R300_TX_ENABLE_10 (1 << 10)
532# define R300_TX_ENABLE_11 (1 << 11)
533# define R300_TX_ENABLE_12 (1 << 12)
534# define R300_TX_ENABLE_13 (1 << 13)
535# define R300_TX_ENABLE_14 (1 << 14)
536# define R300_TX_ENABLE_15 (1 << 15)
537
538/* The pointsize is given in multiples of 6. The pointsize can be
539 * enormous: Clear() renders a single point that fills the entire
540 * framebuffer.
541 */
542#define R300_RE_POINTSIZE 0x421C
543# define R300_POINTSIZE_Y_SHIFT 0
544# define R300_POINTSIZE_Y_MASK (0xFFFF << 0) /* GUESS */
545# define R300_POINTSIZE_X_SHIFT 16
546# define R300_POINTSIZE_X_MASK (0xFFFF << 16) /* GUESS */
547# define R300_POINTSIZE_MAX (R300_POINTSIZE_Y_MASK / 6)
548
549/* The line width is given in multiples of 6.
550 * In default mode lines are classified as vertical lines.
551 * HO: horizontal
552 * VE: vertical or horizontal
553 * HO & VE: no classification
554 */
555#define R300_RE_LINE_CNT 0x4234
556# define R300_LINESIZE_SHIFT 0
557# define R300_LINESIZE_MASK (0xFFFF << 0) /* GUESS */
558# define R300_LINESIZE_MAX (R300_LINESIZE_MASK / 6)
559# define R300_LINE_CNT_HO (1 << 16)
560# define R300_LINE_CNT_VE (1 << 17)
561
562/* Some sort of scale or clamp value for texcoordless textures. */
563#define R300_RE_UNK4238 0x4238
564
565/* Something shade related */
566#define R300_RE_SHADE 0x4274
567
568#define R300_RE_SHADE_MODEL 0x4278
569# define R300_RE_SHADE_MODEL_SMOOTH 0x3aaaa
570# define R300_RE_SHADE_MODEL_FLAT 0x39595
571
572/* Dangerous */
573#define R300_RE_POLYGON_MODE 0x4288
574# define R300_PM_ENABLED (1 << 0)
575# define R300_PM_FRONT_POINT (0 << 0)
576# define R300_PM_BACK_POINT (0 << 0)
577# define R300_PM_FRONT_LINE (1 << 4)
578# define R300_PM_FRONT_FILL (1 << 5)
579# define R300_PM_BACK_LINE (1 << 7)
580# define R300_PM_BACK_FILL (1 << 8)
581
582/* Fog parameters */
583#define R300_RE_FOG_SCALE 0x4294
584#define R300_RE_FOG_START 0x4298
585
586/* Not sure why there are duplicate of factor and constant values.
587 * My best guess so far is that there are separate zbiases for test and write.
588 * Ordering might be wrong.
589 * Some of the tests indicate that fgl has a fallback implementation of zbias
590 * via pixel shaders.
591 */
592#define R300_RE_ZBIAS_CNTL 0x42A0 /* GUESS */
593#define R300_RE_ZBIAS_T_FACTOR 0x42A4
594#define R300_RE_ZBIAS_T_CONSTANT 0x42A8
595#define R300_RE_ZBIAS_W_FACTOR 0x42AC
596#define R300_RE_ZBIAS_W_CONSTANT 0x42B0
597
598/* This register needs to be set to (1<<1) for RV350 to correctly
599 * perform depth test (see --vb-triangles in r300_demo)
600 * Don't know about other chips. - Vladimir
601 * This is set to 3 when GL_POLYGON_OFFSET_FILL is on.
602 * My guess is that there are two bits for each zbias primitive
603 * (FILL, LINE, POINT).
604 * One to enable depth test and one for depth write.
605 * Yet this doesnt explain why depth writes work ...
606 */
607#define R300_RE_OCCLUSION_CNTL 0x42B4
608# define R300_OCCLUSION_ON (1<<1)
609
610#define R300_RE_CULL_CNTL 0x42B8
611# define R300_CULL_FRONT (1 << 0)
612# define R300_CULL_BACK (1 << 1)
613# define R300_FRONT_FACE_CCW (0 << 2)
614# define R300_FRONT_FACE_CW (1 << 2)
615
616
617/* BEGIN: Rasterization / Interpolators - many guesses */
618
619/* 0_UNKNOWN_18 has always been set except for clear operations.
620 * TC_CNT is the number of incoming texture coordinate sets (i.e. it depends
621 * on the vertex program, *not* the fragment program)
622 */
623#define R300_RS_CNTL_0 0x4300
624# define R300_RS_CNTL_TC_CNT_SHIFT 2
625# define R300_RS_CNTL_TC_CNT_MASK (7 << 2)
626 /* number of color interpolators used */
627# define R300_RS_CNTL_CI_CNT_SHIFT 7
628# define R300_RS_CNTL_0_UNKNOWN_18 (1 << 18)
629 /* Guess: RS_CNTL_1 holds the index of the highest used RS_ROUTE_n
630 register. */
631#define R300_RS_CNTL_1 0x4304
632
633/* gap */
634
635/* Only used for texture coordinates.
636 * Use the source field to route texture coordinate input from the
637 * vertex program to the desired interpolator. Note that the source
638 * field is relative to the outputs the vertex program *actually*
639 * writes. If a vertex program only writes texcoord[1], this will
640 * be source index 0.
641 * Set INTERP_USED on all interpolators that produce data used by
642 * the fragment program. INTERP_USED looks like a swizzling mask,
643 * but I haven't seen it used that way.
644 *
645 * Note: The _UNKNOWN constants are always set in their respective
646 * register. I don't know if this is necessary.
647 */
648#define R300_RS_INTERP_0 0x4310
649#define R300_RS_INTERP_1 0x4314
650# define R300_RS_INTERP_1_UNKNOWN 0x40
651#define R300_RS_INTERP_2 0x4318
652# define R300_RS_INTERP_2_UNKNOWN 0x80
653#define R300_RS_INTERP_3 0x431C
654# define R300_RS_INTERP_3_UNKNOWN 0xC0
655#define R300_RS_INTERP_4 0x4320
656#define R300_RS_INTERP_5 0x4324
657#define R300_RS_INTERP_6 0x4328
658#define R300_RS_INTERP_7 0x432C
659# define R300_RS_INTERP_SRC_SHIFT 2
660# define R300_RS_INTERP_SRC_MASK (7 << 2)
661# define R300_RS_INTERP_USED 0x00D10000
662
663/* These DWORDs control how vertex data is routed into fragment program
664 * registers, after interpolators.
665 */
666#define R300_RS_ROUTE_0 0x4330
667#define R300_RS_ROUTE_1 0x4334
668#define R300_RS_ROUTE_2 0x4338
669#define R300_RS_ROUTE_3 0x433C /* GUESS */
670#define R300_RS_ROUTE_4 0x4340 /* GUESS */
671#define R300_RS_ROUTE_5 0x4344 /* GUESS */
672#define R300_RS_ROUTE_6 0x4348 /* GUESS */
673#define R300_RS_ROUTE_7 0x434C /* GUESS */
674# define R300_RS_ROUTE_SOURCE_INTERP_0 0
675# define R300_RS_ROUTE_SOURCE_INTERP_1 1
676# define R300_RS_ROUTE_SOURCE_INTERP_2 2
677# define R300_RS_ROUTE_SOURCE_INTERP_3 3
678# define R300_RS_ROUTE_SOURCE_INTERP_4 4
679# define R300_RS_ROUTE_SOURCE_INTERP_5 5 /* GUESS */
680# define R300_RS_ROUTE_SOURCE_INTERP_6 6 /* GUESS */
681# define R300_RS_ROUTE_SOURCE_INTERP_7 7 /* GUESS */
682# define R300_RS_ROUTE_ENABLE (1 << 3) /* GUESS */
683# define R300_RS_ROUTE_DEST_SHIFT 6
684# define R300_RS_ROUTE_DEST_MASK (31 << 6) /* GUESS */
685
686/* Special handling for color: When the fragment program uses color,
687 * the ROUTE_0_COLOR bit is set and ROUTE_0_COLOR_DEST contains the
688 * color register index.
689 *
690 * Apperently you may set the R300_RS_ROUTE_0_COLOR bit, but not provide any
691 * R300_RS_ROUTE_0_COLOR_DEST value; this setup is used for clearing the state.
692 * See r300_ioctl.c:r300EmitClearState. I'm not sure if this setup is strictly
693 * correct or not. - Oliver.
694 */
695# define R300_RS_ROUTE_0_COLOR (1 << 14)
696# define R300_RS_ROUTE_0_COLOR_DEST_SHIFT 17
697# define R300_RS_ROUTE_0_COLOR_DEST_MASK (31 << 17) /* GUESS */
698/* As above, but for secondary color */
699# define R300_RS_ROUTE_1_COLOR1 (1 << 14)
700# define R300_RS_ROUTE_1_COLOR1_DEST_SHIFT 17
701# define R300_RS_ROUTE_1_COLOR1_DEST_MASK (31 << 17)
702# define R300_RS_ROUTE_1_UNKNOWN11 (1 << 11)
703/* END: Rasterization / Interpolators - many guesses */
704
705/* BEGIN: Scissors and cliprects */
706
707/* There are four clipping rectangles. Their corner coordinates are inclusive.
708 * Every pixel is assigned a number from 0 and 15 by setting bits 0-3 depending
709 * on whether the pixel is inside cliprects 0-3, respectively. For example,
710 * if a pixel is inside cliprects 0 and 1, but outside 2 and 3, it is assigned
711 * the number 3 (binary 0011).
712 * Iff the bit corresponding to the pixel's number in RE_CLIPRECT_CNTL is set,
713 * the pixel is rasterized.
714 *
715 * In addition to this, there is a scissors rectangle. Only pixels inside the
716 * scissors rectangle are drawn. (coordinates are inclusive)
717 *
718 * For some reason, the top-left corner of the framebuffer is at (1440, 1440)
719 * for the purpose of clipping and scissors.
720 */
721#define R300_RE_CLIPRECT_TL_0 0x43B0
722#define R300_RE_CLIPRECT_BR_0 0x43B4
723#define R300_RE_CLIPRECT_TL_1 0x43B8
724#define R300_RE_CLIPRECT_BR_1 0x43BC
725#define R300_RE_CLIPRECT_TL_2 0x43C0
726#define R300_RE_CLIPRECT_BR_2 0x43C4
727#define R300_RE_CLIPRECT_TL_3 0x43C8
728#define R300_RE_CLIPRECT_BR_3 0x43CC
729# define R300_CLIPRECT_OFFSET 1440
730# define R300_CLIPRECT_MASK 0x1FFF
731# define R300_CLIPRECT_X_SHIFT 0
732# define R300_CLIPRECT_X_MASK (0x1FFF << 0)
733# define R300_CLIPRECT_Y_SHIFT 13
734# define R300_CLIPRECT_Y_MASK (0x1FFF << 13)
735#define R300_RE_CLIPRECT_CNTL 0x43D0
736# define R300_CLIP_OUT (1 << 0)
737# define R300_CLIP_0 (1 << 1)
738# define R300_CLIP_1 (1 << 2)
739# define R300_CLIP_10 (1 << 3)
740# define R300_CLIP_2 (1 << 4)
741# define R300_CLIP_20 (1 << 5)
742# define R300_CLIP_21 (1 << 6)
743# define R300_CLIP_210 (1 << 7)
744# define R300_CLIP_3 (1 << 8)
745# define R300_CLIP_30 (1 << 9)
746# define R300_CLIP_31 (1 << 10)
747# define R300_CLIP_310 (1 << 11)
748# define R300_CLIP_32 (1 << 12)
749# define R300_CLIP_320 (1 << 13)
750# define R300_CLIP_321 (1 << 14)
751# define R300_CLIP_3210 (1 << 15)
752
753/* gap */
754
755#define R300_RE_SCISSORS_TL 0x43E0
756#define R300_RE_SCISSORS_BR 0x43E4
757# define R300_SCISSORS_OFFSET 1440
758# define R300_SCISSORS_X_SHIFT 0
759# define R300_SCISSORS_X_MASK (0x1FFF << 0)
760# define R300_SCISSORS_Y_SHIFT 13
761# define R300_SCISSORS_Y_MASK (0x1FFF << 13)
762/* END: Scissors and cliprects */
763
764/* BEGIN: Texture specification */
765
766/*
767 * The texture specification dwords are grouped by meaning and not by texture
768 * unit. This means that e.g. the offset for texture image unit N is found in
769 * register TX_OFFSET_0 + (4*N)
770 */
771#define R300_TX_FILTER_0 0x4400
772# define R300_TX_REPEAT 0
773# define R300_TX_MIRRORED 1
774# define R300_TX_CLAMP 4
775# define R300_TX_CLAMP_TO_EDGE 2
776# define R300_TX_CLAMP_TO_BORDER 6
777# define R300_TX_WRAP_S_SHIFT 0
778# define R300_TX_WRAP_S_MASK (7 << 0)
779# define R300_TX_WRAP_T_SHIFT 3
780# define R300_TX_WRAP_T_MASK (7 << 3)
781# define R300_TX_WRAP_Q_SHIFT 6
782# define R300_TX_WRAP_Q_MASK (7 << 6)
783# define R300_TX_MAG_FILTER_NEAREST (1 << 9)
784# define R300_TX_MAG_FILTER_LINEAR (2 << 9)
785# define R300_TX_MAG_FILTER_MASK (3 << 9)
786# define R300_TX_MIN_FILTER_NEAREST (1 << 11)
787# define R300_TX_MIN_FILTER_LINEAR (2 << 11)
788# define R300_TX_MIN_FILTER_NEAREST_MIP_NEAREST (5 << 11)
789# define R300_TX_MIN_FILTER_NEAREST_MIP_LINEAR (9 << 11)
790# define R300_TX_MIN_FILTER_LINEAR_MIP_NEAREST (6 << 11)
791# define R300_TX_MIN_FILTER_LINEAR_MIP_LINEAR (10 << 11)
792
793/* NOTE: NEAREST doesnt seem to exist.
794 * Im not seting MAG_FILTER_MASK and (3 << 11) on for all
795 * anisotropy modes because that would void selected mag filter
796 */
797# define R300_TX_MIN_FILTER_ANISO_NEAREST (0 << 13)
798# define R300_TX_MIN_FILTER_ANISO_LINEAR (0 << 13)
799# define R300_TX_MIN_FILTER_ANISO_NEAREST_MIP_NEAREST (1 << 13)
800# define R300_TX_MIN_FILTER_ANISO_NEAREST_MIP_LINEAR (2 << 13)
801# define R300_TX_MIN_FILTER_MASK ( (15 << 11) | (3 << 13) )
802# define R300_TX_MAX_ANISO_1_TO_1 (0 << 21)
803# define R300_TX_MAX_ANISO_2_TO_1 (2 << 21)
804# define R300_TX_MAX_ANISO_4_TO_1 (4 << 21)
805# define R300_TX_MAX_ANISO_8_TO_1 (6 << 21)
806# define R300_TX_MAX_ANISO_16_TO_1 (8 << 21)
807# define R300_TX_MAX_ANISO_MASK (14 << 21)
808
809#define R300_TX_FILTER1_0 0x4440
810# define R300_CHROMA_KEY_MODE_DISABLE 0
811# define R300_CHROMA_KEY_FORCE 1
812# define R300_CHROMA_KEY_BLEND 2
813# define R300_MC_ROUND_NORMAL (0<<2)
814# define R300_MC_ROUND_MPEG4 (1<<2)
815# define R300_LOD_BIAS_MASK 0x1fff
816# define R300_EDGE_ANISO_EDGE_DIAG (0<<13)
817# define R300_EDGE_ANISO_EDGE_ONLY (1<<13)
818# define R300_MC_COORD_TRUNCATE_DISABLE (0<<14)
819# define R300_MC_COORD_TRUNCATE_MPEG (1<<14)
820# define R300_TX_TRI_PERF_0_8 (0<<15)
821# define R300_TX_TRI_PERF_1_8 (1<<15)
822# define R300_TX_TRI_PERF_1_4 (2<<15)
823# define R300_TX_TRI_PERF_3_8 (3<<15)
824# define R300_ANISO_THRESHOLD_MASK (7<<17)
825
826#define R300_TX_SIZE_0 0x4480
827# define R300_TX_WIDTHMASK_SHIFT 0
828# define R300_TX_WIDTHMASK_MASK (2047 << 0)
829# define R300_TX_HEIGHTMASK_SHIFT 11
830# define R300_TX_HEIGHTMASK_MASK (2047 << 11)
831# define R300_TX_UNK23 (1 << 23)
832# define R300_TX_MAX_MIP_LEVEL_SHIFT 26
833# define R300_TX_MAX_MIP_LEVEL_MASK (0xf << 26)
834# define R300_TX_SIZE_PROJECTED (1<<30)
835# define R300_TX_SIZE_TXPITCH_EN (1<<31)
836#define R300_TX_FORMAT_0 0x44C0
837 /* The interpretation of the format word by Wladimir van der Laan */
838 /* The X, Y, Z and W refer to the layout of the components.
839 They are given meanings as R, G, B and Alpha by the swizzle
840 specification */
841# define R300_TX_FORMAT_X8 0x0
842# define R300_TX_FORMAT_X16 0x1
843# define R300_TX_FORMAT_Y4X4 0x2
844# define R300_TX_FORMAT_Y8X8 0x3
845# define R300_TX_FORMAT_Y16X16 0x4
846# define R300_TX_FORMAT_Z3Y3X2 0x5
847# define R300_TX_FORMAT_Z5Y6X5 0x6
848# define R300_TX_FORMAT_Z6Y5X5 0x7
849# define R300_TX_FORMAT_Z11Y11X10 0x8
850# define R300_TX_FORMAT_Z10Y11X11 0x9
851# define R300_TX_FORMAT_W4Z4Y4X4 0xA
852# define R300_TX_FORMAT_W1Z5Y5X5 0xB
853# define R300_TX_FORMAT_W8Z8Y8X8 0xC
854# define R300_TX_FORMAT_W2Z10Y10X10 0xD
855# define R300_TX_FORMAT_W16Z16Y16X16 0xE
856# define R300_TX_FORMAT_DXT1 0xF
857# define R300_TX_FORMAT_DXT3 0x10
858# define R300_TX_FORMAT_DXT5 0x11
859# define R300_TX_FORMAT_D3DMFT_CxV8U8 0x12 /* no swizzle */
860# define R300_TX_FORMAT_A8R8G8B8 0x13 /* no swizzle */
861# define R300_TX_FORMAT_B8G8_B8G8 0x14 /* no swizzle */
862# define R300_TX_FORMAT_G8R8_G8B8 0x15 /* no swizzle */
863 /* 0x16 - some 16 bit green format.. ?? */
864# define R300_TX_FORMAT_UNK25 (1 << 25) /* no swizzle */
865# define R300_TX_FORMAT_CUBIC_MAP (1 << 26)
866
867 /* gap */
868 /* Floating point formats */
869 /* Note - hardware supports both 16 and 32 bit floating point */
870# define R300_TX_FORMAT_FL_I16 0x18
871# define R300_TX_FORMAT_FL_I16A16 0x19
872# define R300_TX_FORMAT_FL_R16G16B16A16 0x1A
873# define R300_TX_FORMAT_FL_I32 0x1B
874# define R300_TX_FORMAT_FL_I32A32 0x1C
875# define R300_TX_FORMAT_FL_R32G32B32A32 0x1D
876 /* alpha modes, convenience mostly */
877 /* if you have alpha, pick constant appropriate to the
878 number of channels (1 for I8, 2 for I8A8, 4 for R8G8B8A8, etc */
879# define R300_TX_FORMAT_ALPHA_1CH 0x000
880# define R300_TX_FORMAT_ALPHA_2CH 0x200
881# define R300_TX_FORMAT_ALPHA_4CH 0x600
882# define R300_TX_FORMAT_ALPHA_NONE 0xA00
883 /* Swizzling */
884 /* constants */
885# define R300_TX_FORMAT_X 0
886# define R300_TX_FORMAT_Y 1
887# define R300_TX_FORMAT_Z 2
888# define R300_TX_FORMAT_W 3
889# define R300_TX_FORMAT_ZERO 4
890# define R300_TX_FORMAT_ONE 5
891 /* 2.0*Z, everything above 1.0 is set to 0.0 */
892# define R300_TX_FORMAT_CUT_Z 6
893 /* 2.0*W, everything above 1.0 is set to 0.0 */
894# define R300_TX_FORMAT_CUT_W 7
895
896# define R300_TX_FORMAT_B_SHIFT 18
897# define R300_TX_FORMAT_G_SHIFT 15
898# define R300_TX_FORMAT_R_SHIFT 12
899# define R300_TX_FORMAT_A_SHIFT 9
900 /* Convenience macro to take care of layout and swizzling */
901# define R300_EASY_TX_FORMAT(B, G, R, A, FMT) ( \
902 ((R300_TX_FORMAT_##B)<<R300_TX_FORMAT_B_SHIFT) \
903 | ((R300_TX_FORMAT_##G)<<R300_TX_FORMAT_G_SHIFT) \
904 | ((R300_TX_FORMAT_##R)<<R300_TX_FORMAT_R_SHIFT) \
905 | ((R300_TX_FORMAT_##A)<<R300_TX_FORMAT_A_SHIFT) \
906 | (R300_TX_FORMAT_##FMT) \
907 )
908 /* These can be ORed with result of R300_EASY_TX_FORMAT()
909 We don't really know what they do. Take values from a
910 constant color ? */
911# define R300_TX_FORMAT_CONST_X (1<<5)
912# define R300_TX_FORMAT_CONST_Y (2<<5)
913# define R300_TX_FORMAT_CONST_Z (4<<5)
914# define R300_TX_FORMAT_CONST_W (8<<5)
915
916# define R300_TX_FORMAT_YUV_MODE 0x00800000
917
918#define R300_TX_PITCH_0 0x4500 /* obvious missing in gap */
919#define R300_TX_OFFSET_0 0x4540
920 /* BEGIN: Guess from R200 */
921# define R300_TXO_ENDIAN_NO_SWAP (0 << 0)
922# define R300_TXO_ENDIAN_BYTE_SWAP (1 << 0)
923# define R300_TXO_ENDIAN_WORD_SWAP (2 << 0)
924# define R300_TXO_ENDIAN_HALFDW_SWAP (3 << 0)
925# define R300_TXO_MACRO_TILE (1 << 2)
926# define R300_TXO_MICRO_TILE (1 << 3)
927# define R300_TXO_OFFSET_MASK 0xffffffe0
928# define R300_TXO_OFFSET_SHIFT 5
929 /* END: Guess from R200 */
930
931/* 32 bit chroma key */
932#define R300_TX_CHROMA_KEY_0 0x4580
933/* ff00ff00 == { 0, 1.0, 0, 1.0 } */
934#define R300_TX_BORDER_COLOR_0 0x45C0
935
936/* END: Texture specification */
937
938/* BEGIN: Fragment program instruction set */
939
940/* Fragment programs are written directly into register space.
941 * There are separate instruction streams for texture instructions and ALU
942 * instructions.
943 * In order to synchronize these streams, the program is divided into up
944 * to 4 nodes. Each node begins with a number of TEX operations, followed
945 * by a number of ALU operations.
946 * The first node can have zero TEX ops, all subsequent nodes must have at
947 * least
948 * one TEX ops.
949 * All nodes must have at least one ALU op.
950 *
951 * The index of the last node is stored in PFS_CNTL_0: A value of 0 means
952 * 1 node, a value of 3 means 4 nodes.
953 * The total amount of instructions is defined in PFS_CNTL_2. The offsets are
954 * offsets into the respective instruction streams, while *_END points to the
955 * last instruction relative to this offset.
956 */
957#define R300_PFS_CNTL_0 0x4600
958# define R300_PFS_CNTL_LAST_NODES_SHIFT 0
959# define R300_PFS_CNTL_LAST_NODES_MASK (3 << 0)
960# define R300_PFS_CNTL_FIRST_NODE_HAS_TEX (1 << 3)
961#define R300_PFS_CNTL_1 0x4604
962/* There is an unshifted value here which has so far always been equal to the
963 * index of the highest used temporary register.
964 */
965#define R300_PFS_CNTL_2 0x4608
966# define R300_PFS_CNTL_ALU_OFFSET_SHIFT 0
967# define R300_PFS_CNTL_ALU_OFFSET_MASK (63 << 0)
968# define R300_PFS_CNTL_ALU_END_SHIFT 6
969# define R300_PFS_CNTL_ALU_END_MASK (63 << 6)
970# define R300_PFS_CNTL_TEX_OFFSET_SHIFT 12
971# define R300_PFS_CNTL_TEX_OFFSET_MASK (31 << 12) /* GUESS */
972# define R300_PFS_CNTL_TEX_END_SHIFT 18
973# define R300_PFS_CNTL_TEX_END_MASK (31 << 18) /* GUESS */
974
975/* gap */
976
977/* Nodes are stored backwards. The last active node is always stored in
978 * PFS_NODE_3.
979 * Example: In a 2-node program, NODE_0 and NODE_1 are set to 0. The
980 * first node is stored in NODE_2, the second node is stored in NODE_3.
981 *
982 * Offsets are relative to the master offset from PFS_CNTL_2.
983 */
984#define R300_PFS_NODE_0 0x4610
985#define R300_PFS_NODE_1 0x4614
986#define R300_PFS_NODE_2 0x4618
987#define R300_PFS_NODE_3 0x461C
988# define R300_PFS_NODE_ALU_OFFSET_SHIFT 0
989# define R300_PFS_NODE_ALU_OFFSET_MASK (63 << 0)
990# define R300_PFS_NODE_ALU_END_SHIFT 6
991# define R300_PFS_NODE_ALU_END_MASK (63 << 6)
992# define R300_PFS_NODE_TEX_OFFSET_SHIFT 12
993# define R300_PFS_NODE_TEX_OFFSET_MASK (31 << 12)
994# define R300_PFS_NODE_TEX_END_SHIFT 17
995# define R300_PFS_NODE_TEX_END_MASK (31 << 17)
996# define R300_PFS_NODE_OUTPUT_COLOR (1 << 22)
997# define R300_PFS_NODE_OUTPUT_DEPTH (1 << 23)
998
999/* TEX
1000 * As far as I can tell, texture instructions cannot write into output
1001 * registers directly. A subsequent ALU instruction is always necessary,
1002 * even if it's just MAD o0, r0, 1, 0
1003 */
1004#define R300_PFS_TEXI_0 0x4620
1005# define R300_FPITX_SRC_SHIFT 0
1006# define R300_FPITX_SRC_MASK (31 << 0)
1007 /* GUESS */
1008# define R300_FPITX_SRC_CONST (1 << 5)
1009# define R300_FPITX_DST_SHIFT 6
1010# define R300_FPITX_DST_MASK (31 << 6)
1011# define R300_FPITX_IMAGE_SHIFT 11
1012 /* GUESS based on layout and native limits */
1013# define R300_FPITX_IMAGE_MASK (15 << 11)
1014/* Unsure if these are opcodes, or some kind of bitfield, but this is how
1015 * they were set when I checked
1016 */
1017# define R300_FPITX_OPCODE_SHIFT 15
1018# define R300_FPITX_OP_TEX 1
1019# define R300_FPITX_OP_KIL 2
1020# define R300_FPITX_OP_TXP 3
1021# define R300_FPITX_OP_TXB 4
1022# define R300_FPITX_OPCODE_MASK (7 << 15)
1023
1024/* ALU
1025 * The ALU instructions register blocks are enumerated according to the order
1026 * in which fglrx. I assume there is space for 64 instructions, since
1027 * each block has space for a maximum of 64 DWORDs, and this matches reported
1028 * native limits.
1029 *
1030 * The basic functional block seems to be one MAD for each color and alpha,
1031 * and an adder that adds all components after the MUL.
1032 * - ADD, MUL, MAD etc.: use MAD with appropriate neutral operands
1033 * - DP4: Use OUTC_DP4, OUTA_DP4
1034 * - DP3: Use OUTC_DP3, OUTA_DP4, appropriate alpha operands
1035 * - DPH: Use OUTC_DP4, OUTA_DP4, appropriate alpha operands
1036 * - CMPH: If ARG2 > 0.5, return ARG0, else return ARG1
1037 * - CMP: If ARG2 < 0, return ARG1, else return ARG0
1038 * - FLR: use FRC+MAD
1039 * - XPD: use MAD+MAD
1040 * - SGE, SLT: use MAD+CMP
1041 * - RSQ: use ABS modifier for argument
1042 * - Use OUTC_REPL_ALPHA to write results of an alpha-only operation
1043 * (e.g. RCP) into color register
1044 * - apparently, there's no quick DST operation
1045 * - fglrx set FPI2_UNKNOWN_31 on a "MAD fragment.color, tmp0, tmp1, tmp2"
1046 * - fglrx set FPI2_UNKNOWN_31 on a "MAX r2, r1, c0"
1047 * - fglrx once set FPI0_UNKNOWN_31 on a "FRC r1, r1"
1048 *
1049 * Operand selection
1050 * First stage selects three sources from the available registers and
1051 * constant parameters. This is defined in INSTR1 (color) and INSTR3 (alpha).
1052 * fglrx sorts the three source fields: Registers before constants,
1053 * lower indices before higher indices; I do not know whether this is
1054 * necessary.
1055 *
1056 * fglrx fills unused sources with "read constant 0"
1057 * According to specs, you cannot select more than two different constants.
1058 *
1059 * Second stage selects the operands from the sources. This is defined in
1060 * INSTR0 (color) and INSTR2 (alpha). You can also select the special constants
1061 * zero and one.
1062 * Swizzling and negation happens in this stage, as well.
1063 *
1064 * Important: Color and alpha seem to be mostly separate, i.e. their sources
1065 * selection appears to be fully independent (the register storage is probably
1066 * physically split into a color and an alpha section).
1067 * However (because of the apparent physical split), there is some interaction
1068 * WRT swizzling. If, for example, you want to load an R component into an
1069 * Alpha operand, this R component is taken from a *color* source, not from
1070 * an alpha source. The corresponding register doesn't even have to appear in
1071 * the alpha sources list. (I hope this all makes sense to you)
1072 *
1073 * Destination selection
1074 * The destination register index is in FPI1 (color) and FPI3 (alpha)
1075 * together with enable bits.
1076 * There are separate enable bits for writing into temporary registers
1077 * (DSTC_REG_* /DSTA_REG) and and program output registers (DSTC_OUTPUT_*
1078 * /DSTA_OUTPUT). You can write to both at once, or not write at all (the
1079 * same index must be used for both).
1080 *
1081 * Note: There is a special form for LRP
1082 * - Argument order is the same as in ARB_fragment_program.
1083 * - Operation is MAD
1084 * - ARG1 is set to ARGC_SRC1C_LRP/ARGC_SRC1A_LRP
1085 * - Set FPI0/FPI2_SPECIAL_LRP
1086 * Arbitrary LRP (including support for swizzling) requires vanilla MAD+MAD
1087 */
1088#define R300_PFS_INSTR1_0 0x46C0
1089# define R300_FPI1_SRC0C_SHIFT 0
1090# define R300_FPI1_SRC0C_MASK (31 << 0)
1091# define R300_FPI1_SRC0C_CONST (1 << 5)
1092# define R300_FPI1_SRC1C_SHIFT 6
1093# define R300_FPI1_SRC1C_MASK (31 << 6)
1094# define R300_FPI1_SRC1C_CONST (1 << 11)
1095# define R300_FPI1_SRC2C_SHIFT 12
1096# define R300_FPI1_SRC2C_MASK (31 << 12)
1097# define R300_FPI1_SRC2C_CONST (1 << 17)
1098# define R300_FPI1_SRC_MASK 0x0003ffff
1099# define R300_FPI1_DSTC_SHIFT 18
1100# define R300_FPI1_DSTC_MASK (31 << 18)
1101# define R300_FPI1_DSTC_REG_MASK_SHIFT 23
1102# define R300_FPI1_DSTC_REG_X (1 << 23)
1103# define R300_FPI1_DSTC_REG_Y (1 << 24)
1104# define R300_FPI1_DSTC_REG_Z (1 << 25)
1105# define R300_FPI1_DSTC_OUTPUT_MASK_SHIFT 26
1106# define R300_FPI1_DSTC_OUTPUT_X (1 << 26)
1107# define R300_FPI1_DSTC_OUTPUT_Y (1 << 27)
1108# define R300_FPI1_DSTC_OUTPUT_Z (1 << 28)
1109
1110#define R300_PFS_INSTR3_0 0x47C0
1111# define R300_FPI3_SRC0A_SHIFT 0
1112# define R300_FPI3_SRC0A_MASK (31 << 0)
1113# define R300_FPI3_SRC0A_CONST (1 << 5)
1114# define R300_FPI3_SRC1A_SHIFT 6
1115# define R300_FPI3_SRC1A_MASK (31 << 6)
1116# define R300_FPI3_SRC1A_CONST (1 << 11)
1117# define R300_FPI3_SRC2A_SHIFT 12
1118# define R300_FPI3_SRC2A_MASK (31 << 12)
1119# define R300_FPI3_SRC2A_CONST (1 << 17)
1120# define R300_FPI3_SRC_MASK 0x0003ffff
1121# define R300_FPI3_DSTA_SHIFT 18
1122# define R300_FPI3_DSTA_MASK (31 << 18)
1123# define R300_FPI3_DSTA_REG (1 << 23)
1124# define R300_FPI3_DSTA_OUTPUT (1 << 24)
1125# define R300_FPI3_DSTA_DEPTH (1 << 27)
1126
1127#define R300_PFS_INSTR0_0 0x48C0
1128# define R300_FPI0_ARGC_SRC0C_XYZ 0
1129# define R300_FPI0_ARGC_SRC0C_XXX 1
1130# define R300_FPI0_ARGC_SRC0C_YYY 2
1131# define R300_FPI0_ARGC_SRC0C_ZZZ 3
1132# define R300_FPI0_ARGC_SRC1C_XYZ 4
1133# define R300_FPI0_ARGC_SRC1C_XXX 5
1134# define R300_FPI0_ARGC_SRC1C_YYY 6
1135# define R300_FPI0_ARGC_SRC1C_ZZZ 7
1136# define R300_FPI0_ARGC_SRC2C_XYZ 8
1137# define R300_FPI0_ARGC_SRC2C_XXX 9
1138# define R300_FPI0_ARGC_SRC2C_YYY 10
1139# define R300_FPI0_ARGC_SRC2C_ZZZ 11
1140# define R300_FPI0_ARGC_SRC0A 12
1141# define R300_FPI0_ARGC_SRC1A 13
1142# define R300_FPI0_ARGC_SRC2A 14
1143# define R300_FPI0_ARGC_SRC1C_LRP 15
1144# define R300_FPI0_ARGC_ZERO 20
1145# define R300_FPI0_ARGC_ONE 21
1146 /* GUESS */
1147# define R300_FPI0_ARGC_HALF 22
1148# define R300_FPI0_ARGC_SRC0C_YZX 23
1149# define R300_FPI0_ARGC_SRC1C_YZX 24
1150# define R300_FPI0_ARGC_SRC2C_YZX 25
1151# define R300_FPI0_ARGC_SRC0C_ZXY 26
1152# define R300_FPI0_ARGC_SRC1C_ZXY 27
1153# define R300_FPI0_ARGC_SRC2C_ZXY 28
1154# define R300_FPI0_ARGC_SRC0CA_WZY 29
1155# define R300_FPI0_ARGC_SRC1CA_WZY 30
1156# define R300_FPI0_ARGC_SRC2CA_WZY 31
1157
1158# define R300_FPI0_ARG0C_SHIFT 0
1159# define R300_FPI0_ARG0C_MASK (31 << 0)
1160# define R300_FPI0_ARG0C_NEG (1 << 5)
1161# define R300_FPI0_ARG0C_ABS (1 << 6)
1162# define R300_FPI0_ARG1C_SHIFT 7
1163# define R300_FPI0_ARG1C_MASK (31 << 7)
1164# define R300_FPI0_ARG1C_NEG (1 << 12)
1165# define R300_FPI0_ARG1C_ABS (1 << 13)
1166# define R300_FPI0_ARG2C_SHIFT 14
1167# define R300_FPI0_ARG2C_MASK (31 << 14)
1168# define R300_FPI0_ARG2C_NEG (1 << 19)
1169# define R300_FPI0_ARG2C_ABS (1 << 20)
1170# define R300_FPI0_SPECIAL_LRP (1 << 21)
1171# define R300_FPI0_OUTC_MAD (0 << 23)
1172# define R300_FPI0_OUTC_DP3 (1 << 23)
1173# define R300_FPI0_OUTC_DP4 (2 << 23)
1174# define R300_FPI0_OUTC_MIN (4 << 23)
1175# define R300_FPI0_OUTC_MAX (5 << 23)
1176# define R300_FPI0_OUTC_CMPH (7 << 23)
1177# define R300_FPI0_OUTC_CMP (8 << 23)
1178# define R300_FPI0_OUTC_FRC (9 << 23)
1179# define R300_FPI0_OUTC_REPL_ALPHA (10 << 23)
1180# define R300_FPI0_OUTC_SAT (1 << 30)
1181# define R300_FPI0_INSERT_NOP (1 << 31)
1182
1183#define R300_PFS_INSTR2_0 0x49C0
1184# define R300_FPI2_ARGA_SRC0C_X 0
1185# define R300_FPI2_ARGA_SRC0C_Y 1
1186# define R300_FPI2_ARGA_SRC0C_Z 2
1187# define R300_FPI2_ARGA_SRC1C_X 3
1188# define R300_FPI2_ARGA_SRC1C_Y 4
1189# define R300_FPI2_ARGA_SRC1C_Z 5
1190# define R300_FPI2_ARGA_SRC2C_X 6
1191# define R300_FPI2_ARGA_SRC2C_Y 7
1192# define R300_FPI2_ARGA_SRC2C_Z 8
1193# define R300_FPI2_ARGA_SRC0A 9
1194# define R300_FPI2_ARGA_SRC1A 10
1195# define R300_FPI2_ARGA_SRC2A 11
1196# define R300_FPI2_ARGA_SRC1A_LRP 15
1197# define R300_FPI2_ARGA_ZERO 16
1198# define R300_FPI2_ARGA_ONE 17
1199 /* GUESS */
1200# define R300_FPI2_ARGA_HALF 18
1201# define R300_FPI2_ARG0A_SHIFT 0
1202# define R300_FPI2_ARG0A_MASK (31 << 0)
1203# define R300_FPI2_ARG0A_NEG (1 << 5)
1204 /* GUESS */
1205# define R300_FPI2_ARG0A_ABS (1 << 6)
1206# define R300_FPI2_ARG1A_SHIFT 7
1207# define R300_FPI2_ARG1A_MASK (31 << 7)
1208# define R300_FPI2_ARG1A_NEG (1 << 12)
1209 /* GUESS */
1210# define R300_FPI2_ARG1A_ABS (1 << 13)
1211# define R300_FPI2_ARG2A_SHIFT 14
1212# define R300_FPI2_ARG2A_MASK (31 << 14)
1213# define R300_FPI2_ARG2A_NEG (1 << 19)
1214 /* GUESS */
1215# define R300_FPI2_ARG2A_ABS (1 << 20)
1216# define R300_FPI2_SPECIAL_LRP (1 << 21)
1217# define R300_FPI2_OUTA_MAD (0 << 23)
1218# define R300_FPI2_OUTA_DP4 (1 << 23)
1219# define R300_FPI2_OUTA_MIN (2 << 23)
1220# define R300_FPI2_OUTA_MAX (3 << 23)
1221# define R300_FPI2_OUTA_CMP (6 << 23)
1222# define R300_FPI2_OUTA_FRC (7 << 23)
1223# define R300_FPI2_OUTA_EX2 (8 << 23)
1224# define R300_FPI2_OUTA_LG2 (9 << 23)
1225# define R300_FPI2_OUTA_RCP (10 << 23)
1226# define R300_FPI2_OUTA_RSQ (11 << 23)
1227# define R300_FPI2_OUTA_SAT (1 << 30)
1228# define R300_FPI2_UNKNOWN_31 (1 << 31)
1229/* END: Fragment program instruction set */
1230
1231/* Fog state and color */
1232#define R300_RE_FOG_STATE 0x4BC0
1233# define R300_FOG_ENABLE (1 << 0)
1234# define R300_FOG_MODE_LINEAR (0 << 1)
1235# define R300_FOG_MODE_EXP (1 << 1)
1236# define R300_FOG_MODE_EXP2 (2 << 1)
1237# define R300_FOG_MODE_MASK (3 << 1)
1238#define R300_FOG_COLOR_R 0x4BC8
1239#define R300_FOG_COLOR_G 0x4BCC
1240#define R300_FOG_COLOR_B 0x4BD0
1241
1242#define R300_PP_ALPHA_TEST 0x4BD4
1243# define R300_REF_ALPHA_MASK 0x000000ff
1244# define R300_ALPHA_TEST_FAIL (0 << 8)
1245# define R300_ALPHA_TEST_LESS (1 << 8)
1246# define R300_ALPHA_TEST_LEQUAL (3 << 8)
1247# define R300_ALPHA_TEST_EQUAL (2 << 8)
1248# define R300_ALPHA_TEST_GEQUAL (6 << 8)
1249# define R300_ALPHA_TEST_GREATER (4 << 8)
1250# define R300_ALPHA_TEST_NEQUAL (5 << 8)
1251# define R300_ALPHA_TEST_PASS (7 << 8)
1252# define R300_ALPHA_TEST_OP_MASK (7 << 8)
1253# define R300_ALPHA_TEST_ENABLE (1 << 11)
1254
1255/* gap */
1256
1257/* Fragment program parameters in 7.16 floating point */
1258#define R300_PFS_PARAM_0_X 0x4C00
1259#define R300_PFS_PARAM_0_Y 0x4C04
1260#define R300_PFS_PARAM_0_Z 0x4C08
1261#define R300_PFS_PARAM_0_W 0x4C0C
1262/* GUESS: PARAM_31 is last, based on native limits reported by fglrx */
1263#define R300_PFS_PARAM_31_X 0x4DF0
1264#define R300_PFS_PARAM_31_Y 0x4DF4
1265#define R300_PFS_PARAM_31_Z 0x4DF8
1266#define R300_PFS_PARAM_31_W 0x4DFC
1267
1268/* Notes:
1269 * - AFAIK fglrx always sets BLEND_UNKNOWN when blending is used in
1270 * the application
1271 * - AFAIK fglrx always sets BLEND_NO_SEPARATE when CBLEND and ABLEND
1272 * are set to the same
1273 * function (both registers are always set up completely in any case)
1274 * - Most blend flags are simply copied from R200 and not tested yet
1275 */
1276#define R300_RB3D_CBLEND 0x4E04
1277#define R300_RB3D_ABLEND 0x4E08
1278/* the following only appear in CBLEND */
1279# define R300_BLEND_ENABLE (1 << 0)
1280# define R300_BLEND_UNKNOWN (3 << 1)
1281# define R300_BLEND_NO_SEPARATE (1 << 3)
1282/* the following are shared between CBLEND and ABLEND */
1283# define R300_FCN_MASK (3 << 12)
1284# define R300_COMB_FCN_ADD_CLAMP (0 << 12)
1285# define R300_COMB_FCN_ADD_NOCLAMP (1 << 12)
1286# define R300_COMB_FCN_SUB_CLAMP (2 << 12)
1287# define R300_COMB_FCN_SUB_NOCLAMP (3 << 12)
1288# define R300_COMB_FCN_MIN (4 << 12)
1289# define R300_COMB_FCN_MAX (5 << 12)
1290# define R300_COMB_FCN_RSUB_CLAMP (6 << 12)
1291# define R300_COMB_FCN_RSUB_NOCLAMP (7 << 12)
1292# define R300_BLEND_GL_ZERO (32)
1293# define R300_BLEND_GL_ONE (33)
1294# define R300_BLEND_GL_SRC_COLOR (34)
1295# define R300_BLEND_GL_ONE_MINUS_SRC_COLOR (35)
1296# define R300_BLEND_GL_DST_COLOR (36)
1297# define R300_BLEND_GL_ONE_MINUS_DST_COLOR (37)
1298# define R300_BLEND_GL_SRC_ALPHA (38)
1299# define R300_BLEND_GL_ONE_MINUS_SRC_ALPHA (39)
1300# define R300_BLEND_GL_DST_ALPHA (40)
1301# define R300_BLEND_GL_ONE_MINUS_DST_ALPHA (41)
1302# define R300_BLEND_GL_SRC_ALPHA_SATURATE (42)
1303# define R300_BLEND_GL_CONST_COLOR (43)
1304# define R300_BLEND_GL_ONE_MINUS_CONST_COLOR (44)
1305# define R300_BLEND_GL_CONST_ALPHA (45)
1306# define R300_BLEND_GL_ONE_MINUS_CONST_ALPHA (46)
1307# define R300_BLEND_MASK (63)
1308# define R300_SRC_BLEND_SHIFT (16)
1309# define R300_DST_BLEND_SHIFT (24)
1310#define R300_RB3D_BLEND_COLOR 0x4E10
1311#define R300_RB3D_COLORMASK 0x4E0C
1312# define R300_COLORMASK0_B (1<<0)
1313# define R300_COLORMASK0_G (1<<1)
1314# define R300_COLORMASK0_R (1<<2)
1315# define R300_COLORMASK0_A (1<<3)
1316
1317/* gap */
1318
1319#define R300_RB3D_COLOROFFSET0 0x4E28
1320# define R300_COLOROFFSET_MASK 0xFFFFFFF0 /* GUESS */
1321#define R300_RB3D_COLOROFFSET1 0x4E2C /* GUESS */
1322#define R300_RB3D_COLOROFFSET2 0x4E30 /* GUESS */
1323#define R300_RB3D_COLOROFFSET3 0x4E34 /* GUESS */
1324
1325/* gap */
1326
1327/* Bit 16: Larger tiles
1328 * Bit 17: 4x2 tiles
1329 * Bit 18: Extremely weird tile like, but some pixels duplicated?
1330 */
1331#define R300_RB3D_COLORPITCH0 0x4E38
1332# define R300_COLORPITCH_MASK 0x00001FF8 /* GUESS */
1333# define R300_COLOR_TILE_ENABLE (1 << 16) /* GUESS */
1334# define R300_COLOR_MICROTILE_ENABLE (1 << 17) /* GUESS */
1335# define R300_COLOR_ENDIAN_NO_SWAP (0 << 18) /* GUESS */
1336# define R300_COLOR_ENDIAN_WORD_SWAP (1 << 18) /* GUESS */
1337# define R300_COLOR_ENDIAN_DWORD_SWAP (2 << 18) /* GUESS */
1338# define R300_COLOR_FORMAT_RGB565 (2 << 22)
1339# define R300_COLOR_FORMAT_ARGB8888 (3 << 22)
1340#define R300_RB3D_COLORPITCH1 0x4E3C /* GUESS */
1341#define R300_RB3D_COLORPITCH2 0x4E40 /* GUESS */
1342#define R300_RB3D_COLORPITCH3 0x4E44 /* GUESS */
1343
1344/* gap */
1345
1346/* Guess by Vladimir.
1347 * Set to 0A before 3D operations, set to 02 afterwards.
1348 */
1349#define R300_RB3D_DSTCACHE_CTLSTAT 0x4E4C
1350# define R300_RB3D_DSTCACHE_UNKNOWN_02 0x00000002
1351# define R300_RB3D_DSTCACHE_UNKNOWN_0A 0x0000000A
1352
1353/* gap */
1354/* There seems to be no "write only" setting, so use Z-test = ALWAYS
1355 * for this.
1356 * Bit (1<<8) is the "test" bit. so plain write is 6 - vd
1357 */
1358#define R300_RB3D_ZSTENCIL_CNTL_0 0x4F00
1359# define R300_RB3D_Z_DISABLED_1 0x00000010
1360# define R300_RB3D_Z_DISABLED_2 0x00000014
1361# define R300_RB3D_Z_TEST 0x00000012
1362# define R300_RB3D_Z_TEST_AND_WRITE 0x00000016
1363# define R300_RB3D_Z_WRITE_ONLY 0x00000006
1364
1365# define R300_RB3D_Z_TEST 0x00000012
1366# define R300_RB3D_Z_TEST_AND_WRITE 0x00000016
1367# define R300_RB3D_Z_WRITE_ONLY 0x00000006
1368# define R300_RB3D_STENCIL_ENABLE 0x00000001
1369
1370#define R300_RB3D_ZSTENCIL_CNTL_1 0x4F04
1371 /* functions */
1372# define R300_ZS_NEVER 0
1373# define R300_ZS_LESS 1
1374# define R300_ZS_LEQUAL 2
1375# define R300_ZS_EQUAL 3
1376# define R300_ZS_GEQUAL 4
1377# define R300_ZS_GREATER 5
1378# define R300_ZS_NOTEQUAL 6
1379# define R300_ZS_ALWAYS 7
1380# define R300_ZS_MASK 7
1381 /* operations */
1382# define R300_ZS_KEEP 0
1383# define R300_ZS_ZERO 1
1384# define R300_ZS_REPLACE 2
1385# define R300_ZS_INCR 3
1386# define R300_ZS_DECR 4
1387# define R300_ZS_INVERT 5
1388# define R300_ZS_INCR_WRAP 6
1389# define R300_ZS_DECR_WRAP 7
1390 /* front and back refer to operations done for front
1391 and back faces, i.e. separate stencil function support */
1392# define R300_RB3D_ZS1_DEPTH_FUNC_SHIFT 0
1393# define R300_RB3D_ZS1_FRONT_FUNC_SHIFT 3
1394# define R300_RB3D_ZS1_FRONT_FAIL_OP_SHIFT 6
1395# define R300_RB3D_ZS1_FRONT_ZPASS_OP_SHIFT 9
1396# define R300_RB3D_ZS1_FRONT_ZFAIL_OP_SHIFT 12
1397# define R300_RB3D_ZS1_BACK_FUNC_SHIFT 15
1398# define R300_RB3D_ZS1_BACK_FAIL_OP_SHIFT 18
1399# define R300_RB3D_ZS1_BACK_ZPASS_OP_SHIFT 21
1400# define R300_RB3D_ZS1_BACK_ZFAIL_OP_SHIFT 24
1401
1402#define R300_RB3D_ZSTENCIL_CNTL_2 0x4F08
1403# define R300_RB3D_ZS2_STENCIL_REF_SHIFT 0
1404# define R300_RB3D_ZS2_STENCIL_MASK 0xFF
1405# define R300_RB3D_ZS2_STENCIL_MASK_SHIFT 8
1406# define R300_RB3D_ZS2_STENCIL_WRITE_MASK_SHIFT 16
1407
1408/* gap */
1409
1410#define R300_RB3D_ZSTENCIL_FORMAT 0x4F10
1411# define R300_DEPTH_FORMAT_16BIT_INT_Z (0 << 0)
1412# define R300_DEPTH_FORMAT_24BIT_INT_Z (2 << 0)
1413 /* 16 bit format or some aditional bit ? */
1414# define R300_DEPTH_FORMAT_UNK32 (32 << 0)
1415
1416#define R300_RB3D_EARLY_Z 0x4F14
1417# define R300_EARLY_Z_DISABLE (0 << 0)
1418# define R300_EARLY_Z_ENABLE (1 << 0)
1419
1420/* gap */
1421
1422#define R300_RB3D_ZCACHE_CTLSTAT 0x4F18 /* GUESS */
1423# define R300_RB3D_ZCACHE_UNKNOWN_01 0x1
1424# define R300_RB3D_ZCACHE_UNKNOWN_03 0x3
1425
1426/* gap */
1427
1428#define R300_RB3D_DEPTHOFFSET 0x4F20
1429#define R300_RB3D_DEPTHPITCH 0x4F24
1430# define R300_DEPTHPITCH_MASK 0x00001FF8 /* GUESS */
1431# define R300_DEPTH_TILE_ENABLE (1 << 16) /* GUESS */
1432# define R300_DEPTH_MICROTILE_ENABLE (1 << 17) /* GUESS */
1433# define R300_DEPTH_ENDIAN_NO_SWAP (0 << 18) /* GUESS */
1434# define R300_DEPTH_ENDIAN_WORD_SWAP (1 << 18) /* GUESS */
1435# define R300_DEPTH_ENDIAN_DWORD_SWAP (2 << 18) /* GUESS */
1436
1437/* BEGIN: Vertex program instruction set */
1438
1439/* Every instruction is four dwords long:
1440 * DWORD 0: output and opcode
1441 * DWORD 1: first argument
1442 * DWORD 2: second argument
1443 * DWORD 3: third argument
1444 *
1445 * Notes:
1446 * - ABS r, a is implemented as MAX r, a, -a
1447 * - MOV is implemented as ADD to zero
1448 * - XPD is implemented as MUL + MAD
1449 * - FLR is implemented as FRC + ADD
1450 * - apparently, fglrx tries to schedule instructions so that there is at
1451 * least one instruction between the write to a temporary and the first
1452 * read from said temporary; however, violations of this scheduling are
1453 * allowed
1454 * - register indices seem to be unrelated with OpenGL aliasing to
1455 * conventional state
1456 * - only one attribute and one parameter can be loaded at a time; however,
1457 * the same attribute/parameter can be used for more than one argument
1458 * - the second software argument for POW is the third hardware argument
1459 * (no idea why)
1460 * - MAD with only temporaries as input seems to use VPI_OUT_SELECT_MAD_2
1461 *
1462 * There is some magic surrounding LIT:
1463 * The single argument is replicated across all three inputs, but swizzled:
1464 * First argument: xyzy
1465 * Second argument: xyzx
1466 * Third argument: xyzw
1467 * Whenever the result is used later in the fragment program, fglrx forces
1468 * x and w to be 1.0 in the input selection; I don't know whether this is
1469 * strictly necessary
1470 */
1471#define R300_VPI_OUT_OP_DOT (1 << 0)
1472#define R300_VPI_OUT_OP_MUL (2 << 0)
1473#define R300_VPI_OUT_OP_ADD (3 << 0)
1474#define R300_VPI_OUT_OP_MAD (4 << 0)
1475#define R300_VPI_OUT_OP_DST (5 << 0)
1476#define R300_VPI_OUT_OP_FRC (6 << 0)
1477#define R300_VPI_OUT_OP_MAX (7 << 0)
1478#define R300_VPI_OUT_OP_MIN (8 << 0)
1479#define R300_VPI_OUT_OP_SGE (9 << 0)
1480#define R300_VPI_OUT_OP_SLT (10 << 0)
1481 /* Used in GL_POINT_DISTANCE_ATTENUATION_ARB, vector(scalar, vector) */
1482#define R300_VPI_OUT_OP_UNK12 (12 << 0)
1483#define R300_VPI_OUT_OP_ARL (13 << 0)
1484#define R300_VPI_OUT_OP_EXP (65 << 0)
1485#define R300_VPI_OUT_OP_LOG (66 << 0)
1486 /* Used in fog computations, scalar(scalar) */
1487#define R300_VPI_OUT_OP_UNK67 (67 << 0)
1488#define R300_VPI_OUT_OP_LIT (68 << 0)
1489#define R300_VPI_OUT_OP_POW (69 << 0)
1490#define R300_VPI_OUT_OP_RCP (70 << 0)
1491#define R300_VPI_OUT_OP_RSQ (72 << 0)
1492 /* Used in GL_POINT_DISTANCE_ATTENUATION_ARB, scalar(scalar) */
1493#define R300_VPI_OUT_OP_UNK73 (73 << 0)
1494#define R300_VPI_OUT_OP_EX2 (75 << 0)
1495#define R300_VPI_OUT_OP_LG2 (76 << 0)
1496#define R300_VPI_OUT_OP_MAD_2 (128 << 0)
1497 /* all temps, vector(scalar, vector, vector) */
1498#define R300_VPI_OUT_OP_UNK129 (129 << 0)
1499
1500#define R300_VPI_OUT_REG_CLASS_TEMPORARY (0 << 8)
1501#define R300_VPI_OUT_REG_CLASS_ADDR (1 << 8)
1502#define R300_VPI_OUT_REG_CLASS_RESULT (2 << 8)
1503#define R300_VPI_OUT_REG_CLASS_MASK (31 << 8)
1504
1505#define R300_VPI_OUT_REG_INDEX_SHIFT 13
1506 /* GUESS based on fglrx native limits */
1507#define R300_VPI_OUT_REG_INDEX_MASK (31 << 13)
1508
1509#define R300_VPI_OUT_WRITE_X (1 << 20)
1510#define R300_VPI_OUT_WRITE_Y (1 << 21)
1511#define R300_VPI_OUT_WRITE_Z (1 << 22)
1512#define R300_VPI_OUT_WRITE_W (1 << 23)
1513
1514#define R300_VPI_IN_REG_CLASS_TEMPORARY (0 << 0)
1515#define R300_VPI_IN_REG_CLASS_ATTRIBUTE (1 << 0)
1516#define R300_VPI_IN_REG_CLASS_PARAMETER (2 << 0)
1517#define R300_VPI_IN_REG_CLASS_NONE (9 << 0)
1518#define R300_VPI_IN_REG_CLASS_MASK (31 << 0)
1519
1520#define R300_VPI_IN_REG_INDEX_SHIFT 5
1521 /* GUESS based on fglrx native limits */
1522#define R300_VPI_IN_REG_INDEX_MASK (255 << 5)
1523
1524/* The R300 can select components from the input register arbitrarily.
1525 * Use the following constants, shifted by the component shift you
1526 * want to select
1527 */
1528#define R300_VPI_IN_SELECT_X 0
1529#define R300_VPI_IN_SELECT_Y 1
1530#define R300_VPI_IN_SELECT_Z 2
1531#define R300_VPI_IN_SELECT_W 3
1532#define R300_VPI_IN_SELECT_ZERO 4
1533#define R300_VPI_IN_SELECT_ONE 5
1534#define R300_VPI_IN_SELECT_MASK 7
1535
1536#define R300_VPI_IN_X_SHIFT 13
1537#define R300_VPI_IN_Y_SHIFT 16
1538#define R300_VPI_IN_Z_SHIFT 19
1539#define R300_VPI_IN_W_SHIFT 22
1540
1541#define R300_VPI_IN_NEG_X (1 << 25)
1542#define R300_VPI_IN_NEG_Y (1 << 26)
1543#define R300_VPI_IN_NEG_Z (1 << 27)
1544#define R300_VPI_IN_NEG_W (1 << 28)
1545/* END: Vertex program instruction set */
1546
1547/* BEGIN: Packet 3 commands */
1548
1549/* A primitive emission dword. */
1550#define R300_PRIM_TYPE_NONE (0 << 0)
1551#define R300_PRIM_TYPE_POINT (1 << 0)
1552#define R300_PRIM_TYPE_LINE (2 << 0)
1553#define R300_PRIM_TYPE_LINE_STRIP (3 << 0)
1554#define R300_PRIM_TYPE_TRI_LIST (4 << 0)
1555#define R300_PRIM_TYPE_TRI_FAN (5 << 0)
1556#define R300_PRIM_TYPE_TRI_STRIP (6 << 0)
1557#define R300_PRIM_TYPE_TRI_TYPE2 (7 << 0)
1558#define R300_PRIM_TYPE_RECT_LIST (8 << 0)
1559#define R300_PRIM_TYPE_3VRT_POINT_LIST (9 << 0)
1560#define R300_PRIM_TYPE_3VRT_LINE_LIST (10 << 0)
1561 /* GUESS (based on r200) */
1562#define R300_PRIM_TYPE_POINT_SPRITES (11 << 0)
1563#define R300_PRIM_TYPE_LINE_LOOP (12 << 0)
1564#define R300_PRIM_TYPE_QUADS (13 << 0)
1565#define R300_PRIM_TYPE_QUAD_STRIP (14 << 0)
1566#define R300_PRIM_TYPE_POLYGON (15 << 0)
1567#define R300_PRIM_TYPE_MASK 0xF
1568#define R300_PRIM_WALK_IND (1 << 4)
1569#define R300_PRIM_WALK_LIST (2 << 4)
1570#define R300_PRIM_WALK_RING (3 << 4)
1571#define R300_PRIM_WALK_MASK (3 << 4)
1572 /* GUESS (based on r200) */
1573#define R300_PRIM_COLOR_ORDER_BGRA (0 << 6)
1574#define R300_PRIM_COLOR_ORDER_RGBA (1 << 6)
1575#define R300_PRIM_NUM_VERTICES_SHIFT 16
1576#define R300_PRIM_NUM_VERTICES_MASK 0xffff
1577
1578/* Draw a primitive from vertex data in arrays loaded via 3D_LOAD_VBPNTR.
1579 * Two parameter dwords:
1580 * 0. The first parameter appears to be always 0
1581 * 1. The second parameter is a standard primitive emission dword.
1582 */
1583#define R300_PACKET3_3D_DRAW_VBUF 0x00002800
1584
1585/* Specify the full set of vertex arrays as (address, stride).
1586 * The first parameter is the number of vertex arrays specified.
1587 * The rest of the command is a variable length list of blocks, where
1588 * each block is three dwords long and specifies two arrays.
1589 * The first dword of a block is split into two words, the lower significant
1590 * word refers to the first array, the more significant word to the second
1591 * array in the block.
1592 * The low byte of each word contains the size of an array entry in dwords,
1593 * the high byte contains the stride of the array.
1594 * The second dword of a block contains the pointer to the first array,
1595 * the third dword of a block contains the pointer to the second array.
1596 * Note that if the total number of arrays is odd, the third dword of
1597 * the last block is omitted.
1598 */
1599#define R300_PACKET3_3D_LOAD_VBPNTR 0x00002F00
1600
1601#define R300_PACKET3_INDX_BUFFER 0x00003300
1602# define R300_EB_UNK1_SHIFT 24
1603# define R300_EB_UNK1 (0x80<<24)
1604# define R300_EB_UNK2 0x0810
1605#define R300_PACKET3_3D_DRAW_VBUF_2 0x00003400
1606#define R300_PACKET3_3D_DRAW_INDX_2 0x00003600
1607
1608/* END: Packet 3 commands */
1609
1610
1611/* Color formats for 2d packets
1612 */
1613#define R300_CP_COLOR_FORMAT_CI8 2
1614#define R300_CP_COLOR_FORMAT_ARGB1555 3
1615#define R300_CP_COLOR_FORMAT_RGB565 4
1616#define R300_CP_COLOR_FORMAT_ARGB8888 6
1617#define R300_CP_COLOR_FORMAT_RGB332 7
1618#define R300_CP_COLOR_FORMAT_RGB8 9
1619#define R300_CP_COLOR_FORMAT_ARGB4444 15
1620
1621/*
1622 * CP type-3 packets
1623 */
1624#define R300_CP_CMD_BITBLT_MULTI 0xC0009B00
1625
1626#endif /* _R300_REG_H */
diff --git a/drivers/char/drm/radeon_cp.c b/drivers/char/drm/radeon_cp.c
deleted file mode 100644
index f6f6c92bf771..000000000000
--- a/drivers/char/drm/radeon_cp.c
+++ /dev/null
@@ -1,2435 +0,0 @@
1/* radeon_cp.c -- CP support for Radeon -*- linux-c -*- */
2/*
3 * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas.
4 * Copyright 2000 VA Linux Systems, Inc., Fremont, California.
5 * All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the next
15 * paragraph) shall be included in all copies or substantial portions of the
16 * Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
22 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 * DEALINGS IN THE SOFTWARE.
25 *
26 * Authors:
27 * Kevin E. Martin <martin@valinux.com>
28 * Gareth Hughes <gareth@valinux.com>
29 */
30
31#include "drmP.h"
32#include "drm.h"
33#include "radeon_drm.h"
34#include "radeon_drv.h"
35#include "r300_reg.h"
36
37#define RADEON_FIFO_DEBUG 0
38
39static int radeon_do_cleanup_cp(struct drm_device * dev);
40
41/* CP microcode (from ATI) */
42static const u32 R200_cp_microcode[][2] = {
43 {0x21007000, 0000000000},
44 {0x20007000, 0000000000},
45 {0x000000ab, 0x00000004},
46 {0x000000af, 0x00000004},
47 {0x66544a49, 0000000000},
48 {0x49494174, 0000000000},
49 {0x54517d83, 0000000000},
50 {0x498d8b64, 0000000000},
51 {0x49494949, 0000000000},
52 {0x49da493c, 0000000000},
53 {0x49989898, 0000000000},
54 {0xd34949d5, 0000000000},
55 {0x9dc90e11, 0000000000},
56 {0xce9b9b9b, 0000000000},
57 {0x000f0000, 0x00000016},
58 {0x352e232c, 0000000000},
59 {0x00000013, 0x00000004},
60 {0x000f0000, 0x00000016},
61 {0x352e272c, 0000000000},
62 {0x000f0001, 0x00000016},
63 {0x3239362f, 0000000000},
64 {0x000077ef, 0x00000002},
65 {0x00061000, 0x00000002},
66 {0x00000020, 0x0000001a},
67 {0x00004000, 0x0000001e},
68 {0x00061000, 0x00000002},
69 {0x00000020, 0x0000001a},
70 {0x00004000, 0x0000001e},
71 {0x00061000, 0x00000002},
72 {0x00000020, 0x0000001a},
73 {0x00004000, 0x0000001e},
74 {0x00000016, 0x00000004},
75 {0x0003802a, 0x00000002},
76 {0x040067e0, 0x00000002},
77 {0x00000016, 0x00000004},
78 {0x000077e0, 0x00000002},
79 {0x00065000, 0x00000002},
80 {0x000037e1, 0x00000002},
81 {0x040067e1, 0x00000006},
82 {0x000077e0, 0x00000002},
83 {0x000077e1, 0x00000002},
84 {0x000077e1, 0x00000006},
85 {0xffffffff, 0000000000},
86 {0x10000000, 0000000000},
87 {0x0003802a, 0x00000002},
88 {0x040067e0, 0x00000006},
89 {0x00007675, 0x00000002},
90 {0x00007676, 0x00000002},
91 {0x00007677, 0x00000002},
92 {0x00007678, 0x00000006},
93 {0x0003802b, 0x00000002},
94 {0x04002676, 0x00000002},
95 {0x00007677, 0x00000002},
96 {0x00007678, 0x00000006},
97 {0x0000002e, 0x00000018},
98 {0x0000002e, 0x00000018},
99 {0000000000, 0x00000006},
100 {0x0000002f, 0x00000018},
101 {0x0000002f, 0x00000018},
102 {0000000000, 0x00000006},
103 {0x01605000, 0x00000002},
104 {0x00065000, 0x00000002},
105 {0x00098000, 0x00000002},
106 {0x00061000, 0x00000002},
107 {0x64c0603d, 0x00000004},
108 {0x00080000, 0x00000016},
109 {0000000000, 0000000000},
110 {0x0400251d, 0x00000002},
111 {0x00007580, 0x00000002},
112 {0x00067581, 0x00000002},
113 {0x04002580, 0x00000002},
114 {0x00067581, 0x00000002},
115 {0x00000046, 0x00000004},
116 {0x00005000, 0000000000},
117 {0x00061000, 0x00000002},
118 {0x0000750e, 0x00000002},
119 {0x00019000, 0x00000002},
120 {0x00011055, 0x00000014},
121 {0x00000055, 0x00000012},
122 {0x0400250f, 0x00000002},
123 {0x0000504a, 0x00000004},
124 {0x00007565, 0x00000002},
125 {0x00007566, 0x00000002},
126 {0x00000051, 0x00000004},
127 {0x01e655b4, 0x00000002},
128 {0x4401b0dc, 0x00000002},
129 {0x01c110dc, 0x00000002},
130 {0x2666705d, 0x00000018},
131 {0x040c2565, 0x00000002},
132 {0x0000005d, 0x00000018},
133 {0x04002564, 0x00000002},
134 {0x00007566, 0x00000002},
135 {0x00000054, 0x00000004},
136 {0x00401060, 0x00000008},
137 {0x00101000, 0x00000002},
138 {0x000d80ff, 0x00000002},
139 {0x00800063, 0x00000008},
140 {0x000f9000, 0x00000002},
141 {0x000e00ff, 0x00000002},
142 {0000000000, 0x00000006},
143 {0x00000080, 0x00000018},
144 {0x00000054, 0x00000004},
145 {0x00007576, 0x00000002},
146 {0x00065000, 0x00000002},
147 {0x00009000, 0x00000002},
148 {0x00041000, 0x00000002},
149 {0x0c00350e, 0x00000002},
150 {0x00049000, 0x00000002},
151 {0x00051000, 0x00000002},
152 {0x01e785f8, 0x00000002},
153 {0x00200000, 0x00000002},
154 {0x00600073, 0x0000000c},
155 {0x00007563, 0x00000002},
156 {0x006075f0, 0x00000021},
157 {0x20007068, 0x00000004},
158 {0x00005068, 0x00000004},
159 {0x00007576, 0x00000002},
160 {0x00007577, 0x00000002},
161 {0x0000750e, 0x00000002},
162 {0x0000750f, 0x00000002},
163 {0x00a05000, 0x00000002},
164 {0x00600076, 0x0000000c},
165 {0x006075f0, 0x00000021},
166 {0x000075f8, 0x00000002},
167 {0x00000076, 0x00000004},
168 {0x000a750e, 0x00000002},
169 {0x0020750f, 0x00000002},
170 {0x00600079, 0x00000004},
171 {0x00007570, 0x00000002},
172 {0x00007571, 0x00000002},
173 {0x00007572, 0x00000006},
174 {0x00005000, 0x00000002},
175 {0x00a05000, 0x00000002},
176 {0x00007568, 0x00000002},
177 {0x00061000, 0x00000002},
178 {0x00000084, 0x0000000c},
179 {0x00058000, 0x00000002},
180 {0x0c607562, 0x00000002},
181 {0x00000086, 0x00000004},
182 {0x00600085, 0x00000004},
183 {0x400070dd, 0000000000},
184 {0x000380dd, 0x00000002},
185 {0x00000093, 0x0000001c},
186 {0x00065095, 0x00000018},
187 {0x040025bb, 0x00000002},
188 {0x00061096, 0x00000018},
189 {0x040075bc, 0000000000},
190 {0x000075bb, 0x00000002},
191 {0x000075bc, 0000000000},
192 {0x00090000, 0x00000006},
193 {0x00090000, 0x00000002},
194 {0x000d8002, 0x00000006},
195 {0x00005000, 0x00000002},
196 {0x00007821, 0x00000002},
197 {0x00007800, 0000000000},
198 {0x00007821, 0x00000002},
199 {0x00007800, 0000000000},
200 {0x01665000, 0x00000002},
201 {0x000a0000, 0x00000002},
202 {0x000671cc, 0x00000002},
203 {0x0286f1cd, 0x00000002},
204 {0x000000a3, 0x00000010},
205 {0x21007000, 0000000000},
206 {0x000000aa, 0x0000001c},
207 {0x00065000, 0x00000002},
208 {0x000a0000, 0x00000002},
209 {0x00061000, 0x00000002},
210 {0x000b0000, 0x00000002},
211 {0x38067000, 0x00000002},
212 {0x000a00a6, 0x00000004},
213 {0x20007000, 0000000000},
214 {0x01200000, 0x00000002},
215 {0x20077000, 0x00000002},
216 {0x01200000, 0x00000002},
217 {0x20007000, 0000000000},
218 {0x00061000, 0x00000002},
219 {0x0120751b, 0x00000002},
220 {0x8040750a, 0x00000002},
221 {0x8040750b, 0x00000002},
222 {0x00110000, 0x00000002},
223 {0x000380dd, 0x00000002},
224 {0x000000bd, 0x0000001c},
225 {0x00061096, 0x00000018},
226 {0x844075bd, 0x00000002},
227 {0x00061095, 0x00000018},
228 {0x840075bb, 0x00000002},
229 {0x00061096, 0x00000018},
230 {0x844075bc, 0x00000002},
231 {0x000000c0, 0x00000004},
232 {0x804075bd, 0x00000002},
233 {0x800075bb, 0x00000002},
234 {0x804075bc, 0x00000002},
235 {0x00108000, 0x00000002},
236 {0x01400000, 0x00000002},
237 {0x006000c4, 0x0000000c},
238 {0x20c07000, 0x00000020},
239 {0x000000c6, 0x00000012},
240 {0x00800000, 0x00000006},
241 {0x0080751d, 0x00000006},
242 {0x000025bb, 0x00000002},
243 {0x000040c0, 0x00000004},
244 {0x0000775c, 0x00000002},
245 {0x00a05000, 0x00000002},
246 {0x00661000, 0x00000002},
247 {0x0460275d, 0x00000020},
248 {0x00004000, 0000000000},
249 {0x00007999, 0x00000002},
250 {0x00a05000, 0x00000002},
251 {0x00661000, 0x00000002},
252 {0x0460299b, 0x00000020},
253 {0x00004000, 0000000000},
254 {0x01e00830, 0x00000002},
255 {0x21007000, 0000000000},
256 {0x00005000, 0x00000002},
257 {0x00038042, 0x00000002},
258 {0x040025e0, 0x00000002},
259 {0x000075e1, 0000000000},
260 {0x00000001, 0000000000},
261 {0x000380d9, 0x00000002},
262 {0x04007394, 0000000000},
263 {0000000000, 0000000000},
264 {0000000000, 0000000000},
265 {0000000000, 0000000000},
266 {0000000000, 0000000000},
267 {0000000000, 0000000000},
268 {0000000000, 0000000000},
269 {0000000000, 0000000000},
270 {0000000000, 0000000000},
271 {0000000000, 0000000000},
272 {0000000000, 0000000000},
273 {0000000000, 0000000000},
274 {0000000000, 0000000000},
275 {0000000000, 0000000000},
276 {0000000000, 0000000000},
277 {0000000000, 0000000000},
278 {0000000000, 0000000000},
279 {0000000000, 0000000000},
280 {0000000000, 0000000000},
281 {0000000000, 0000000000},
282 {0000000000, 0000000000},
283 {0000000000, 0000000000},
284 {0000000000, 0000000000},
285 {0000000000, 0000000000},
286 {0000000000, 0000000000},
287 {0000000000, 0000000000},
288 {0000000000, 0000000000},
289 {0000000000, 0000000000},
290 {0000000000, 0000000000},
291 {0000000000, 0000000000},
292 {0000000000, 0000000000},
293 {0000000000, 0000000000},
294 {0000000000, 0000000000},
295 {0000000000, 0000000000},
296 {0000000000, 0000000000},
297 {0000000000, 0000000000},
298 {0000000000, 0000000000},
299};
300
301static const u32 radeon_cp_microcode[][2] = {
302 {0x21007000, 0000000000},
303 {0x20007000, 0000000000},
304 {0x000000b4, 0x00000004},
305 {0x000000b8, 0x00000004},
306 {0x6f5b4d4c, 0000000000},
307 {0x4c4c427f, 0000000000},
308 {0x5b568a92, 0000000000},
309 {0x4ca09c6d, 0000000000},
310 {0xad4c4c4c, 0000000000},
311 {0x4ce1af3d, 0000000000},
312 {0xd8afafaf, 0000000000},
313 {0xd64c4cdc, 0000000000},
314 {0x4cd10d10, 0000000000},
315 {0x000f0000, 0x00000016},
316 {0x362f242d, 0000000000},
317 {0x00000012, 0x00000004},
318 {0x000f0000, 0x00000016},
319 {0x362f282d, 0000000000},
320 {0x000380e7, 0x00000002},
321 {0x04002c97, 0x00000002},
322 {0x000f0001, 0x00000016},
323 {0x333a3730, 0000000000},
324 {0x000077ef, 0x00000002},
325 {0x00061000, 0x00000002},
326 {0x00000021, 0x0000001a},
327 {0x00004000, 0x0000001e},
328 {0x00061000, 0x00000002},
329 {0x00000021, 0x0000001a},
330 {0x00004000, 0x0000001e},
331 {0x00061000, 0x00000002},
332 {0x00000021, 0x0000001a},
333 {0x00004000, 0x0000001e},
334 {0x00000017, 0x00000004},
335 {0x0003802b, 0x00000002},
336 {0x040067e0, 0x00000002},
337 {0x00000017, 0x00000004},
338 {0x000077e0, 0x00000002},
339 {0x00065000, 0x00000002},
340 {0x000037e1, 0x00000002},
341 {0x040067e1, 0x00000006},
342 {0x000077e0, 0x00000002},
343 {0x000077e1, 0x00000002},
344 {0x000077e1, 0x00000006},
345 {0xffffffff, 0000000000},
346 {0x10000000, 0000000000},
347 {0x0003802b, 0x00000002},
348 {0x040067e0, 0x00000006},
349 {0x00007675, 0x00000002},
350 {0x00007676, 0x00000002},
351 {0x00007677, 0x00000002},
352 {0x00007678, 0x00000006},
353 {0x0003802c, 0x00000002},
354 {0x04002676, 0x00000002},
355 {0x00007677, 0x00000002},
356 {0x00007678, 0x00000006},
357 {0x0000002f, 0x00000018},
358 {0x0000002f, 0x00000018},
359 {0000000000, 0x00000006},
360 {0x00000030, 0x00000018},
361 {0x00000030, 0x00000018},
362 {0000000000, 0x00000006},
363 {0x01605000, 0x00000002},
364 {0x00065000, 0x00000002},
365 {0x00098000, 0x00000002},
366 {0x00061000, 0x00000002},
367 {0x64c0603e, 0x00000004},
368 {0x000380e6, 0x00000002},
369 {0x040025c5, 0x00000002},
370 {0x00080000, 0x00000016},
371 {0000000000, 0000000000},
372 {0x0400251d, 0x00000002},
373 {0x00007580, 0x00000002},
374 {0x00067581, 0x00000002},
375 {0x04002580, 0x00000002},
376 {0x00067581, 0x00000002},
377 {0x00000049, 0x00000004},
378 {0x00005000, 0000000000},
379 {0x000380e6, 0x00000002},
380 {0x040025c5, 0x00000002},
381 {0x00061000, 0x00000002},
382 {0x0000750e, 0x00000002},
383 {0x00019000, 0x00000002},
384 {0x00011055, 0x00000014},
385 {0x00000055, 0x00000012},
386 {0x0400250f, 0x00000002},
387 {0x0000504f, 0x00000004},
388 {0x000380e6, 0x00000002},
389 {0x040025c5, 0x00000002},
390 {0x00007565, 0x00000002},
391 {0x00007566, 0x00000002},
392 {0x00000058, 0x00000004},
393 {0x000380e6, 0x00000002},
394 {0x040025c5, 0x00000002},
395 {0x01e655b4, 0x00000002},
396 {0x4401b0e4, 0x00000002},
397 {0x01c110e4, 0x00000002},
398 {0x26667066, 0x00000018},
399 {0x040c2565, 0x00000002},
400 {0x00000066, 0x00000018},
401 {0x04002564, 0x00000002},
402 {0x00007566, 0x00000002},
403 {0x0000005d, 0x00000004},
404 {0x00401069, 0x00000008},
405 {0x00101000, 0x00000002},
406 {0x000d80ff, 0x00000002},
407 {0x0080006c, 0x00000008},
408 {0x000f9000, 0x00000002},
409 {0x000e00ff, 0x00000002},
410 {0000000000, 0x00000006},
411 {0x0000008f, 0x00000018},
412 {0x0000005b, 0x00000004},
413 {0x000380e6, 0x00000002},
414 {0x040025c5, 0x00000002},
415 {0x00007576, 0x00000002},
416 {0x00065000, 0x00000002},
417 {0x00009000, 0x00000002},
418 {0x00041000, 0x00000002},
419 {0x0c00350e, 0x00000002},
420 {0x00049000, 0x00000002},
421 {0x00051000, 0x00000002},
422 {0x01e785f8, 0x00000002},
423 {0x00200000, 0x00000002},
424 {0x0060007e, 0x0000000c},
425 {0x00007563, 0x00000002},
426 {0x006075f0, 0x00000021},
427 {0x20007073, 0x00000004},
428 {0x00005073, 0x00000004},
429 {0x000380e6, 0x00000002},
430 {0x040025c5, 0x00000002},
431 {0x00007576, 0x00000002},
432 {0x00007577, 0x00000002},
433 {0x0000750e, 0x00000002},
434 {0x0000750f, 0x00000002},
435 {0x00a05000, 0x00000002},
436 {0x00600083, 0x0000000c},
437 {0x006075f0, 0x00000021},
438 {0x000075f8, 0x00000002},
439 {0x00000083, 0x00000004},
440 {0x000a750e, 0x00000002},
441 {0x000380e6, 0x00000002},
442 {0x040025c5, 0x00000002},
443 {0x0020750f, 0x00000002},
444 {0x00600086, 0x00000004},
445 {0x00007570, 0x00000002},
446 {0x00007571, 0x00000002},
447 {0x00007572, 0x00000006},
448 {0x000380e6, 0x00000002},
449 {0x040025c5, 0x00000002},
450 {0x00005000, 0x00000002},
451 {0x00a05000, 0x00000002},
452 {0x00007568, 0x00000002},
453 {0x00061000, 0x00000002},
454 {0x00000095, 0x0000000c},
455 {0x00058000, 0x00000002},
456 {0x0c607562, 0x00000002},
457 {0x00000097, 0x00000004},
458 {0x000380e6, 0x00000002},
459 {0x040025c5, 0x00000002},
460 {0x00600096, 0x00000004},
461 {0x400070e5, 0000000000},
462 {0x000380e6, 0x00000002},
463 {0x040025c5, 0x00000002},
464 {0x000380e5, 0x00000002},
465 {0x000000a8, 0x0000001c},
466 {0x000650aa, 0x00000018},
467 {0x040025bb, 0x00000002},
468 {0x000610ab, 0x00000018},
469 {0x040075bc, 0000000000},
470 {0x000075bb, 0x00000002},
471 {0x000075bc, 0000000000},
472 {0x00090000, 0x00000006},
473 {0x00090000, 0x00000002},
474 {0x000d8002, 0x00000006},
475 {0x00007832, 0x00000002},
476 {0x00005000, 0x00000002},
477 {0x000380e7, 0x00000002},
478 {0x04002c97, 0x00000002},
479 {0x00007820, 0x00000002},
480 {0x00007821, 0x00000002},
481 {0x00007800, 0000000000},
482 {0x01200000, 0x00000002},
483 {0x20077000, 0x00000002},
484 {0x01200000, 0x00000002},
485 {0x20007000, 0x00000002},
486 {0x00061000, 0x00000002},
487 {0x0120751b, 0x00000002},
488 {0x8040750a, 0x00000002},
489 {0x8040750b, 0x00000002},
490 {0x00110000, 0x00000002},
491 {0x000380e5, 0x00000002},
492 {0x000000c6, 0x0000001c},
493 {0x000610ab, 0x00000018},
494 {0x844075bd, 0x00000002},
495 {0x000610aa, 0x00000018},
496 {0x840075bb, 0x00000002},
497 {0x000610ab, 0x00000018},
498 {0x844075bc, 0x00000002},
499 {0x000000c9, 0x00000004},
500 {0x804075bd, 0x00000002},
501 {0x800075bb, 0x00000002},
502 {0x804075bc, 0x00000002},
503 {0x00108000, 0x00000002},
504 {0x01400000, 0x00000002},
505 {0x006000cd, 0x0000000c},
506 {0x20c07000, 0x00000020},
507 {0x000000cf, 0x00000012},
508 {0x00800000, 0x00000006},
509 {0x0080751d, 0x00000006},
510 {0000000000, 0000000000},
511 {0x0000775c, 0x00000002},
512 {0x00a05000, 0x00000002},
513 {0x00661000, 0x00000002},
514 {0x0460275d, 0x00000020},
515 {0x00004000, 0000000000},
516 {0x01e00830, 0x00000002},
517 {0x21007000, 0000000000},
518 {0x6464614d, 0000000000},
519 {0x69687420, 0000000000},
520 {0x00000073, 0000000000},
521 {0000000000, 0000000000},
522 {0x00005000, 0x00000002},
523 {0x000380d0, 0x00000002},
524 {0x040025e0, 0x00000002},
525 {0x000075e1, 0000000000},
526 {0x00000001, 0000000000},
527 {0x000380e0, 0x00000002},
528 {0x04002394, 0x00000002},
529 {0x00005000, 0000000000},
530 {0000000000, 0000000000},
531 {0000000000, 0000000000},
532 {0x00000008, 0000000000},
533 {0x00000004, 0000000000},
534 {0000000000, 0000000000},
535 {0000000000, 0000000000},
536 {0000000000, 0000000000},
537 {0000000000, 0000000000},
538 {0000000000, 0000000000},
539 {0000000000, 0000000000},
540 {0000000000, 0000000000},
541 {0000000000, 0000000000},
542 {0000000000, 0000000000},
543 {0000000000, 0000000000},
544 {0000000000, 0000000000},
545 {0000000000, 0000000000},
546 {0000000000, 0000000000},
547 {0000000000, 0000000000},
548 {0000000000, 0000000000},
549 {0000000000, 0000000000},
550 {0000000000, 0000000000},
551 {0000000000, 0000000000},
552 {0000000000, 0000000000},
553 {0000000000, 0000000000},
554 {0000000000, 0000000000},
555 {0000000000, 0000000000},
556 {0000000000, 0000000000},
557 {0000000000, 0000000000},
558};
559
560static const u32 R300_cp_microcode[][2] = {
561 {0x4200e000, 0000000000},
562 {0x4000e000, 0000000000},
563 {0x000000af, 0x00000008},
564 {0x000000b3, 0x00000008},
565 {0x6c5a504f, 0000000000},
566 {0x4f4f497a, 0000000000},
567 {0x5a578288, 0000000000},
568 {0x4f91906a, 0000000000},
569 {0x4f4f4f4f, 0000000000},
570 {0x4fe24f44, 0000000000},
571 {0x4f9c9c9c, 0000000000},
572 {0xdc4f4fde, 0000000000},
573 {0xa1cd4f4f, 0000000000},
574 {0xd29d9d9d, 0000000000},
575 {0x4f0f9fd7, 0000000000},
576 {0x000ca000, 0x00000004},
577 {0x000d0012, 0x00000038},
578 {0x0000e8b4, 0x00000004},
579 {0x000d0014, 0x00000038},
580 {0x0000e8b6, 0x00000004},
581 {0x000d0016, 0x00000038},
582 {0x0000e854, 0x00000004},
583 {0x000d0018, 0x00000038},
584 {0x0000e855, 0x00000004},
585 {0x000d001a, 0x00000038},
586 {0x0000e856, 0x00000004},
587 {0x000d001c, 0x00000038},
588 {0x0000e857, 0x00000004},
589 {0x000d001e, 0x00000038},
590 {0x0000e824, 0x00000004},
591 {0x000d0020, 0x00000038},
592 {0x0000e825, 0x00000004},
593 {0x000d0022, 0x00000038},
594 {0x0000e830, 0x00000004},
595 {0x000d0024, 0x00000038},
596 {0x0000f0c0, 0x00000004},
597 {0x000d0026, 0x00000038},
598 {0x0000f0c1, 0x00000004},
599 {0x000d0028, 0x00000038},
600 {0x0000f041, 0x00000004},
601 {0x000d002a, 0x00000038},
602 {0x0000f184, 0x00000004},
603 {0x000d002c, 0x00000038},
604 {0x0000f185, 0x00000004},
605 {0x000d002e, 0x00000038},
606 {0x0000f186, 0x00000004},
607 {0x000d0030, 0x00000038},
608 {0x0000f187, 0x00000004},
609 {0x000d0032, 0x00000038},
610 {0x0000f180, 0x00000004},
611 {0x000d0034, 0x00000038},
612 {0x0000f393, 0x00000004},
613 {0x000d0036, 0x00000038},
614 {0x0000f38a, 0x00000004},
615 {0x000d0038, 0x00000038},
616 {0x0000f38e, 0x00000004},
617 {0x0000e821, 0x00000004},
618 {0x0140a000, 0x00000004},
619 {0x00000043, 0x00000018},
620 {0x00cce800, 0x00000004},
621 {0x001b0001, 0x00000004},
622 {0x08004800, 0x00000004},
623 {0x001b0001, 0x00000004},
624 {0x08004800, 0x00000004},
625 {0x001b0001, 0x00000004},
626 {0x08004800, 0x00000004},
627 {0x0000003a, 0x00000008},
628 {0x0000a000, 0000000000},
629 {0x02c0a000, 0x00000004},
630 {0x000ca000, 0x00000004},
631 {0x00130000, 0x00000004},
632 {0x000c2000, 0x00000004},
633 {0xc980c045, 0x00000008},
634 {0x2000451d, 0x00000004},
635 {0x0000e580, 0x00000004},
636 {0x000ce581, 0x00000004},
637 {0x08004580, 0x00000004},
638 {0x000ce581, 0x00000004},
639 {0x0000004c, 0x00000008},
640 {0x0000a000, 0000000000},
641 {0x000c2000, 0x00000004},
642 {0x0000e50e, 0x00000004},
643 {0x00032000, 0x00000004},
644 {0x00022056, 0x00000028},
645 {0x00000056, 0x00000024},
646 {0x0800450f, 0x00000004},
647 {0x0000a050, 0x00000008},
648 {0x0000e565, 0x00000004},
649 {0x0000e566, 0x00000004},
650 {0x00000057, 0x00000008},
651 {0x03cca5b4, 0x00000004},
652 {0x05432000, 0x00000004},
653 {0x00022000, 0x00000004},
654 {0x4ccce063, 0x00000030},
655 {0x08274565, 0x00000004},
656 {0x00000063, 0x00000030},
657 {0x08004564, 0x00000004},
658 {0x0000e566, 0x00000004},
659 {0x0000005a, 0x00000008},
660 {0x00802066, 0x00000010},
661 {0x00202000, 0x00000004},
662 {0x001b00ff, 0x00000004},
663 {0x01000069, 0x00000010},
664 {0x001f2000, 0x00000004},
665 {0x001c00ff, 0x00000004},
666 {0000000000, 0x0000000c},
667 {0x00000085, 0x00000030},
668 {0x0000005a, 0x00000008},
669 {0x0000e576, 0x00000004},
670 {0x000ca000, 0x00000004},
671 {0x00012000, 0x00000004},
672 {0x00082000, 0x00000004},
673 {0x1800650e, 0x00000004},
674 {0x00092000, 0x00000004},
675 {0x000a2000, 0x00000004},
676 {0x000f0000, 0x00000004},
677 {0x00400000, 0x00000004},
678 {0x00000079, 0x00000018},
679 {0x0000e563, 0x00000004},
680 {0x00c0e5f9, 0x000000c2},
681 {0x0000006e, 0x00000008},
682 {0x0000a06e, 0x00000008},
683 {0x0000e576, 0x00000004},
684 {0x0000e577, 0x00000004},
685 {0x0000e50e, 0x00000004},
686 {0x0000e50f, 0x00000004},
687 {0x0140a000, 0x00000004},
688 {0x0000007c, 0x00000018},
689 {0x00c0e5f9, 0x000000c2},
690 {0x0000007c, 0x00000008},
691 {0x0014e50e, 0x00000004},
692 {0x0040e50f, 0x00000004},
693 {0x00c0007f, 0x00000008},
694 {0x0000e570, 0x00000004},
695 {0x0000e571, 0x00000004},
696 {0x0000e572, 0x0000000c},
697 {0x0000a000, 0x00000004},
698 {0x0140a000, 0x00000004},
699 {0x0000e568, 0x00000004},
700 {0x000c2000, 0x00000004},
701 {0x00000089, 0x00000018},
702 {0x000b0000, 0x00000004},
703 {0x18c0e562, 0x00000004},
704 {0x0000008b, 0x00000008},
705 {0x00c0008a, 0x00000008},
706 {0x000700e4, 0x00000004},
707 {0x00000097, 0x00000038},
708 {0x000ca099, 0x00000030},
709 {0x080045bb, 0x00000004},
710 {0x000c209a, 0x00000030},
711 {0x0800e5bc, 0000000000},
712 {0x0000e5bb, 0x00000004},
713 {0x0000e5bc, 0000000000},
714 {0x00120000, 0x0000000c},
715 {0x00120000, 0x00000004},
716 {0x001b0002, 0x0000000c},
717 {0x0000a000, 0x00000004},
718 {0x0000e821, 0x00000004},
719 {0x0000e800, 0000000000},
720 {0x0000e821, 0x00000004},
721 {0x0000e82e, 0000000000},
722 {0x02cca000, 0x00000004},
723 {0x00140000, 0x00000004},
724 {0x000ce1cc, 0x00000004},
725 {0x050de1cd, 0x00000004},
726 {0x000000a7, 0x00000020},
727 {0x4200e000, 0000000000},
728 {0x000000ae, 0x00000038},
729 {0x000ca000, 0x00000004},
730 {0x00140000, 0x00000004},
731 {0x000c2000, 0x00000004},
732 {0x00160000, 0x00000004},
733 {0x700ce000, 0x00000004},
734 {0x001400aa, 0x00000008},
735 {0x4000e000, 0000000000},
736 {0x02400000, 0x00000004},
737 {0x400ee000, 0x00000004},
738 {0x02400000, 0x00000004},
739 {0x4000e000, 0000000000},
740 {0x000c2000, 0x00000004},
741 {0x0240e51b, 0x00000004},
742 {0x0080e50a, 0x00000005},
743 {0x0080e50b, 0x00000005},
744 {0x00220000, 0x00000004},
745 {0x000700e4, 0x00000004},
746 {0x000000c1, 0x00000038},
747 {0x000c209a, 0x00000030},
748 {0x0880e5bd, 0x00000005},
749 {0x000c2099, 0x00000030},
750 {0x0800e5bb, 0x00000005},
751 {0x000c209a, 0x00000030},
752 {0x0880e5bc, 0x00000005},
753 {0x000000c4, 0x00000008},
754 {0x0080e5bd, 0x00000005},
755 {0x0000e5bb, 0x00000005},
756 {0x0080e5bc, 0x00000005},
757 {0x00210000, 0x00000004},
758 {0x02800000, 0x00000004},
759 {0x00c000c8, 0x00000018},
760 {0x4180e000, 0x00000040},
761 {0x000000ca, 0x00000024},
762 {0x01000000, 0x0000000c},
763 {0x0100e51d, 0x0000000c},
764 {0x000045bb, 0x00000004},
765 {0x000080c4, 0x00000008},
766 {0x0000f3ce, 0x00000004},
767 {0x0140a000, 0x00000004},
768 {0x00cc2000, 0x00000004},
769 {0x08c053cf, 0x00000040},
770 {0x00008000, 0000000000},
771 {0x0000f3d2, 0x00000004},
772 {0x0140a000, 0x00000004},
773 {0x00cc2000, 0x00000004},
774 {0x08c053d3, 0x00000040},
775 {0x00008000, 0000000000},
776 {0x0000f39d, 0x00000004},
777 {0x0140a000, 0x00000004},
778 {0x00cc2000, 0x00000004},
779 {0x08c0539e, 0x00000040},
780 {0x00008000, 0000000000},
781 {0x03c00830, 0x00000004},
782 {0x4200e000, 0000000000},
783 {0x0000a000, 0x00000004},
784 {0x200045e0, 0x00000004},
785 {0x0000e5e1, 0000000000},
786 {0x00000001, 0000000000},
787 {0x000700e1, 0x00000004},
788 {0x0800e394, 0000000000},
789 {0000000000, 0000000000},
790 {0000000000, 0000000000},
791 {0000000000, 0000000000},
792 {0000000000, 0000000000},
793 {0000000000, 0000000000},
794 {0000000000, 0000000000},
795 {0000000000, 0000000000},
796 {0000000000, 0000000000},
797 {0000000000, 0000000000},
798 {0000000000, 0000000000},
799 {0000000000, 0000000000},
800 {0000000000, 0000000000},
801 {0000000000, 0000000000},
802 {0000000000, 0000000000},
803 {0000000000, 0000000000},
804 {0000000000, 0000000000},
805 {0000000000, 0000000000},
806 {0000000000, 0000000000},
807 {0000000000, 0000000000},
808 {0000000000, 0000000000},
809 {0000000000, 0000000000},
810 {0000000000, 0000000000},
811 {0000000000, 0000000000},
812 {0000000000, 0000000000},
813 {0000000000, 0000000000},
814 {0000000000, 0000000000},
815 {0000000000, 0000000000},
816 {0000000000, 0000000000},
817};
818
819static u32 RADEON_READ_MCIND(drm_radeon_private_t *dev_priv, int addr)
820{
821 u32 ret;
822 RADEON_WRITE(R520_MC_IND_INDEX, 0x7f0000 | (addr & 0xff));
823 ret = RADEON_READ(R520_MC_IND_DATA);
824 RADEON_WRITE(R520_MC_IND_INDEX, 0);
825 return ret;
826}
827
828static u32 RS690_READ_MCIND(drm_radeon_private_t *dev_priv, int addr)
829{
830 RADEON_WRITE(RS690_MC_INDEX, (addr & RS690_MC_INDEX_MASK));
831 return RADEON_READ(RS690_MC_DATA);
832}
833
834u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv)
835{
836
837 if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515)
838 return RADEON_READ_MCIND(dev_priv, RV515_MC_FB_LOCATION);
839 else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690)
840 return RS690_READ_MCIND(dev_priv, RS690_MC_FB_LOCATION);
841 else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515)
842 return RADEON_READ_MCIND(dev_priv, R520_MC_FB_LOCATION);
843 else
844 return RADEON_READ(RADEON_MC_FB_LOCATION);
845}
846
847static void radeon_write_fb_location(drm_radeon_private_t *dev_priv, u32 fb_loc)
848{
849 if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515)
850 RADEON_WRITE_MCIND(RV515_MC_FB_LOCATION, fb_loc);
851 else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690)
852 RS690_WRITE_MCIND(RS690_MC_FB_LOCATION, fb_loc);
853 else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515)
854 RADEON_WRITE_MCIND(R520_MC_FB_LOCATION, fb_loc);
855 else
856 RADEON_WRITE(RADEON_MC_FB_LOCATION, fb_loc);
857}
858
859static void radeon_write_agp_location(drm_radeon_private_t *dev_priv, u32 agp_loc)
860{
861 if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515)
862 RADEON_WRITE_MCIND(RV515_MC_AGP_LOCATION, agp_loc);
863 else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690)
864 RS690_WRITE_MCIND(RS690_MC_AGP_LOCATION, agp_loc);
865 else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515)
866 RADEON_WRITE_MCIND(R520_MC_AGP_LOCATION, agp_loc);
867 else
868 RADEON_WRITE(RADEON_MC_AGP_LOCATION, agp_loc);
869}
870
871static int RADEON_READ_PLL(struct drm_device * dev, int addr)
872{
873 drm_radeon_private_t *dev_priv = dev->dev_private;
874
875 RADEON_WRITE8(RADEON_CLOCK_CNTL_INDEX, addr & 0x1f);
876 return RADEON_READ(RADEON_CLOCK_CNTL_DATA);
877}
878
879static u32 RADEON_READ_PCIE(drm_radeon_private_t *dev_priv, int addr)
880{
881 RADEON_WRITE8(RADEON_PCIE_INDEX, addr & 0xff);
882 return RADEON_READ(RADEON_PCIE_DATA);
883}
884
885static u32 RADEON_READ_IGPGART(drm_radeon_private_t *dev_priv, int addr)
886{
887 u32 ret;
888 RADEON_WRITE(RADEON_IGPGART_INDEX, addr & 0x7f);
889 ret = RADEON_READ(RADEON_IGPGART_DATA);
890 RADEON_WRITE(RADEON_IGPGART_INDEX, 0x7f);
891 return ret;
892}
893
894#if RADEON_FIFO_DEBUG
895static void radeon_status(drm_radeon_private_t * dev_priv)
896{
897 printk("%s:\n", __func__);
898 printk("RBBM_STATUS = 0x%08x\n",
899 (unsigned int)RADEON_READ(RADEON_RBBM_STATUS));
900 printk("CP_RB_RTPR = 0x%08x\n",
901 (unsigned int)RADEON_READ(RADEON_CP_RB_RPTR));
902 printk("CP_RB_WTPR = 0x%08x\n",
903 (unsigned int)RADEON_READ(RADEON_CP_RB_WPTR));
904 printk("AIC_CNTL = 0x%08x\n",
905 (unsigned int)RADEON_READ(RADEON_AIC_CNTL));
906 printk("AIC_STAT = 0x%08x\n",
907 (unsigned int)RADEON_READ(RADEON_AIC_STAT));
908 printk("AIC_PT_BASE = 0x%08x\n",
909 (unsigned int)RADEON_READ(RADEON_AIC_PT_BASE));
910 printk("TLB_ADDR = 0x%08x\n",
911 (unsigned int)RADEON_READ(RADEON_AIC_TLB_ADDR));
912 printk("TLB_DATA = 0x%08x\n",
913 (unsigned int)RADEON_READ(RADEON_AIC_TLB_DATA));
914}
915#endif
916
917/* ================================================================
918 * Engine, FIFO control
919 */
920
921static int radeon_do_pixcache_flush(drm_radeon_private_t * dev_priv)
922{
923 u32 tmp;
924 int i;
925
926 dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
927
928 tmp = RADEON_READ(RADEON_RB3D_DSTCACHE_CTLSTAT);
929 tmp |= RADEON_RB3D_DC_FLUSH_ALL;
930 RADEON_WRITE(RADEON_RB3D_DSTCACHE_CTLSTAT, tmp);
931
932 for (i = 0; i < dev_priv->usec_timeout; i++) {
933 if (!(RADEON_READ(RADEON_RB3D_DSTCACHE_CTLSTAT)
934 & RADEON_RB3D_DC_BUSY)) {
935 return 0;
936 }
937 DRM_UDELAY(1);
938 }
939
940#if RADEON_FIFO_DEBUG
941 DRM_ERROR("failed!\n");
942 radeon_status(dev_priv);
943#endif
944 return -EBUSY;
945}
946
947static int radeon_do_wait_for_fifo(drm_radeon_private_t * dev_priv, int entries)
948{
949 int i;
950
951 dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
952
953 for (i = 0; i < dev_priv->usec_timeout; i++) {
954 int slots = (RADEON_READ(RADEON_RBBM_STATUS)
955 & RADEON_RBBM_FIFOCNT_MASK);
956 if (slots >= entries)
957 return 0;
958 DRM_UDELAY(1);
959 }
960
961#if RADEON_FIFO_DEBUG
962 DRM_ERROR("failed!\n");
963 radeon_status(dev_priv);
964#endif
965 return -EBUSY;
966}
967
968static int radeon_do_wait_for_idle(drm_radeon_private_t * dev_priv)
969{
970 int i, ret;
971
972 dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
973
974 ret = radeon_do_wait_for_fifo(dev_priv, 64);
975 if (ret)
976 return ret;
977
978 for (i = 0; i < dev_priv->usec_timeout; i++) {
979 if (!(RADEON_READ(RADEON_RBBM_STATUS)
980 & RADEON_RBBM_ACTIVE)) {
981 radeon_do_pixcache_flush(dev_priv);
982 return 0;
983 }
984 DRM_UDELAY(1);
985 }
986
987#if RADEON_FIFO_DEBUG
988 DRM_ERROR("failed!\n");
989 radeon_status(dev_priv);
990#endif
991 return -EBUSY;
992}
993
994/* ================================================================
995 * CP control, initialization
996 */
997
998/* Load the microcode for the CP */
999static void radeon_cp_load_microcode(drm_radeon_private_t * dev_priv)
1000{
1001 int i;
1002 DRM_DEBUG("\n");
1003
1004 radeon_do_wait_for_idle(dev_priv);
1005
1006 RADEON_WRITE(RADEON_CP_ME_RAM_ADDR, 0);
1007
1008 if (dev_priv->microcode_version == UCODE_R200) {
1009 DRM_INFO("Loading R200 Microcode\n");
1010 for (i = 0; i < 256; i++) {
1011 RADEON_WRITE(RADEON_CP_ME_RAM_DATAH,
1012 R200_cp_microcode[i][1]);
1013 RADEON_WRITE(RADEON_CP_ME_RAM_DATAL,
1014 R200_cp_microcode[i][0]);
1015 }
1016 } else if (dev_priv->microcode_version == UCODE_R300) {
1017 DRM_INFO("Loading R300 Microcode\n");
1018 for (i = 0; i < 256; i++) {
1019 RADEON_WRITE(RADEON_CP_ME_RAM_DATAH,
1020 R300_cp_microcode[i][1]);
1021 RADEON_WRITE(RADEON_CP_ME_RAM_DATAL,
1022 R300_cp_microcode[i][0]);
1023 }
1024 } else {
1025 for (i = 0; i < 256; i++) {
1026 RADEON_WRITE(RADEON_CP_ME_RAM_DATAH,
1027 radeon_cp_microcode[i][1]);
1028 RADEON_WRITE(RADEON_CP_ME_RAM_DATAL,
1029 radeon_cp_microcode[i][0]);
1030 }
1031 }
1032}
1033
1034/* Flush any pending commands to the CP. This should only be used just
1035 * prior to a wait for idle, as it informs the engine that the command
1036 * stream is ending.
1037 */
1038static void radeon_do_cp_flush(drm_radeon_private_t * dev_priv)
1039{
1040 DRM_DEBUG("\n");
1041#if 0
1042 u32 tmp;
1043
1044 tmp = RADEON_READ(RADEON_CP_RB_WPTR) | (1 << 31);
1045 RADEON_WRITE(RADEON_CP_RB_WPTR, tmp);
1046#endif
1047}
1048
1049/* Wait for the CP to go idle.
1050 */
1051int radeon_do_cp_idle(drm_radeon_private_t * dev_priv)
1052{
1053 RING_LOCALS;
1054 DRM_DEBUG("\n");
1055
1056 BEGIN_RING(6);
1057
1058 RADEON_PURGE_CACHE();
1059 RADEON_PURGE_ZCACHE();
1060 RADEON_WAIT_UNTIL_IDLE();
1061
1062 ADVANCE_RING();
1063 COMMIT_RING();
1064
1065 return radeon_do_wait_for_idle(dev_priv);
1066}
1067
1068/* Start the Command Processor.
1069 */
1070static void radeon_do_cp_start(drm_radeon_private_t * dev_priv)
1071{
1072 RING_LOCALS;
1073 DRM_DEBUG("\n");
1074
1075 radeon_do_wait_for_idle(dev_priv);
1076
1077 RADEON_WRITE(RADEON_CP_CSQ_CNTL, dev_priv->cp_mode);
1078
1079 dev_priv->cp_running = 1;
1080
1081 BEGIN_RING(6);
1082
1083 RADEON_PURGE_CACHE();
1084 RADEON_PURGE_ZCACHE();
1085 RADEON_WAIT_UNTIL_IDLE();
1086
1087 ADVANCE_RING();
1088 COMMIT_RING();
1089}
1090
1091/* Reset the Command Processor. This will not flush any pending
1092 * commands, so you must wait for the CP command stream to complete
1093 * before calling this routine.
1094 */
1095static void radeon_do_cp_reset(drm_radeon_private_t * dev_priv)
1096{
1097 u32 cur_read_ptr;
1098 DRM_DEBUG("\n");
1099
1100 cur_read_ptr = RADEON_READ(RADEON_CP_RB_RPTR);
1101 RADEON_WRITE(RADEON_CP_RB_WPTR, cur_read_ptr);
1102 SET_RING_HEAD(dev_priv, cur_read_ptr);
1103 dev_priv->ring.tail = cur_read_ptr;
1104}
1105
1106/* Stop the Command Processor. This will not flush any pending
1107 * commands, so you must flush the command stream and wait for the CP
1108 * to go idle before calling this routine.
1109 */
1110static void radeon_do_cp_stop(drm_radeon_private_t * dev_priv)
1111{
1112 DRM_DEBUG("\n");
1113
1114 RADEON_WRITE(RADEON_CP_CSQ_CNTL, RADEON_CSQ_PRIDIS_INDDIS);
1115
1116 dev_priv->cp_running = 0;
1117}
1118
1119/* Reset the engine. This will stop the CP if it is running.
1120 */
1121static int radeon_do_engine_reset(struct drm_device * dev)
1122{
1123 drm_radeon_private_t *dev_priv = dev->dev_private;
1124 u32 clock_cntl_index, mclk_cntl, rbbm_soft_reset;
1125 DRM_DEBUG("\n");
1126
1127 radeon_do_pixcache_flush(dev_priv);
1128
1129 if ((dev_priv->flags & RADEON_FAMILY_MASK) < CHIP_RV515) {
1130 clock_cntl_index = RADEON_READ(RADEON_CLOCK_CNTL_INDEX);
1131 mclk_cntl = RADEON_READ_PLL(dev, RADEON_MCLK_CNTL);
1132
1133 RADEON_WRITE_PLL(RADEON_MCLK_CNTL, (mclk_cntl |
1134 RADEON_FORCEON_MCLKA |
1135 RADEON_FORCEON_MCLKB |
1136 RADEON_FORCEON_YCLKA |
1137 RADEON_FORCEON_YCLKB |
1138 RADEON_FORCEON_MC |
1139 RADEON_FORCEON_AIC));
1140
1141 rbbm_soft_reset = RADEON_READ(RADEON_RBBM_SOFT_RESET);
1142
1143 RADEON_WRITE(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset |
1144 RADEON_SOFT_RESET_CP |
1145 RADEON_SOFT_RESET_HI |
1146 RADEON_SOFT_RESET_SE |
1147 RADEON_SOFT_RESET_RE |
1148 RADEON_SOFT_RESET_PP |
1149 RADEON_SOFT_RESET_E2 |
1150 RADEON_SOFT_RESET_RB));
1151 RADEON_READ(RADEON_RBBM_SOFT_RESET);
1152 RADEON_WRITE(RADEON_RBBM_SOFT_RESET, (rbbm_soft_reset &
1153 ~(RADEON_SOFT_RESET_CP |
1154 RADEON_SOFT_RESET_HI |
1155 RADEON_SOFT_RESET_SE |
1156 RADEON_SOFT_RESET_RE |
1157 RADEON_SOFT_RESET_PP |
1158 RADEON_SOFT_RESET_E2 |
1159 RADEON_SOFT_RESET_RB)));
1160 RADEON_READ(RADEON_RBBM_SOFT_RESET);
1161
1162 RADEON_WRITE_PLL(RADEON_MCLK_CNTL, mclk_cntl);
1163 RADEON_WRITE(RADEON_CLOCK_CNTL_INDEX, clock_cntl_index);
1164 RADEON_WRITE(RADEON_RBBM_SOFT_RESET, rbbm_soft_reset);
1165 }
1166
1167 /* Reset the CP ring */
1168 radeon_do_cp_reset(dev_priv);
1169
1170 /* The CP is no longer running after an engine reset */
1171 dev_priv->cp_running = 0;
1172
1173 /* Reset any pending vertex, indirect buffers */
1174 radeon_freelist_reset(dev);
1175
1176 return 0;
1177}
1178
1179static void radeon_cp_init_ring_buffer(struct drm_device * dev,
1180 drm_radeon_private_t * dev_priv)
1181{
1182 u32 ring_start, cur_read_ptr;
1183 u32 tmp;
1184
1185 /* Initialize the memory controller. With new memory map, the fb location
1186 * is not changed, it should have been properly initialized already. Part
1187 * of the problem is that the code below is bogus, assuming the GART is
1188 * always appended to the fb which is not necessarily the case
1189 */
1190 if (!dev_priv->new_memmap)
1191 radeon_write_fb_location(dev_priv,
1192 ((dev_priv->gart_vm_start - 1) & 0xffff0000)
1193 | (dev_priv->fb_location >> 16));
1194
1195#if __OS_HAS_AGP
1196 if (dev_priv->flags & RADEON_IS_AGP) {
1197 RADEON_WRITE(RADEON_AGP_BASE, (unsigned int)dev->agp->base);
1198 radeon_write_agp_location(dev_priv,
1199 (((dev_priv->gart_vm_start - 1 +
1200 dev_priv->gart_size) & 0xffff0000) |
1201 (dev_priv->gart_vm_start >> 16)));
1202
1203 ring_start = (dev_priv->cp_ring->offset
1204 - dev->agp->base
1205 + dev_priv->gart_vm_start);
1206 } else
1207#endif
1208 ring_start = (dev_priv->cp_ring->offset
1209 - (unsigned long)dev->sg->virtual
1210 + dev_priv->gart_vm_start);
1211
1212 RADEON_WRITE(RADEON_CP_RB_BASE, ring_start);
1213
1214 /* Set the write pointer delay */
1215 RADEON_WRITE(RADEON_CP_RB_WPTR_DELAY, 0);
1216
1217 /* Initialize the ring buffer's read and write pointers */
1218 cur_read_ptr = RADEON_READ(RADEON_CP_RB_RPTR);
1219 RADEON_WRITE(RADEON_CP_RB_WPTR, cur_read_ptr);
1220 SET_RING_HEAD(dev_priv, cur_read_ptr);
1221 dev_priv->ring.tail = cur_read_ptr;
1222
1223#if __OS_HAS_AGP
1224 if (dev_priv->flags & RADEON_IS_AGP) {
1225 RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR,
1226 dev_priv->ring_rptr->offset
1227 - dev->agp->base + dev_priv->gart_vm_start);
1228 } else
1229#endif
1230 {
1231 struct drm_sg_mem *entry = dev->sg;
1232 unsigned long tmp_ofs, page_ofs;
1233
1234 tmp_ofs = dev_priv->ring_rptr->offset -
1235 (unsigned long)dev->sg->virtual;
1236 page_ofs = tmp_ofs >> PAGE_SHIFT;
1237
1238 RADEON_WRITE(RADEON_CP_RB_RPTR_ADDR, entry->busaddr[page_ofs]);
1239 DRM_DEBUG("ring rptr: offset=0x%08lx handle=0x%08lx\n",
1240 (unsigned long)entry->busaddr[page_ofs],
1241 entry->handle + tmp_ofs);
1242 }
1243
1244 /* Set ring buffer size */
1245#ifdef __BIG_ENDIAN
1246 RADEON_WRITE(RADEON_CP_RB_CNTL,
1247 RADEON_BUF_SWAP_32BIT |
1248 (dev_priv->ring.fetch_size_l2ow << 18) |
1249 (dev_priv->ring.rptr_update_l2qw << 8) |
1250 dev_priv->ring.size_l2qw);
1251#else
1252 RADEON_WRITE(RADEON_CP_RB_CNTL,
1253 (dev_priv->ring.fetch_size_l2ow << 18) |
1254 (dev_priv->ring.rptr_update_l2qw << 8) |
1255 dev_priv->ring.size_l2qw);
1256#endif
1257
1258 /* Start with assuming that writeback doesn't work */
1259 dev_priv->writeback_works = 0;
1260
1261 /* Initialize the scratch register pointer. This will cause
1262 * the scratch register values to be written out to memory
1263 * whenever they are updated.
1264 *
1265 * We simply put this behind the ring read pointer, this works
1266 * with PCI GART as well as (whatever kind of) AGP GART
1267 */
1268 RADEON_WRITE(RADEON_SCRATCH_ADDR, RADEON_READ(RADEON_CP_RB_RPTR_ADDR)
1269 + RADEON_SCRATCH_REG_OFFSET);
1270
1271 dev_priv->scratch = ((__volatile__ u32 *)
1272 dev_priv->ring_rptr->handle +
1273 (RADEON_SCRATCH_REG_OFFSET / sizeof(u32)));
1274
1275 RADEON_WRITE(RADEON_SCRATCH_UMSK, 0x7);
1276
1277 /* Turn on bus mastering */
1278 tmp = RADEON_READ(RADEON_BUS_CNTL) & ~RADEON_BUS_MASTER_DIS;
1279 RADEON_WRITE(RADEON_BUS_CNTL, tmp);
1280
1281 dev_priv->sarea_priv->last_frame = dev_priv->scratch[0] = 0;
1282 RADEON_WRITE(RADEON_LAST_FRAME_REG, dev_priv->sarea_priv->last_frame);
1283
1284 dev_priv->sarea_priv->last_dispatch = dev_priv->scratch[1] = 0;
1285 RADEON_WRITE(RADEON_LAST_DISPATCH_REG,
1286 dev_priv->sarea_priv->last_dispatch);
1287
1288 dev_priv->sarea_priv->last_clear = dev_priv->scratch[2] = 0;
1289 RADEON_WRITE(RADEON_LAST_CLEAR_REG, dev_priv->sarea_priv->last_clear);
1290
1291 radeon_do_wait_for_idle(dev_priv);
1292
1293 /* Sync everything up */
1294 RADEON_WRITE(RADEON_ISYNC_CNTL,
1295 (RADEON_ISYNC_ANY2D_IDLE3D |
1296 RADEON_ISYNC_ANY3D_IDLE2D |
1297 RADEON_ISYNC_WAIT_IDLEGUI |
1298 RADEON_ISYNC_CPSCRATCH_IDLEGUI));
1299
1300}
1301
1302static void radeon_test_writeback(drm_radeon_private_t * dev_priv)
1303{
1304 u32 tmp;
1305
1306 /* Writeback doesn't seem to work everywhere, test it here and possibly
1307 * enable it if it appears to work
1308 */
1309 DRM_WRITE32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1), 0);
1310 RADEON_WRITE(RADEON_SCRATCH_REG1, 0xdeadbeef);
1311
1312 for (tmp = 0; tmp < dev_priv->usec_timeout; tmp++) {
1313 if (DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1)) ==
1314 0xdeadbeef)
1315 break;
1316 DRM_UDELAY(1);
1317 }
1318
1319 if (tmp < dev_priv->usec_timeout) {
1320 dev_priv->writeback_works = 1;
1321 DRM_INFO("writeback test succeeded in %d usecs\n", tmp);
1322 } else {
1323 dev_priv->writeback_works = 0;
1324 DRM_INFO("writeback test failed\n");
1325 }
1326 if (radeon_no_wb == 1) {
1327 dev_priv->writeback_works = 0;
1328 DRM_INFO("writeback forced off\n");
1329 }
1330
1331 if (!dev_priv->writeback_works) {
1332 /* Disable writeback to avoid unnecessary bus master transfer */
1333 RADEON_WRITE(RADEON_CP_RB_CNTL, RADEON_READ(RADEON_CP_RB_CNTL) |
1334 RADEON_RB_NO_UPDATE);
1335 RADEON_WRITE(RADEON_SCRATCH_UMSK, 0);
1336 }
1337}
1338
1339/* Enable or disable IGP GART on the chip */
1340static void radeon_set_igpgart(drm_radeon_private_t * dev_priv, int on)
1341{
1342 u32 temp, tmp;
1343
1344 tmp = RADEON_READ(RADEON_AIC_CNTL);
1345 if (on) {
1346 DRM_DEBUG("programming igpgart %08X %08lX %08X\n",
1347 dev_priv->gart_vm_start,
1348 (long)dev_priv->gart_info.bus_addr,
1349 dev_priv->gart_size);
1350
1351 RADEON_WRITE_IGPGART(RADEON_IGPGART_UNK_18, 0x1000);
1352 RADEON_WRITE_IGPGART(RADEON_IGPGART_ENABLE, 0x1);
1353 RADEON_WRITE_IGPGART(RADEON_IGPGART_CTRL, 0x42040800);
1354 RADEON_WRITE_IGPGART(RADEON_IGPGART_BASE_ADDR,
1355 dev_priv->gart_info.bus_addr);
1356
1357 temp = RADEON_READ_IGPGART(dev_priv, RADEON_IGPGART_UNK_39);
1358 RADEON_WRITE_IGPGART(RADEON_IGPGART_UNK_39, temp);
1359
1360 RADEON_WRITE(RADEON_AGP_BASE, (unsigned int)dev_priv->gart_vm_start);
1361 dev_priv->gart_size = 32*1024*1024;
1362 radeon_write_agp_location(dev_priv,
1363 (((dev_priv->gart_vm_start - 1 +
1364 dev_priv->gart_size) & 0xffff0000) |
1365 (dev_priv->gart_vm_start >> 16)));
1366
1367 temp = RADEON_READ_IGPGART(dev_priv, RADEON_IGPGART_ENABLE);
1368 RADEON_WRITE_IGPGART(RADEON_IGPGART_ENABLE, temp);
1369
1370 RADEON_READ_IGPGART(dev_priv, RADEON_IGPGART_FLUSH);
1371 RADEON_WRITE_IGPGART(RADEON_IGPGART_FLUSH, 0x1);
1372 RADEON_READ_IGPGART(dev_priv, RADEON_IGPGART_FLUSH);
1373 RADEON_WRITE_IGPGART(RADEON_IGPGART_FLUSH, 0x0);
1374 }
1375}
1376
1377/* Enable or disable RS690 GART on the chip */
1378static void radeon_set_rs690gart(drm_radeon_private_t *dev_priv, int on)
1379{
1380 u32 temp;
1381
1382 if (on) {
1383 DRM_DEBUG("programming rs690 gart %08X %08lX %08X\n",
1384 dev_priv->gart_vm_start,
1385 (long)dev_priv->gart_info.bus_addr,
1386 dev_priv->gart_size);
1387
1388 temp = RS690_READ_MCIND(dev_priv, RS690_MC_MISC_CNTL);
1389 RS690_WRITE_MCIND(RS690_MC_MISC_CNTL, 0x5000);
1390
1391 RS690_WRITE_MCIND(RS690_MC_AGP_SIZE,
1392 RS690_MC_GART_EN | RS690_MC_AGP_SIZE_32MB);
1393
1394 temp = RS690_READ_MCIND(dev_priv, RS690_MC_GART_FEATURE_ID);
1395 RS690_WRITE_MCIND(RS690_MC_GART_FEATURE_ID, 0x42040800);
1396
1397 RS690_WRITE_MCIND(RS690_MC_GART_BASE,
1398 dev_priv->gart_info.bus_addr);
1399
1400 temp = RS690_READ_MCIND(dev_priv, RS690_MC_AGP_MODE_CONTROL);
1401 RS690_WRITE_MCIND(RS690_MC_AGP_MODE_CONTROL, 0x01400000);
1402
1403 RS690_WRITE_MCIND(RS690_MC_AGP_BASE,
1404 (unsigned int)dev_priv->gart_vm_start);
1405
1406 dev_priv->gart_size = 32*1024*1024;
1407 temp = (((dev_priv->gart_vm_start - 1 + dev_priv->gart_size) &
1408 0xffff0000) | (dev_priv->gart_vm_start >> 16));
1409
1410 RS690_WRITE_MCIND(RS690_MC_AGP_LOCATION, temp);
1411
1412 temp = RS690_READ_MCIND(dev_priv, RS690_MC_AGP_SIZE);
1413 RS690_WRITE_MCIND(RS690_MC_AGP_SIZE,
1414 RS690_MC_GART_EN | RS690_MC_AGP_SIZE_32MB);
1415
1416 do {
1417 temp = RS690_READ_MCIND(dev_priv, RS690_MC_GART_CACHE_CNTL);
1418 if ((temp & RS690_MC_GART_CLEAR_STATUS) ==
1419 RS690_MC_GART_CLEAR_DONE)
1420 break;
1421 DRM_UDELAY(1);
1422 } while (1);
1423
1424 RS690_WRITE_MCIND(RS690_MC_GART_CACHE_CNTL,
1425 RS690_MC_GART_CC_CLEAR);
1426 do {
1427 temp = RS690_READ_MCIND(dev_priv, RS690_MC_GART_CACHE_CNTL);
1428 if ((temp & RS690_MC_GART_CLEAR_STATUS) ==
1429 RS690_MC_GART_CLEAR_DONE)
1430 break;
1431 DRM_UDELAY(1);
1432 } while (1);
1433
1434 RS690_WRITE_MCIND(RS690_MC_GART_CACHE_CNTL,
1435 RS690_MC_GART_CC_NO_CHANGE);
1436 } else {
1437 RS690_WRITE_MCIND(RS690_MC_AGP_SIZE, RS690_MC_GART_DIS);
1438 }
1439}
1440
1441static void radeon_set_pciegart(drm_radeon_private_t * dev_priv, int on)
1442{
1443 u32 tmp = RADEON_READ_PCIE(dev_priv, RADEON_PCIE_TX_GART_CNTL);
1444 if (on) {
1445
1446 DRM_DEBUG("programming pcie %08X %08lX %08X\n",
1447 dev_priv->gart_vm_start,
1448 (long)dev_priv->gart_info.bus_addr,
1449 dev_priv->gart_size);
1450 RADEON_WRITE_PCIE(RADEON_PCIE_TX_DISCARD_RD_ADDR_LO,
1451 dev_priv->gart_vm_start);
1452 RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_BASE,
1453 dev_priv->gart_info.bus_addr);
1454 RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_START_LO,
1455 dev_priv->gart_vm_start);
1456 RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_END_LO,
1457 dev_priv->gart_vm_start +
1458 dev_priv->gart_size - 1);
1459
1460 radeon_write_agp_location(dev_priv, 0xffffffc0); /* ?? */
1461
1462 RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_CNTL,
1463 RADEON_PCIE_TX_GART_EN);
1464 } else {
1465 RADEON_WRITE_PCIE(RADEON_PCIE_TX_GART_CNTL,
1466 tmp & ~RADEON_PCIE_TX_GART_EN);
1467 }
1468}
1469
1470/* Enable or disable PCI GART on the chip */
1471static void radeon_set_pcigart(drm_radeon_private_t * dev_priv, int on)
1472{
1473 u32 tmp;
1474
1475 if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) {
1476 radeon_set_rs690gart(dev_priv, on);
1477 return;
1478 }
1479
1480 if (dev_priv->flags & RADEON_IS_IGPGART) {
1481 radeon_set_igpgart(dev_priv, on);
1482 return;
1483 }
1484
1485 if (dev_priv->flags & RADEON_IS_PCIE) {
1486 radeon_set_pciegart(dev_priv, on);
1487 return;
1488 }
1489
1490 tmp = RADEON_READ(RADEON_AIC_CNTL);
1491
1492 if (on) {
1493 RADEON_WRITE(RADEON_AIC_CNTL,
1494 tmp | RADEON_PCIGART_TRANSLATE_EN);
1495
1496 /* set PCI GART page-table base address
1497 */
1498 RADEON_WRITE(RADEON_AIC_PT_BASE, dev_priv->gart_info.bus_addr);
1499
1500 /* set address range for PCI address translate
1501 */
1502 RADEON_WRITE(RADEON_AIC_LO_ADDR, dev_priv->gart_vm_start);
1503 RADEON_WRITE(RADEON_AIC_HI_ADDR, dev_priv->gart_vm_start
1504 + dev_priv->gart_size - 1);
1505
1506 /* Turn off AGP aperture -- is this required for PCI GART?
1507 */
1508 radeon_write_agp_location(dev_priv, 0xffffffc0);
1509 RADEON_WRITE(RADEON_AGP_COMMAND, 0); /* clear AGP_COMMAND */
1510 } else {
1511 RADEON_WRITE(RADEON_AIC_CNTL,
1512 tmp & ~RADEON_PCIGART_TRANSLATE_EN);
1513 }
1514}
1515
1516static int radeon_do_init_cp(struct drm_device * dev, drm_radeon_init_t * init)
1517{
1518 drm_radeon_private_t *dev_priv = dev->dev_private;
1519
1520 DRM_DEBUG("\n");
1521
1522 /* if we require new memory map but we don't have it fail */
1523 if ((dev_priv->flags & RADEON_NEW_MEMMAP) && !dev_priv->new_memmap) {
1524 DRM_ERROR("Cannot initialise DRM on this card\nThis card requires a new X.org DDX for 3D\n");
1525 radeon_do_cleanup_cp(dev);
1526 return -EINVAL;
1527 }
1528
1529 if (init->is_pci && (dev_priv->flags & RADEON_IS_AGP)) {
1530 DRM_DEBUG("Forcing AGP card to PCI mode\n");
1531 dev_priv->flags &= ~RADEON_IS_AGP;
1532 } else if (!(dev_priv->flags & (RADEON_IS_AGP | RADEON_IS_PCI | RADEON_IS_PCIE))
1533 && !init->is_pci) {
1534 DRM_DEBUG("Restoring AGP flag\n");
1535 dev_priv->flags |= RADEON_IS_AGP;
1536 }
1537
1538 if ((!(dev_priv->flags & RADEON_IS_AGP)) && !dev->sg) {
1539 DRM_ERROR("PCI GART memory not allocated!\n");
1540 radeon_do_cleanup_cp(dev);
1541 return -EINVAL;
1542 }
1543
1544 dev_priv->usec_timeout = init->usec_timeout;
1545 if (dev_priv->usec_timeout < 1 ||
1546 dev_priv->usec_timeout > RADEON_MAX_USEC_TIMEOUT) {
1547 DRM_DEBUG("TIMEOUT problem!\n");
1548 radeon_do_cleanup_cp(dev);
1549 return -EINVAL;
1550 }
1551
1552 /* Enable vblank on CRTC1 for older X servers
1553 */
1554 dev_priv->vblank_crtc = DRM_RADEON_VBLANK_CRTC1;
1555
1556 switch(init->func) {
1557 case RADEON_INIT_R200_CP:
1558 dev_priv->microcode_version = UCODE_R200;
1559 break;
1560 case RADEON_INIT_R300_CP:
1561 dev_priv->microcode_version = UCODE_R300;
1562 break;
1563 default:
1564 dev_priv->microcode_version = UCODE_R100;
1565 }
1566
1567 dev_priv->do_boxes = 0;
1568 dev_priv->cp_mode = init->cp_mode;
1569
1570 /* We don't support anything other than bus-mastering ring mode,
1571 * but the ring can be in either AGP or PCI space for the ring
1572 * read pointer.
1573 */
1574 if ((init->cp_mode != RADEON_CSQ_PRIBM_INDDIS) &&
1575 (init->cp_mode != RADEON_CSQ_PRIBM_INDBM)) {
1576 DRM_DEBUG("BAD cp_mode (%x)!\n", init->cp_mode);
1577 radeon_do_cleanup_cp(dev);
1578 return -EINVAL;
1579 }
1580
1581 switch (init->fb_bpp) {
1582 case 16:
1583 dev_priv->color_fmt = RADEON_COLOR_FORMAT_RGB565;
1584 break;
1585 case 32:
1586 default:
1587 dev_priv->color_fmt = RADEON_COLOR_FORMAT_ARGB8888;
1588 break;
1589 }
1590 dev_priv->front_offset = init->front_offset;
1591 dev_priv->front_pitch = init->front_pitch;
1592 dev_priv->back_offset = init->back_offset;
1593 dev_priv->back_pitch = init->back_pitch;
1594
1595 switch (init->depth_bpp) {
1596 case 16:
1597 dev_priv->depth_fmt = RADEON_DEPTH_FORMAT_16BIT_INT_Z;
1598 break;
1599 case 32:
1600 default:
1601 dev_priv->depth_fmt = RADEON_DEPTH_FORMAT_24BIT_INT_Z;
1602 break;
1603 }
1604 dev_priv->depth_offset = init->depth_offset;
1605 dev_priv->depth_pitch = init->depth_pitch;
1606
1607 /* Hardware state for depth clears. Remove this if/when we no
1608 * longer clear the depth buffer with a 3D rectangle. Hard-code
1609 * all values to prevent unwanted 3D state from slipping through
1610 * and screwing with the clear operation.
1611 */
1612 dev_priv->depth_clear.rb3d_cntl = (RADEON_PLANE_MASK_ENABLE |
1613 (dev_priv->color_fmt << 10) |
1614 (dev_priv->microcode_version ==
1615 UCODE_R100 ? RADEON_ZBLOCK16 : 0));
1616
1617 dev_priv->depth_clear.rb3d_zstencilcntl =
1618 (dev_priv->depth_fmt |
1619 RADEON_Z_TEST_ALWAYS |
1620 RADEON_STENCIL_TEST_ALWAYS |
1621 RADEON_STENCIL_S_FAIL_REPLACE |
1622 RADEON_STENCIL_ZPASS_REPLACE |
1623 RADEON_STENCIL_ZFAIL_REPLACE | RADEON_Z_WRITE_ENABLE);
1624
1625 dev_priv->depth_clear.se_cntl = (RADEON_FFACE_CULL_CW |
1626 RADEON_BFACE_SOLID |
1627 RADEON_FFACE_SOLID |
1628 RADEON_FLAT_SHADE_VTX_LAST |
1629 RADEON_DIFFUSE_SHADE_FLAT |
1630 RADEON_ALPHA_SHADE_FLAT |
1631 RADEON_SPECULAR_SHADE_FLAT |
1632 RADEON_FOG_SHADE_FLAT |
1633 RADEON_VTX_PIX_CENTER_OGL |
1634 RADEON_ROUND_MODE_TRUNC |
1635 RADEON_ROUND_PREC_8TH_PIX);
1636
1637
1638 dev_priv->ring_offset = init->ring_offset;
1639 dev_priv->ring_rptr_offset = init->ring_rptr_offset;
1640 dev_priv->buffers_offset = init->buffers_offset;
1641 dev_priv->gart_textures_offset = init->gart_textures_offset;
1642
1643 dev_priv->sarea = drm_getsarea(dev);
1644 if (!dev_priv->sarea) {
1645 DRM_ERROR("could not find sarea!\n");
1646 radeon_do_cleanup_cp(dev);
1647 return -EINVAL;
1648 }
1649
1650 dev_priv->cp_ring = drm_core_findmap(dev, init->ring_offset);
1651 if (!dev_priv->cp_ring) {
1652 DRM_ERROR("could not find cp ring region!\n");
1653 radeon_do_cleanup_cp(dev);
1654 return -EINVAL;
1655 }
1656 dev_priv->ring_rptr = drm_core_findmap(dev, init->ring_rptr_offset);
1657 if (!dev_priv->ring_rptr) {
1658 DRM_ERROR("could not find ring read pointer!\n");
1659 radeon_do_cleanup_cp(dev);
1660 return -EINVAL;
1661 }
1662 dev->agp_buffer_token = init->buffers_offset;
1663 dev->agp_buffer_map = drm_core_findmap(dev, init->buffers_offset);
1664 if (!dev->agp_buffer_map) {
1665 DRM_ERROR("could not find dma buffer region!\n");
1666 radeon_do_cleanup_cp(dev);
1667 return -EINVAL;
1668 }
1669
1670 if (init->gart_textures_offset) {
1671 dev_priv->gart_textures =
1672 drm_core_findmap(dev, init->gart_textures_offset);
1673 if (!dev_priv->gart_textures) {
1674 DRM_ERROR("could not find GART texture region!\n");
1675 radeon_do_cleanup_cp(dev);
1676 return -EINVAL;
1677 }
1678 }
1679
1680 dev_priv->sarea_priv =
1681 (drm_radeon_sarea_t *) ((u8 *) dev_priv->sarea->handle +
1682 init->sarea_priv_offset);
1683
1684#if __OS_HAS_AGP
1685 if (dev_priv->flags & RADEON_IS_AGP) {
1686 drm_core_ioremap(dev_priv->cp_ring, dev);
1687 drm_core_ioremap(dev_priv->ring_rptr, dev);
1688 drm_core_ioremap(dev->agp_buffer_map, dev);
1689 if (!dev_priv->cp_ring->handle ||
1690 !dev_priv->ring_rptr->handle ||
1691 !dev->agp_buffer_map->handle) {
1692 DRM_ERROR("could not find ioremap agp regions!\n");
1693 radeon_do_cleanup_cp(dev);
1694 return -EINVAL;
1695 }
1696 } else
1697#endif
1698 {
1699 dev_priv->cp_ring->handle = (void *)dev_priv->cp_ring->offset;
1700 dev_priv->ring_rptr->handle =
1701 (void *)dev_priv->ring_rptr->offset;
1702 dev->agp_buffer_map->handle =
1703 (void *)dev->agp_buffer_map->offset;
1704
1705 DRM_DEBUG("dev_priv->cp_ring->handle %p\n",
1706 dev_priv->cp_ring->handle);
1707 DRM_DEBUG("dev_priv->ring_rptr->handle %p\n",
1708 dev_priv->ring_rptr->handle);
1709 DRM_DEBUG("dev->agp_buffer_map->handle %p\n",
1710 dev->agp_buffer_map->handle);
1711 }
1712
1713 dev_priv->fb_location = (radeon_read_fb_location(dev_priv) & 0xffff) << 16;
1714 dev_priv->fb_size =
1715 ((radeon_read_fb_location(dev_priv) & 0xffff0000u) + 0x10000)
1716 - dev_priv->fb_location;
1717
1718 dev_priv->front_pitch_offset = (((dev_priv->front_pitch / 64) << 22) |
1719 ((dev_priv->front_offset
1720 + dev_priv->fb_location) >> 10));
1721
1722 dev_priv->back_pitch_offset = (((dev_priv->back_pitch / 64) << 22) |
1723 ((dev_priv->back_offset
1724 + dev_priv->fb_location) >> 10));
1725
1726 dev_priv->depth_pitch_offset = (((dev_priv->depth_pitch / 64) << 22) |
1727 ((dev_priv->depth_offset
1728 + dev_priv->fb_location) >> 10));
1729
1730 dev_priv->gart_size = init->gart_size;
1731
1732 /* New let's set the memory map ... */
1733 if (dev_priv->new_memmap) {
1734 u32 base = 0;
1735
1736 DRM_INFO("Setting GART location based on new memory map\n");
1737
1738 /* If using AGP, try to locate the AGP aperture at the same
1739 * location in the card and on the bus, though we have to
1740 * align it down.
1741 */
1742#if __OS_HAS_AGP
1743 if (dev_priv->flags & RADEON_IS_AGP) {
1744 base = dev->agp->base;
1745 /* Check if valid */
1746 if ((base + dev_priv->gart_size - 1) >= dev_priv->fb_location &&
1747 base < (dev_priv->fb_location + dev_priv->fb_size - 1)) {
1748 DRM_INFO("Can't use AGP base @0x%08lx, won't fit\n",
1749 dev->agp->base);
1750 base = 0;
1751 }
1752 }
1753#endif
1754 /* If not or if AGP is at 0 (Macs), try to put it elsewhere */
1755 if (base == 0) {
1756 base = dev_priv->fb_location + dev_priv->fb_size;
1757 if (base < dev_priv->fb_location ||
1758 ((base + dev_priv->gart_size) & 0xfffffffful) < base)
1759 base = dev_priv->fb_location
1760 - dev_priv->gart_size;
1761 }
1762 dev_priv->gart_vm_start = base & 0xffc00000u;
1763 if (dev_priv->gart_vm_start != base)
1764 DRM_INFO("GART aligned down from 0x%08x to 0x%08x\n",
1765 base, dev_priv->gart_vm_start);
1766 } else {
1767 DRM_INFO("Setting GART location based on old memory map\n");
1768 dev_priv->gart_vm_start = dev_priv->fb_location +
1769 RADEON_READ(RADEON_CONFIG_APER_SIZE);
1770 }
1771
1772#if __OS_HAS_AGP
1773 if (dev_priv->flags & RADEON_IS_AGP)
1774 dev_priv->gart_buffers_offset = (dev->agp_buffer_map->offset
1775 - dev->agp->base
1776 + dev_priv->gart_vm_start);
1777 else
1778#endif
1779 dev_priv->gart_buffers_offset = (dev->agp_buffer_map->offset
1780 - (unsigned long)dev->sg->virtual
1781 + dev_priv->gart_vm_start);
1782
1783 DRM_DEBUG("dev_priv->gart_size %d\n", dev_priv->gart_size);
1784 DRM_DEBUG("dev_priv->gart_vm_start 0x%x\n", dev_priv->gart_vm_start);
1785 DRM_DEBUG("dev_priv->gart_buffers_offset 0x%lx\n",
1786 dev_priv->gart_buffers_offset);
1787
1788 dev_priv->ring.start = (u32 *) dev_priv->cp_ring->handle;
1789 dev_priv->ring.end = ((u32 *) dev_priv->cp_ring->handle
1790 + init->ring_size / sizeof(u32));
1791 dev_priv->ring.size = init->ring_size;
1792 dev_priv->ring.size_l2qw = drm_order(init->ring_size / 8);
1793
1794 dev_priv->ring.rptr_update = /* init->rptr_update */ 4096;
1795 dev_priv->ring.rptr_update_l2qw = drm_order( /* init->rptr_update */ 4096 / 8);
1796
1797 dev_priv->ring.fetch_size = /* init->fetch_size */ 32;
1798 dev_priv->ring.fetch_size_l2ow = drm_order( /* init->fetch_size */ 32 / 16);
1799 dev_priv->ring.tail_mask = (dev_priv->ring.size / sizeof(u32)) - 1;
1800
1801 dev_priv->ring.high_mark = RADEON_RING_HIGH_MARK;
1802
1803#if __OS_HAS_AGP
1804 if (dev_priv->flags & RADEON_IS_AGP) {
1805 /* Turn off PCI GART */
1806 radeon_set_pcigart(dev_priv, 0);
1807 } else
1808#endif
1809 {
1810 dev_priv->gart_info.table_mask = DMA_BIT_MASK(32);
1811 /* if we have an offset set from userspace */
1812 if (dev_priv->pcigart_offset_set) {
1813 dev_priv->gart_info.bus_addr =
1814 dev_priv->pcigart_offset + dev_priv->fb_location;
1815 dev_priv->gart_info.mapping.offset =
1816 dev_priv->pcigart_offset + dev_priv->fb_aper_offset;
1817 dev_priv->gart_info.mapping.size =
1818 dev_priv->gart_info.table_size;
1819
1820 drm_core_ioremap(&dev_priv->gart_info.mapping, dev);
1821 dev_priv->gart_info.addr =
1822 dev_priv->gart_info.mapping.handle;
1823
1824 if (dev_priv->flags & RADEON_IS_PCIE)
1825 dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCIE;
1826 else
1827 dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCI;
1828 dev_priv->gart_info.gart_table_location =
1829 DRM_ATI_GART_FB;
1830
1831 DRM_DEBUG("Setting phys_pci_gart to %p %08lX\n",
1832 dev_priv->gart_info.addr,
1833 dev_priv->pcigart_offset);
1834 } else {
1835 if (dev_priv->flags & RADEON_IS_IGPGART)
1836 dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_IGP;
1837 else
1838 dev_priv->gart_info.gart_reg_if = DRM_ATI_GART_PCI;
1839 dev_priv->gart_info.gart_table_location =
1840 DRM_ATI_GART_MAIN;
1841 dev_priv->gart_info.addr = NULL;
1842 dev_priv->gart_info.bus_addr = 0;
1843 if (dev_priv->flags & RADEON_IS_PCIE) {
1844 DRM_ERROR
1845 ("Cannot use PCI Express without GART in FB memory\n");
1846 radeon_do_cleanup_cp(dev);
1847 return -EINVAL;
1848 }
1849 }
1850
1851 if (!drm_ati_pcigart_init(dev, &dev_priv->gart_info)) {
1852 DRM_ERROR("failed to init PCI GART!\n");
1853 radeon_do_cleanup_cp(dev);
1854 return -ENOMEM;
1855 }
1856
1857 /* Turn on PCI GART */
1858 radeon_set_pcigart(dev_priv, 1);
1859 }
1860
1861 radeon_cp_load_microcode(dev_priv);
1862 radeon_cp_init_ring_buffer(dev, dev_priv);
1863
1864 dev_priv->last_buf = 0;
1865
1866 radeon_do_engine_reset(dev);
1867 radeon_test_writeback(dev_priv);
1868
1869 return 0;
1870}
1871
1872static int radeon_do_cleanup_cp(struct drm_device * dev)
1873{
1874 drm_radeon_private_t *dev_priv = dev->dev_private;
1875 DRM_DEBUG("\n");
1876
1877 /* Make sure interrupts are disabled here because the uninstall ioctl
1878 * may not have been called from userspace and after dev_private
1879 * is freed, it's too late.
1880 */
1881 if (dev->irq_enabled)
1882 drm_irq_uninstall(dev);
1883
1884#if __OS_HAS_AGP
1885 if (dev_priv->flags & RADEON_IS_AGP) {
1886 if (dev_priv->cp_ring != NULL) {
1887 drm_core_ioremapfree(dev_priv->cp_ring, dev);
1888 dev_priv->cp_ring = NULL;
1889 }
1890 if (dev_priv->ring_rptr != NULL) {
1891 drm_core_ioremapfree(dev_priv->ring_rptr, dev);
1892 dev_priv->ring_rptr = NULL;
1893 }
1894 if (dev->agp_buffer_map != NULL) {
1895 drm_core_ioremapfree(dev->agp_buffer_map, dev);
1896 dev->agp_buffer_map = NULL;
1897 }
1898 } else
1899#endif
1900 {
1901
1902 if (dev_priv->gart_info.bus_addr) {
1903 /* Turn off PCI GART */
1904 radeon_set_pcigart(dev_priv, 0);
1905 if (!drm_ati_pcigart_cleanup(dev, &dev_priv->gart_info))
1906 DRM_ERROR("failed to cleanup PCI GART!\n");
1907 }
1908
1909 if (dev_priv->gart_info.gart_table_location == DRM_ATI_GART_FB)
1910 {
1911 drm_core_ioremapfree(&dev_priv->gart_info.mapping, dev);
1912 dev_priv->gart_info.addr = 0;
1913 }
1914 }
1915 /* only clear to the start of flags */
1916 memset(dev_priv, 0, offsetof(drm_radeon_private_t, flags));
1917
1918 return 0;
1919}
1920
1921/* This code will reinit the Radeon CP hardware after a resume from disc.
1922 * AFAIK, it would be very difficult to pickle the state at suspend time, so
1923 * here we make sure that all Radeon hardware initialisation is re-done without
1924 * affecting running applications.
1925 *
1926 * Charl P. Botha <http://cpbotha.net>
1927 */
1928static int radeon_do_resume_cp(struct drm_device * dev)
1929{
1930 drm_radeon_private_t *dev_priv = dev->dev_private;
1931
1932 if (!dev_priv) {
1933 DRM_ERROR("Called with no initialization\n");
1934 return -EINVAL;
1935 }
1936
1937 DRM_DEBUG("Starting radeon_do_resume_cp()\n");
1938
1939#if __OS_HAS_AGP
1940 if (dev_priv->flags & RADEON_IS_AGP) {
1941 /* Turn off PCI GART */
1942 radeon_set_pcigart(dev_priv, 0);
1943 } else
1944#endif
1945 {
1946 /* Turn on PCI GART */
1947 radeon_set_pcigart(dev_priv, 1);
1948 }
1949
1950 radeon_cp_load_microcode(dev_priv);
1951 radeon_cp_init_ring_buffer(dev, dev_priv);
1952
1953 radeon_do_engine_reset(dev);
1954
1955 DRM_DEBUG("radeon_do_resume_cp() complete\n");
1956
1957 return 0;
1958}
1959
1960int radeon_cp_init(struct drm_device *dev, void *data, struct drm_file *file_priv)
1961{
1962 drm_radeon_init_t *init = data;
1963
1964 LOCK_TEST_WITH_RETURN(dev, file_priv);
1965
1966 if (init->func == RADEON_INIT_R300_CP)
1967 r300_init_reg_flags(dev);
1968
1969 switch (init->func) {
1970 case RADEON_INIT_CP:
1971 case RADEON_INIT_R200_CP:
1972 case RADEON_INIT_R300_CP:
1973 return radeon_do_init_cp(dev, init);
1974 case RADEON_CLEANUP_CP:
1975 return radeon_do_cleanup_cp(dev);
1976 }
1977
1978 return -EINVAL;
1979}
1980
1981int radeon_cp_start(struct drm_device *dev, void *data, struct drm_file *file_priv)
1982{
1983 drm_radeon_private_t *dev_priv = dev->dev_private;
1984 DRM_DEBUG("\n");
1985
1986 LOCK_TEST_WITH_RETURN(dev, file_priv);
1987
1988 if (dev_priv->cp_running) {
1989 DRM_DEBUG("while CP running\n");
1990 return 0;
1991 }
1992 if (dev_priv->cp_mode == RADEON_CSQ_PRIDIS_INDDIS) {
1993 DRM_DEBUG("called with bogus CP mode (%d)\n",
1994 dev_priv->cp_mode);
1995 return 0;
1996 }
1997
1998 radeon_do_cp_start(dev_priv);
1999
2000 return 0;
2001}
2002
2003/* Stop the CP. The engine must have been idled before calling this
2004 * routine.
2005 */
2006int radeon_cp_stop(struct drm_device *dev, void *data, struct drm_file *file_priv)
2007{
2008 drm_radeon_private_t *dev_priv = dev->dev_private;
2009 drm_radeon_cp_stop_t *stop = data;
2010 int ret;
2011 DRM_DEBUG("\n");
2012
2013 LOCK_TEST_WITH_RETURN(dev, file_priv);
2014
2015 if (!dev_priv->cp_running)
2016 return 0;
2017
2018 /* Flush any pending CP commands. This ensures any outstanding
2019 * commands are exectuted by the engine before we turn it off.
2020 */
2021 if (stop->flush) {
2022 radeon_do_cp_flush(dev_priv);
2023 }
2024
2025 /* If we fail to make the engine go idle, we return an error
2026 * code so that the DRM ioctl wrapper can try again.
2027 */
2028 if (stop->idle) {
2029 ret = radeon_do_cp_idle(dev_priv);
2030 if (ret)
2031 return ret;
2032 }
2033
2034 /* Finally, we can turn off the CP. If the engine isn't idle,
2035 * we will get some dropped triangles as they won't be fully
2036 * rendered before the CP is shut down.
2037 */
2038 radeon_do_cp_stop(dev_priv);
2039
2040 /* Reset the engine */
2041 radeon_do_engine_reset(dev);
2042
2043 return 0;
2044}
2045
2046void radeon_do_release(struct drm_device * dev)
2047{
2048 drm_radeon_private_t *dev_priv = dev->dev_private;
2049 int i, ret;
2050
2051 if (dev_priv) {
2052 if (dev_priv->cp_running) {
2053 /* Stop the cp */
2054 while ((ret = radeon_do_cp_idle(dev_priv)) != 0) {
2055 DRM_DEBUG("radeon_do_cp_idle %d\n", ret);
2056#ifdef __linux__
2057 schedule();
2058#else
2059 tsleep(&ret, PZERO, "rdnrel", 1);
2060#endif
2061 }
2062 radeon_do_cp_stop(dev_priv);
2063 radeon_do_engine_reset(dev);
2064 }
2065
2066 /* Disable *all* interrupts */
2067 if (dev_priv->mmio) /* remove this after permanent addmaps */
2068 RADEON_WRITE(RADEON_GEN_INT_CNTL, 0);
2069
2070 if (dev_priv->mmio) { /* remove all surfaces */
2071 for (i = 0; i < RADEON_MAX_SURFACES; i++) {
2072 RADEON_WRITE(RADEON_SURFACE0_INFO + 16 * i, 0);
2073 RADEON_WRITE(RADEON_SURFACE0_LOWER_BOUND +
2074 16 * i, 0);
2075 RADEON_WRITE(RADEON_SURFACE0_UPPER_BOUND +
2076 16 * i, 0);
2077 }
2078 }
2079
2080 /* Free memory heap structures */
2081 radeon_mem_takedown(&(dev_priv->gart_heap));
2082 radeon_mem_takedown(&(dev_priv->fb_heap));
2083
2084 /* deallocate kernel resources */
2085 radeon_do_cleanup_cp(dev);
2086 }
2087}
2088
2089/* Just reset the CP ring. Called as part of an X Server engine reset.
2090 */
2091int radeon_cp_reset(struct drm_device *dev, void *data, struct drm_file *file_priv)
2092{
2093 drm_radeon_private_t *dev_priv = dev->dev_private;
2094 DRM_DEBUG("\n");
2095
2096 LOCK_TEST_WITH_RETURN(dev, file_priv);
2097
2098 if (!dev_priv) {
2099 DRM_DEBUG("called before init done\n");
2100 return -EINVAL;
2101 }
2102
2103 radeon_do_cp_reset(dev_priv);
2104
2105 /* The CP is no longer running after an engine reset */
2106 dev_priv->cp_running = 0;
2107
2108 return 0;
2109}
2110
2111int radeon_cp_idle(struct drm_device *dev, void *data, struct drm_file *file_priv)
2112{
2113 drm_radeon_private_t *dev_priv = dev->dev_private;
2114 DRM_DEBUG("\n");
2115
2116 LOCK_TEST_WITH_RETURN(dev, file_priv);
2117
2118 return radeon_do_cp_idle(dev_priv);
2119}
2120
2121/* Added by Charl P. Botha to call radeon_do_resume_cp().
2122 */
2123int radeon_cp_resume(struct drm_device *dev, void *data, struct drm_file *file_priv)
2124{
2125
2126 return radeon_do_resume_cp(dev);
2127}
2128
2129int radeon_engine_reset(struct drm_device *dev, void *data, struct drm_file *file_priv)
2130{
2131 DRM_DEBUG("\n");
2132
2133 LOCK_TEST_WITH_RETURN(dev, file_priv);
2134
2135 return radeon_do_engine_reset(dev);
2136}
2137
2138/* ================================================================
2139 * Fullscreen mode
2140 */
2141
2142/* KW: Deprecated to say the least:
2143 */
2144int radeon_fullscreen(struct drm_device *dev, void *data, struct drm_file *file_priv)
2145{
2146 return 0;
2147}
2148
2149/* ================================================================
2150 * Freelist management
2151 */
2152
2153/* Original comment: FIXME: ROTATE_BUFS is a hack to cycle through
2154 * bufs until freelist code is used. Note this hides a problem with
2155 * the scratch register * (used to keep track of last buffer
2156 * completed) being written to before * the last buffer has actually
2157 * completed rendering.
2158 *
2159 * KW: It's also a good way to find free buffers quickly.
2160 *
2161 * KW: Ideally this loop wouldn't exist, and freelist_get wouldn't
2162 * sleep. However, bugs in older versions of radeon_accel.c mean that
2163 * we essentially have to do this, else old clients will break.
2164 *
2165 * However, it does leave open a potential deadlock where all the
2166 * buffers are held by other clients, which can't release them because
2167 * they can't get the lock.
2168 */
2169
2170struct drm_buf *radeon_freelist_get(struct drm_device * dev)
2171{
2172 struct drm_device_dma *dma = dev->dma;
2173 drm_radeon_private_t *dev_priv = dev->dev_private;
2174 drm_radeon_buf_priv_t *buf_priv;
2175 struct drm_buf *buf;
2176 int i, t;
2177 int start;
2178
2179 if (++dev_priv->last_buf >= dma->buf_count)
2180 dev_priv->last_buf = 0;
2181
2182 start = dev_priv->last_buf;
2183
2184 for (t = 0; t < dev_priv->usec_timeout; t++) {
2185 u32 done_age = GET_SCRATCH(1);
2186 DRM_DEBUG("done_age = %d\n", done_age);
2187 for (i = start; i < dma->buf_count; i++) {
2188 buf = dma->buflist[i];
2189 buf_priv = buf->dev_private;
2190 if (buf->file_priv == NULL || (buf->pending &&
2191 buf_priv->age <=
2192 done_age)) {
2193 dev_priv->stats.requested_bufs++;
2194 buf->pending = 0;
2195 return buf;
2196 }
2197 start = 0;
2198 }
2199
2200 if (t) {
2201 DRM_UDELAY(1);
2202 dev_priv->stats.freelist_loops++;
2203 }
2204 }
2205
2206 DRM_DEBUG("returning NULL!\n");
2207 return NULL;
2208}
2209
2210#if 0
2211struct drm_buf *radeon_freelist_get(struct drm_device * dev)
2212{
2213 struct drm_device_dma *dma = dev->dma;
2214 drm_radeon_private_t *dev_priv = dev->dev_private;
2215 drm_radeon_buf_priv_t *buf_priv;
2216 struct drm_buf *buf;
2217 int i, t;
2218 int start;
2219 u32 done_age = DRM_READ32(dev_priv->ring_rptr, RADEON_SCRATCHOFF(1));
2220
2221 if (++dev_priv->last_buf >= dma->buf_count)
2222 dev_priv->last_buf = 0;
2223
2224 start = dev_priv->last_buf;
2225 dev_priv->stats.freelist_loops++;
2226
2227 for (t = 0; t < 2; t++) {
2228 for (i = start; i < dma->buf_count; i++) {
2229 buf = dma->buflist[i];
2230 buf_priv = buf->dev_private;
2231 if (buf->file_priv == 0 || (buf->pending &&
2232 buf_priv->age <=
2233 done_age)) {
2234 dev_priv->stats.requested_bufs++;
2235 buf->pending = 0;
2236 return buf;
2237 }
2238 }
2239 start = 0;
2240 }
2241
2242 return NULL;
2243}
2244#endif
2245
2246void radeon_freelist_reset(struct drm_device * dev)
2247{
2248 struct drm_device_dma *dma = dev->dma;
2249 drm_radeon_private_t *dev_priv = dev->dev_private;
2250 int i;
2251
2252 dev_priv->last_buf = 0;
2253 for (i = 0; i < dma->buf_count; i++) {
2254 struct drm_buf *buf = dma->buflist[i];
2255 drm_radeon_buf_priv_t *buf_priv = buf->dev_private;
2256 buf_priv->age = 0;
2257 }
2258}
2259
2260/* ================================================================
2261 * CP command submission
2262 */
2263
2264int radeon_wait_ring(drm_radeon_private_t * dev_priv, int n)
2265{
2266 drm_radeon_ring_buffer_t *ring = &dev_priv->ring;
2267 int i;
2268 u32 last_head = GET_RING_HEAD(dev_priv);
2269
2270 for (i = 0; i < dev_priv->usec_timeout; i++) {
2271 u32 head = GET_RING_HEAD(dev_priv);
2272
2273 ring->space = (head - ring->tail) * sizeof(u32);
2274 if (ring->space <= 0)
2275 ring->space += ring->size;
2276 if (ring->space > n)
2277 return 0;
2278
2279 dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
2280
2281 if (head != last_head)
2282 i = 0;
2283 last_head = head;
2284
2285 DRM_UDELAY(1);
2286 }
2287
2288 /* FIXME: This return value is ignored in the BEGIN_RING macro! */
2289#if RADEON_FIFO_DEBUG
2290 radeon_status(dev_priv);
2291 DRM_ERROR("failed!\n");
2292#endif
2293 return -EBUSY;
2294}
2295
2296static int radeon_cp_get_buffers(struct drm_device *dev,
2297 struct drm_file *file_priv,
2298 struct drm_dma * d)
2299{
2300 int i;
2301 struct drm_buf *buf;
2302
2303 for (i = d->granted_count; i < d->request_count; i++) {
2304 buf = radeon_freelist_get(dev);
2305 if (!buf)
2306 return -EBUSY; /* NOTE: broken client */
2307
2308 buf->file_priv = file_priv;
2309
2310 if (DRM_COPY_TO_USER(&d->request_indices[i], &buf->idx,
2311 sizeof(buf->idx)))
2312 return -EFAULT;
2313 if (DRM_COPY_TO_USER(&d->request_sizes[i], &buf->total,
2314 sizeof(buf->total)))
2315 return -EFAULT;
2316
2317 d->granted_count++;
2318 }
2319 return 0;
2320}
2321
2322int radeon_cp_buffers(struct drm_device *dev, void *data, struct drm_file *file_priv)
2323{
2324 struct drm_device_dma *dma = dev->dma;
2325 int ret = 0;
2326 struct drm_dma *d = data;
2327
2328 LOCK_TEST_WITH_RETURN(dev, file_priv);
2329
2330 /* Please don't send us buffers.
2331 */
2332 if (d->send_count != 0) {
2333 DRM_ERROR("Process %d trying to send %d buffers via drmDMA\n",
2334 DRM_CURRENTPID, d->send_count);
2335 return -EINVAL;
2336 }
2337
2338 /* We'll send you buffers.
2339 */
2340 if (d->request_count < 0 || d->request_count > dma->buf_count) {
2341 DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n",
2342 DRM_CURRENTPID, d->request_count, dma->buf_count);
2343 return -EINVAL;
2344 }
2345
2346 d->granted_count = 0;
2347
2348 if (d->request_count) {
2349 ret = radeon_cp_get_buffers(dev, file_priv, d);
2350 }
2351
2352 return ret;
2353}
2354
2355int radeon_driver_load(struct drm_device *dev, unsigned long flags)
2356{
2357 drm_radeon_private_t *dev_priv;
2358 int ret = 0;
2359
2360 dev_priv = drm_alloc(sizeof(drm_radeon_private_t), DRM_MEM_DRIVER);
2361 if (dev_priv == NULL)
2362 return -ENOMEM;
2363
2364 memset(dev_priv, 0, sizeof(drm_radeon_private_t));
2365 dev->dev_private = (void *)dev_priv;
2366 dev_priv->flags = flags;
2367
2368 switch (flags & RADEON_FAMILY_MASK) {
2369 case CHIP_R100:
2370 case CHIP_RV200:
2371 case CHIP_R200:
2372 case CHIP_R300:
2373 case CHIP_R350:
2374 case CHIP_R420:
2375 case CHIP_RV410:
2376 case CHIP_RV515:
2377 case CHIP_R520:
2378 case CHIP_RV570:
2379 case CHIP_R580:
2380 dev_priv->flags |= RADEON_HAS_HIERZ;
2381 break;
2382 default:
2383 /* all other chips have no hierarchical z buffer */
2384 break;
2385 }
2386
2387 if (drm_device_is_agp(dev))
2388 dev_priv->flags |= RADEON_IS_AGP;
2389 else if (drm_device_is_pcie(dev))
2390 dev_priv->flags |= RADEON_IS_PCIE;
2391 else
2392 dev_priv->flags |= RADEON_IS_PCI;
2393
2394 DRM_DEBUG("%s card detected\n",
2395 ((dev_priv->flags & RADEON_IS_AGP) ? "AGP" : (((dev_priv->flags & RADEON_IS_PCIE) ? "PCIE" : "PCI"))));
2396 return ret;
2397}
2398
2399/* Create mappings for registers and framebuffer so userland doesn't necessarily
2400 * have to find them.
2401 */
2402int radeon_driver_firstopen(struct drm_device *dev)
2403{
2404 int ret;
2405 drm_local_map_t *map;
2406 drm_radeon_private_t *dev_priv = dev->dev_private;
2407
2408 dev_priv->gart_info.table_size = RADEON_PCIGART_TABLE_SIZE;
2409
2410 ret = drm_addmap(dev, drm_get_resource_start(dev, 2),
2411 drm_get_resource_len(dev, 2), _DRM_REGISTERS,
2412 _DRM_READ_ONLY, &dev_priv->mmio);
2413 if (ret != 0)
2414 return ret;
2415
2416 dev_priv->fb_aper_offset = drm_get_resource_start(dev, 0);
2417 ret = drm_addmap(dev, dev_priv->fb_aper_offset,
2418 drm_get_resource_len(dev, 0), _DRM_FRAME_BUFFER,
2419 _DRM_WRITE_COMBINING, &map);
2420 if (ret != 0)
2421 return ret;
2422
2423 return 0;
2424}
2425
2426int radeon_driver_unload(struct drm_device *dev)
2427{
2428 drm_radeon_private_t *dev_priv = dev->dev_private;
2429
2430 DRM_DEBUG("\n");
2431 drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER);
2432
2433 dev->dev_private = NULL;
2434 return 0;
2435}
diff --git a/drivers/char/drm/radeon_drm.h b/drivers/char/drm/radeon_drm.h
deleted file mode 100644
index aab82e121e07..000000000000
--- a/drivers/char/drm/radeon_drm.h
+++ /dev/null
@@ -1,741 +0,0 @@
1/* radeon_drm.h -- Public header for the radeon driver -*- linux-c -*-
2 *
3 * Copyright 2000 Precision Insight, Inc., Cedar Park, Texas.
4 * Copyright 2000 VA Linux Systems, Inc., Fremont, California.
5 * Copyright 2002 Tungsten Graphics, Inc., Cedar Park, Texas.
6 * All rights reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice (including the next
16 * paragraph) shall be included in all copies or substantial portions of the
17 * Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
23 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 * DEALINGS IN THE SOFTWARE.
26 *
27 * Authors:
28 * Kevin E. Martin <martin@valinux.com>
29 * Gareth Hughes <gareth@valinux.com>
30 * Keith Whitwell <keith@tungstengraphics.com>
31 */
32
33#ifndef __RADEON_DRM_H__
34#define __RADEON_DRM_H__
35
36/* WARNING: If you change any of these defines, make sure to change the
37 * defines in the X server file (radeon_sarea.h)
38 */
39#ifndef __RADEON_SAREA_DEFINES__
40#define __RADEON_SAREA_DEFINES__
41
42/* Old style state flags, required for sarea interface (1.1 and 1.2
43 * clears) and 1.2 drm_vertex2 ioctl.
44 */
45#define RADEON_UPLOAD_CONTEXT 0x00000001
46#define RADEON_UPLOAD_VERTFMT 0x00000002
47#define RADEON_UPLOAD_LINE 0x00000004
48#define RADEON_UPLOAD_BUMPMAP 0x00000008
49#define RADEON_UPLOAD_MASKS 0x00000010
50#define RADEON_UPLOAD_VIEWPORT 0x00000020
51#define RADEON_UPLOAD_SETUP 0x00000040
52#define RADEON_UPLOAD_TCL 0x00000080
53#define RADEON_UPLOAD_MISC 0x00000100
54#define RADEON_UPLOAD_TEX0 0x00000200
55#define RADEON_UPLOAD_TEX1 0x00000400
56#define RADEON_UPLOAD_TEX2 0x00000800
57#define RADEON_UPLOAD_TEX0IMAGES 0x00001000
58#define RADEON_UPLOAD_TEX1IMAGES 0x00002000
59#define RADEON_UPLOAD_TEX2IMAGES 0x00004000
60#define RADEON_UPLOAD_CLIPRECTS 0x00008000 /* handled client-side */
61#define RADEON_REQUIRE_QUIESCENCE 0x00010000
62#define RADEON_UPLOAD_ZBIAS 0x00020000 /* version 1.2 and newer */
63#define RADEON_UPLOAD_ALL 0x003effff
64#define RADEON_UPLOAD_CONTEXT_ALL 0x003e01ff
65
66/* New style per-packet identifiers for use in cmd_buffer ioctl with
67 * the RADEON_EMIT_PACKET command. Comments relate new packets to old
68 * state bits and the packet size:
69 */
70#define RADEON_EMIT_PP_MISC 0 /* context/7 */
71#define RADEON_EMIT_PP_CNTL 1 /* context/3 */
72#define RADEON_EMIT_RB3D_COLORPITCH 2 /* context/1 */
73#define RADEON_EMIT_RE_LINE_PATTERN 3 /* line/2 */
74#define RADEON_EMIT_SE_LINE_WIDTH 4 /* line/1 */
75#define RADEON_EMIT_PP_LUM_MATRIX 5 /* bumpmap/1 */
76#define RADEON_EMIT_PP_ROT_MATRIX_0 6 /* bumpmap/2 */
77#define RADEON_EMIT_RB3D_STENCILREFMASK 7 /* masks/3 */
78#define RADEON_EMIT_SE_VPORT_XSCALE 8 /* viewport/6 */
79#define RADEON_EMIT_SE_CNTL 9 /* setup/2 */
80#define RADEON_EMIT_SE_CNTL_STATUS 10 /* setup/1 */
81#define RADEON_EMIT_RE_MISC 11 /* misc/1 */
82#define RADEON_EMIT_PP_TXFILTER_0 12 /* tex0/6 */
83#define RADEON_EMIT_PP_BORDER_COLOR_0 13 /* tex0/1 */
84#define RADEON_EMIT_PP_TXFILTER_1 14 /* tex1/6 */
85#define RADEON_EMIT_PP_BORDER_COLOR_1 15 /* tex1/1 */
86#define RADEON_EMIT_PP_TXFILTER_2 16 /* tex2/6 */
87#define RADEON_EMIT_PP_BORDER_COLOR_2 17 /* tex2/1 */
88#define RADEON_EMIT_SE_ZBIAS_FACTOR 18 /* zbias/2 */
89#define RADEON_EMIT_SE_TCL_OUTPUT_VTX_FMT 19 /* tcl/11 */
90#define RADEON_EMIT_SE_TCL_MATERIAL_EMMISSIVE_RED 20 /* material/17 */
91#define R200_EMIT_PP_TXCBLEND_0 21 /* tex0/4 */
92#define R200_EMIT_PP_TXCBLEND_1 22 /* tex1/4 */
93#define R200_EMIT_PP_TXCBLEND_2 23 /* tex2/4 */
94#define R200_EMIT_PP_TXCBLEND_3 24 /* tex3/4 */
95#define R200_EMIT_PP_TXCBLEND_4 25 /* tex4/4 */
96#define R200_EMIT_PP_TXCBLEND_5 26 /* tex5/4 */
97#define R200_EMIT_PP_TXCBLEND_6 27 /* /4 */
98#define R200_EMIT_PP_TXCBLEND_7 28 /* /4 */
99#define R200_EMIT_TCL_LIGHT_MODEL_CTL_0 29 /* tcl/7 */
100#define R200_EMIT_TFACTOR_0 30 /* tf/7 */
101#define R200_EMIT_VTX_FMT_0 31 /* vtx/5 */
102#define R200_EMIT_VAP_CTL 32 /* vap/1 */
103#define R200_EMIT_MATRIX_SELECT_0 33 /* msl/5 */
104#define R200_EMIT_TEX_PROC_CTL_2 34 /* tcg/5 */
105#define R200_EMIT_TCL_UCP_VERT_BLEND_CTL 35 /* tcl/1 */
106#define R200_EMIT_PP_TXFILTER_0 36 /* tex0/6 */
107#define R200_EMIT_PP_TXFILTER_1 37 /* tex1/6 */
108#define R200_EMIT_PP_TXFILTER_2 38 /* tex2/6 */
109#define R200_EMIT_PP_TXFILTER_3 39 /* tex3/6 */
110#define R200_EMIT_PP_TXFILTER_4 40 /* tex4/6 */
111#define R200_EMIT_PP_TXFILTER_5 41 /* tex5/6 */
112#define R200_EMIT_PP_TXOFFSET_0 42 /* tex0/1 */
113#define R200_EMIT_PP_TXOFFSET_1 43 /* tex1/1 */
114#define R200_EMIT_PP_TXOFFSET_2 44 /* tex2/1 */
115#define R200_EMIT_PP_TXOFFSET_3 45 /* tex3/1 */
116#define R200_EMIT_PP_TXOFFSET_4 46 /* tex4/1 */
117#define R200_EMIT_PP_TXOFFSET_5 47 /* tex5/1 */
118#define R200_EMIT_VTE_CNTL 48 /* vte/1 */
119#define R200_EMIT_OUTPUT_VTX_COMP_SEL 49 /* vtx/1 */
120#define R200_EMIT_PP_TAM_DEBUG3 50 /* tam/1 */
121#define R200_EMIT_PP_CNTL_X 51 /* cst/1 */
122#define R200_EMIT_RB3D_DEPTHXY_OFFSET 52 /* cst/1 */
123#define R200_EMIT_RE_AUX_SCISSOR_CNTL 53 /* cst/1 */
124#define R200_EMIT_RE_SCISSOR_TL_0 54 /* cst/2 */
125#define R200_EMIT_RE_SCISSOR_TL_1 55 /* cst/2 */
126#define R200_EMIT_RE_SCISSOR_TL_2 56 /* cst/2 */
127#define R200_EMIT_SE_VAP_CNTL_STATUS 57 /* cst/1 */
128#define R200_EMIT_SE_VTX_STATE_CNTL 58 /* cst/1 */
129#define R200_EMIT_RE_POINTSIZE 59 /* cst/1 */
130#define R200_EMIT_TCL_INPUT_VTX_VECTOR_ADDR_0 60 /* cst/4 */
131#define R200_EMIT_PP_CUBIC_FACES_0 61
132#define R200_EMIT_PP_CUBIC_OFFSETS_0 62
133#define R200_EMIT_PP_CUBIC_FACES_1 63
134#define R200_EMIT_PP_CUBIC_OFFSETS_1 64
135#define R200_EMIT_PP_CUBIC_FACES_2 65
136#define R200_EMIT_PP_CUBIC_OFFSETS_2 66
137#define R200_EMIT_PP_CUBIC_FACES_3 67
138#define R200_EMIT_PP_CUBIC_OFFSETS_3 68
139#define R200_EMIT_PP_CUBIC_FACES_4 69
140#define R200_EMIT_PP_CUBIC_OFFSETS_4 70
141#define R200_EMIT_PP_CUBIC_FACES_5 71
142#define R200_EMIT_PP_CUBIC_OFFSETS_5 72
143#define RADEON_EMIT_PP_TEX_SIZE_0 73
144#define RADEON_EMIT_PP_TEX_SIZE_1 74
145#define RADEON_EMIT_PP_TEX_SIZE_2 75
146#define R200_EMIT_RB3D_BLENDCOLOR 76
147#define R200_EMIT_TCL_POINT_SPRITE_CNTL 77
148#define RADEON_EMIT_PP_CUBIC_FACES_0 78
149#define RADEON_EMIT_PP_CUBIC_OFFSETS_T0 79
150#define RADEON_EMIT_PP_CUBIC_FACES_1 80
151#define RADEON_EMIT_PP_CUBIC_OFFSETS_T1 81
152#define RADEON_EMIT_PP_CUBIC_FACES_2 82
153#define RADEON_EMIT_PP_CUBIC_OFFSETS_T2 83
154#define R200_EMIT_PP_TRI_PERF_CNTL 84
155#define R200_EMIT_PP_AFS_0 85
156#define R200_EMIT_PP_AFS_1 86
157#define R200_EMIT_ATF_TFACTOR 87
158#define R200_EMIT_PP_TXCTLALL_0 88
159#define R200_EMIT_PP_TXCTLALL_1 89
160#define R200_EMIT_PP_TXCTLALL_2 90
161#define R200_EMIT_PP_TXCTLALL_3 91
162#define R200_EMIT_PP_TXCTLALL_4 92
163#define R200_EMIT_PP_TXCTLALL_5 93
164#define R200_EMIT_VAP_PVS_CNTL 94
165#define RADEON_MAX_STATE_PACKETS 95
166
167/* Commands understood by cmd_buffer ioctl. More can be added but
168 * obviously these can't be removed or changed:
169 */
170#define RADEON_CMD_PACKET 1 /* emit one of the register packets above */
171#define RADEON_CMD_SCALARS 2 /* emit scalar data */
172#define RADEON_CMD_VECTORS 3 /* emit vector data */
173#define RADEON_CMD_DMA_DISCARD 4 /* discard current dma buf */
174#define RADEON_CMD_PACKET3 5 /* emit hw packet */
175#define RADEON_CMD_PACKET3_CLIP 6 /* emit hw packet wrapped in cliprects */
176#define RADEON_CMD_SCALARS2 7 /* r200 stopgap */
177#define RADEON_CMD_WAIT 8 /* emit hw wait commands -- note:
178 * doesn't make the cpu wait, just
179 * the graphics hardware */
180#define RADEON_CMD_VECLINEAR 9 /* another r200 stopgap */
181
182typedef union {
183 int i;
184 struct {
185 unsigned char cmd_type, pad0, pad1, pad2;
186 } header;
187 struct {
188 unsigned char cmd_type, packet_id, pad0, pad1;
189 } packet;
190 struct {
191 unsigned char cmd_type, offset, stride, count;
192 } scalars;
193 struct {
194 unsigned char cmd_type, offset, stride, count;
195 } vectors;
196 struct {
197 unsigned char cmd_type, addr_lo, addr_hi, count;
198 } veclinear;
199 struct {
200 unsigned char cmd_type, buf_idx, pad0, pad1;
201 } dma;
202 struct {
203 unsigned char cmd_type, flags, pad0, pad1;
204 } wait;
205} drm_radeon_cmd_header_t;
206
207#define RADEON_WAIT_2D 0x1
208#define RADEON_WAIT_3D 0x2
209
210/* Allowed parameters for R300_CMD_PACKET3
211 */
212#define R300_CMD_PACKET3_CLEAR 0
213#define R300_CMD_PACKET3_RAW 1
214
215/* Commands understood by cmd_buffer ioctl for R300.
216 * The interface has not been stabilized, so some of these may be removed
217 * and eventually reordered before stabilization.
218 */
219#define R300_CMD_PACKET0 1
220#define R300_CMD_VPU 2 /* emit vertex program upload */
221#define R300_CMD_PACKET3 3 /* emit a packet3 */
222#define R300_CMD_END3D 4 /* emit sequence ending 3d rendering */
223#define R300_CMD_CP_DELAY 5
224#define R300_CMD_DMA_DISCARD 6
225#define R300_CMD_WAIT 7
226# define R300_WAIT_2D 0x1
227# define R300_WAIT_3D 0x2
228/* these two defines are DOING IT WRONG - however
229 * we have userspace which relies on using these.
230 * The wait interface is backwards compat new
231 * code should use the NEW_WAIT defines below
232 * THESE ARE NOT BIT FIELDS
233 */
234# define R300_WAIT_2D_CLEAN 0x3
235# define R300_WAIT_3D_CLEAN 0x4
236
237# define R300_NEW_WAIT_2D_3D 0x3
238# define R300_NEW_WAIT_2D_2D_CLEAN 0x4
239# define R300_NEW_WAIT_3D_3D_CLEAN 0x6
240# define R300_NEW_WAIT_2D_2D_CLEAN_3D_3D_CLEAN 0x8
241
242#define R300_CMD_SCRATCH 8
243
244typedef union {
245 unsigned int u;
246 struct {
247 unsigned char cmd_type, pad0, pad1, pad2;
248 } header;
249 struct {
250 unsigned char cmd_type, count, reglo, reghi;
251 } packet0;
252 struct {
253 unsigned char cmd_type, count, adrlo, adrhi;
254 } vpu;
255 struct {
256 unsigned char cmd_type, packet, pad0, pad1;
257 } packet3;
258 struct {
259 unsigned char cmd_type, packet;
260 unsigned short count; /* amount of packet2 to emit */
261 } delay;
262 struct {
263 unsigned char cmd_type, buf_idx, pad0, pad1;
264 } dma;
265 struct {
266 unsigned char cmd_type, flags, pad0, pad1;
267 } wait;
268 struct {
269 unsigned char cmd_type, reg, n_bufs, flags;
270 } scratch;
271} drm_r300_cmd_header_t;
272
273#define RADEON_FRONT 0x1
274#define RADEON_BACK 0x2
275#define RADEON_DEPTH 0x4
276#define RADEON_STENCIL 0x8
277#define RADEON_CLEAR_FASTZ 0x80000000
278#define RADEON_USE_HIERZ 0x40000000
279#define RADEON_USE_COMP_ZBUF 0x20000000
280
281/* Primitive types
282 */
283#define RADEON_POINTS 0x1
284#define RADEON_LINES 0x2
285#define RADEON_LINE_STRIP 0x3
286#define RADEON_TRIANGLES 0x4
287#define RADEON_TRIANGLE_FAN 0x5
288#define RADEON_TRIANGLE_STRIP 0x6
289
290/* Vertex/indirect buffer size
291 */
292#define RADEON_BUFFER_SIZE 65536
293
294/* Byte offsets for indirect buffer data
295 */
296#define RADEON_INDEX_PRIM_OFFSET 20
297
298#define RADEON_SCRATCH_REG_OFFSET 32
299
300#define RADEON_NR_SAREA_CLIPRECTS 12
301
302/* There are 2 heaps (local/GART). Each region within a heap is a
303 * minimum of 64k, and there are at most 64 of them per heap.
304 */
305#define RADEON_LOCAL_TEX_HEAP 0
306#define RADEON_GART_TEX_HEAP 1
307#define RADEON_NR_TEX_HEAPS 2
308#define RADEON_NR_TEX_REGIONS 64
309#define RADEON_LOG_TEX_GRANULARITY 16
310
311#define RADEON_MAX_TEXTURE_LEVELS 12
312#define RADEON_MAX_TEXTURE_UNITS 3
313
314#define RADEON_MAX_SURFACES 8
315
316/* Blits have strict offset rules. All blit offset must be aligned on
317 * a 1K-byte boundary.
318 */
319#define RADEON_OFFSET_SHIFT 10
320#define RADEON_OFFSET_ALIGN (1 << RADEON_OFFSET_SHIFT)
321#define RADEON_OFFSET_MASK (RADEON_OFFSET_ALIGN - 1)
322
323#endif /* __RADEON_SAREA_DEFINES__ */
324
325typedef struct {
326 unsigned int red;
327 unsigned int green;
328 unsigned int blue;
329 unsigned int alpha;
330} radeon_color_regs_t;
331
332typedef struct {
333 /* Context state */
334 unsigned int pp_misc; /* 0x1c14 */
335 unsigned int pp_fog_color;
336 unsigned int re_solid_color;
337 unsigned int rb3d_blendcntl;
338 unsigned int rb3d_depthoffset;
339 unsigned int rb3d_depthpitch;
340 unsigned int rb3d_zstencilcntl;
341
342 unsigned int pp_cntl; /* 0x1c38 */
343 unsigned int rb3d_cntl;
344 unsigned int rb3d_coloroffset;
345 unsigned int re_width_height;
346 unsigned int rb3d_colorpitch;
347 unsigned int se_cntl;
348
349 /* Vertex format state */
350 unsigned int se_coord_fmt; /* 0x1c50 */
351
352 /* Line state */
353 unsigned int re_line_pattern; /* 0x1cd0 */
354 unsigned int re_line_state;
355
356 unsigned int se_line_width; /* 0x1db8 */
357
358 /* Bumpmap state */
359 unsigned int pp_lum_matrix; /* 0x1d00 */
360
361 unsigned int pp_rot_matrix_0; /* 0x1d58 */
362 unsigned int pp_rot_matrix_1;
363
364 /* Mask state */
365 unsigned int rb3d_stencilrefmask; /* 0x1d7c */
366 unsigned int rb3d_ropcntl;
367 unsigned int rb3d_planemask;
368
369 /* Viewport state */
370 unsigned int se_vport_xscale; /* 0x1d98 */
371 unsigned int se_vport_xoffset;
372 unsigned int se_vport_yscale;
373 unsigned int se_vport_yoffset;
374 unsigned int se_vport_zscale;
375 unsigned int se_vport_zoffset;
376
377 /* Setup state */
378 unsigned int se_cntl_status; /* 0x2140 */
379
380 /* Misc state */
381 unsigned int re_top_left; /* 0x26c0 */
382 unsigned int re_misc;
383} drm_radeon_context_regs_t;
384
385typedef struct {
386 /* Zbias state */
387 unsigned int se_zbias_factor; /* 0x1dac */
388 unsigned int se_zbias_constant;
389} drm_radeon_context2_regs_t;
390
391/* Setup registers for each texture unit
392 */
393typedef struct {
394 unsigned int pp_txfilter;
395 unsigned int pp_txformat;
396 unsigned int pp_txoffset;
397 unsigned int pp_txcblend;
398 unsigned int pp_txablend;
399 unsigned int pp_tfactor;
400 unsigned int pp_border_color;
401} drm_radeon_texture_regs_t;
402
403typedef struct {
404 unsigned int start;
405 unsigned int finish;
406 unsigned int prim:8;
407 unsigned int stateidx:8;
408 unsigned int numverts:16; /* overloaded as offset/64 for elt prims */
409 unsigned int vc_format; /* vertex format */
410} drm_radeon_prim_t;
411
412typedef struct {
413 drm_radeon_context_regs_t context;
414 drm_radeon_texture_regs_t tex[RADEON_MAX_TEXTURE_UNITS];
415 drm_radeon_context2_regs_t context2;
416 unsigned int dirty;
417} drm_radeon_state_t;
418
419typedef struct {
420 /* The channel for communication of state information to the
421 * kernel on firing a vertex buffer with either of the
422 * obsoleted vertex/index ioctls.
423 */
424 drm_radeon_context_regs_t context_state;
425 drm_radeon_texture_regs_t tex_state[RADEON_MAX_TEXTURE_UNITS];
426 unsigned int dirty;
427 unsigned int vertsize;
428 unsigned int vc_format;
429
430 /* The current cliprects, or a subset thereof.
431 */
432 struct drm_clip_rect boxes[RADEON_NR_SAREA_CLIPRECTS];
433 unsigned int nbox;
434
435 /* Counters for client-side throttling of rendering clients.
436 */
437 unsigned int last_frame;
438 unsigned int last_dispatch;
439 unsigned int last_clear;
440
441 struct drm_tex_region tex_list[RADEON_NR_TEX_HEAPS][RADEON_NR_TEX_REGIONS +
442 1];
443 unsigned int tex_age[RADEON_NR_TEX_HEAPS];
444 int ctx_owner;
445 int pfState; /* number of 3d windows (0,1,2ormore) */
446 int pfCurrentPage; /* which buffer is being displayed? */
447 int crtc2_base; /* CRTC2 frame offset */
448 int tiling_enabled; /* set by drm, read by 2d + 3d clients */
449} drm_radeon_sarea_t;
450
451/* WARNING: If you change any of these defines, make sure to change the
452 * defines in the Xserver file (xf86drmRadeon.h)
453 *
454 * KW: actually it's illegal to change any of this (backwards compatibility).
455 */
456
457/* Radeon specific ioctls
458 * The device specific ioctl range is 0x40 to 0x79.
459 */
460#define DRM_RADEON_CP_INIT 0x00
461#define DRM_RADEON_CP_START 0x01
462#define DRM_RADEON_CP_STOP 0x02
463#define DRM_RADEON_CP_RESET 0x03
464#define DRM_RADEON_CP_IDLE 0x04
465#define DRM_RADEON_RESET 0x05
466#define DRM_RADEON_FULLSCREEN 0x06
467#define DRM_RADEON_SWAP 0x07
468#define DRM_RADEON_CLEAR 0x08
469#define DRM_RADEON_VERTEX 0x09
470#define DRM_RADEON_INDICES 0x0A
471#define DRM_RADEON_NOT_USED
472#define DRM_RADEON_STIPPLE 0x0C
473#define DRM_RADEON_INDIRECT 0x0D
474#define DRM_RADEON_TEXTURE 0x0E
475#define DRM_RADEON_VERTEX2 0x0F
476#define DRM_RADEON_CMDBUF 0x10
477#define DRM_RADEON_GETPARAM 0x11
478#define DRM_RADEON_FLIP 0x12
479#define DRM_RADEON_ALLOC 0x13
480#define DRM_RADEON_FREE 0x14
481#define DRM_RADEON_INIT_HEAP 0x15
482#define DRM_RADEON_IRQ_EMIT 0x16
483#define DRM_RADEON_IRQ_WAIT 0x17
484#define DRM_RADEON_CP_RESUME 0x18
485#define DRM_RADEON_SETPARAM 0x19
486#define DRM_RADEON_SURF_ALLOC 0x1a
487#define DRM_RADEON_SURF_FREE 0x1b
488
489#define DRM_IOCTL_RADEON_CP_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_CP_INIT, drm_radeon_init_t)
490#define DRM_IOCTL_RADEON_CP_START DRM_IO( DRM_COMMAND_BASE + DRM_RADEON_CP_START)
491#define DRM_IOCTL_RADEON_CP_STOP DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_CP_STOP, drm_radeon_cp_stop_t)
492#define DRM_IOCTL_RADEON_CP_RESET DRM_IO( DRM_COMMAND_BASE + DRM_RADEON_CP_RESET)
493#define DRM_IOCTL_RADEON_CP_IDLE DRM_IO( DRM_COMMAND_BASE + DRM_RADEON_CP_IDLE)
494#define DRM_IOCTL_RADEON_RESET DRM_IO( DRM_COMMAND_BASE + DRM_RADEON_RESET)
495#define DRM_IOCTL_RADEON_FULLSCREEN DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_FULLSCREEN, drm_radeon_fullscreen_t)
496#define DRM_IOCTL_RADEON_SWAP DRM_IO( DRM_COMMAND_BASE + DRM_RADEON_SWAP)
497#define DRM_IOCTL_RADEON_CLEAR DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_CLEAR, drm_radeon_clear_t)
498#define DRM_IOCTL_RADEON_VERTEX DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_VERTEX, drm_radeon_vertex_t)
499#define DRM_IOCTL_RADEON_INDICES DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_INDICES, drm_radeon_indices_t)
500#define DRM_IOCTL_RADEON_STIPPLE DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_STIPPLE, drm_radeon_stipple_t)
501#define DRM_IOCTL_RADEON_INDIRECT DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_INDIRECT, drm_radeon_indirect_t)
502#define DRM_IOCTL_RADEON_TEXTURE DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_TEXTURE, drm_radeon_texture_t)
503#define DRM_IOCTL_RADEON_VERTEX2 DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_VERTEX2, drm_radeon_vertex2_t)
504#define DRM_IOCTL_RADEON_CMDBUF DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_CMDBUF, drm_radeon_cmd_buffer_t)
505#define DRM_IOCTL_RADEON_GETPARAM DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_GETPARAM, drm_radeon_getparam_t)
506#define DRM_IOCTL_RADEON_FLIP DRM_IO( DRM_COMMAND_BASE + DRM_RADEON_FLIP)
507#define DRM_IOCTL_RADEON_ALLOC DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_ALLOC, drm_radeon_mem_alloc_t)
508#define DRM_IOCTL_RADEON_FREE DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_FREE, drm_radeon_mem_free_t)
509#define DRM_IOCTL_RADEON_INIT_HEAP DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_INIT_HEAP, drm_radeon_mem_init_heap_t)
510#define DRM_IOCTL_RADEON_IRQ_EMIT DRM_IOWR(DRM_COMMAND_BASE + DRM_RADEON_IRQ_EMIT, drm_radeon_irq_emit_t)
511#define DRM_IOCTL_RADEON_IRQ_WAIT DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_IRQ_WAIT, drm_radeon_irq_wait_t)
512#define DRM_IOCTL_RADEON_CP_RESUME DRM_IO( DRM_COMMAND_BASE + DRM_RADEON_CP_RESUME)
513#define DRM_IOCTL_RADEON_SETPARAM DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_SETPARAM, drm_radeon_setparam_t)
514#define DRM_IOCTL_RADEON_SURF_ALLOC DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_SURF_ALLOC, drm_radeon_surface_alloc_t)
515#define DRM_IOCTL_RADEON_SURF_FREE DRM_IOW( DRM_COMMAND_BASE + DRM_RADEON_SURF_FREE, drm_radeon_surface_free_t)
516
517typedef struct drm_radeon_init {
518 enum {
519 RADEON_INIT_CP = 0x01,
520 RADEON_CLEANUP_CP = 0x02,
521 RADEON_INIT_R200_CP = 0x03,
522 RADEON_INIT_R300_CP = 0x04
523 } func;
524 unsigned long sarea_priv_offset;
525 int is_pci;
526 int cp_mode;
527 int gart_size;
528 int ring_size;
529 int usec_timeout;
530
531 unsigned int fb_bpp;
532 unsigned int front_offset, front_pitch;
533 unsigned int back_offset, back_pitch;
534 unsigned int depth_bpp;
535 unsigned int depth_offset, depth_pitch;
536
537 unsigned long fb_offset;
538 unsigned long mmio_offset;
539 unsigned long ring_offset;
540 unsigned long ring_rptr_offset;
541 unsigned long buffers_offset;
542 unsigned long gart_textures_offset;
543} drm_radeon_init_t;
544
545typedef struct drm_radeon_cp_stop {
546 int flush;
547 int idle;
548} drm_radeon_cp_stop_t;
549
550typedef struct drm_radeon_fullscreen {
551 enum {
552 RADEON_INIT_FULLSCREEN = 0x01,
553 RADEON_CLEANUP_FULLSCREEN = 0x02
554 } func;
555} drm_radeon_fullscreen_t;
556
557#define CLEAR_X1 0
558#define CLEAR_Y1 1
559#define CLEAR_X2 2
560#define CLEAR_Y2 3
561#define CLEAR_DEPTH 4
562
563typedef union drm_radeon_clear_rect {
564 float f[5];
565 unsigned int ui[5];
566} drm_radeon_clear_rect_t;
567
568typedef struct drm_radeon_clear {
569 unsigned int flags;
570 unsigned int clear_color;
571 unsigned int clear_depth;
572 unsigned int color_mask;
573 unsigned int depth_mask; /* misnamed field: should be stencil */
574 drm_radeon_clear_rect_t __user *depth_boxes;
575} drm_radeon_clear_t;
576
577typedef struct drm_radeon_vertex {
578 int prim;
579 int idx; /* Index of vertex buffer */
580 int count; /* Number of vertices in buffer */
581 int discard; /* Client finished with buffer? */
582} drm_radeon_vertex_t;
583
584typedef struct drm_radeon_indices {
585 int prim;
586 int idx;
587 int start;
588 int end;
589 int discard; /* Client finished with buffer? */
590} drm_radeon_indices_t;
591
592/* v1.2 - obsoletes drm_radeon_vertex and drm_radeon_indices
593 * - allows multiple primitives and state changes in a single ioctl
594 * - supports driver change to emit native primitives
595 */
596typedef struct drm_radeon_vertex2 {
597 int idx; /* Index of vertex buffer */
598 int discard; /* Client finished with buffer? */
599 int nr_states;
600 drm_radeon_state_t __user *state;
601 int nr_prims;
602 drm_radeon_prim_t __user *prim;
603} drm_radeon_vertex2_t;
604
605/* v1.3 - obsoletes drm_radeon_vertex2
606 * - allows arbitarily large cliprect list
607 * - allows updating of tcl packet, vector and scalar state
608 * - allows memory-efficient description of state updates
609 * - allows state to be emitted without a primitive
610 * (for clears, ctx switches)
611 * - allows more than one dma buffer to be referenced per ioctl
612 * - supports tcl driver
613 * - may be extended in future versions with new cmd types, packets
614 */
615typedef struct drm_radeon_cmd_buffer {
616 int bufsz;
617 char __user *buf;
618 int nbox;
619 struct drm_clip_rect __user *boxes;
620} drm_radeon_cmd_buffer_t;
621
622typedef struct drm_radeon_tex_image {
623 unsigned int x, y; /* Blit coordinates */
624 unsigned int width, height;
625 const void __user *data;
626} drm_radeon_tex_image_t;
627
628typedef struct drm_radeon_texture {
629 unsigned int offset;
630 int pitch;
631 int format;
632 int width; /* Texture image coordinates */
633 int height;
634 drm_radeon_tex_image_t __user *image;
635} drm_radeon_texture_t;
636
637typedef struct drm_radeon_stipple {
638 unsigned int __user *mask;
639} drm_radeon_stipple_t;
640
641typedef struct drm_radeon_indirect {
642 int idx;
643 int start;
644 int end;
645 int discard;
646} drm_radeon_indirect_t;
647
648/* enum for card type parameters */
649#define RADEON_CARD_PCI 0
650#define RADEON_CARD_AGP 1
651#define RADEON_CARD_PCIE 2
652
653/* 1.3: An ioctl to get parameters that aren't available to the 3d
654 * client any other way.
655 */
656#define RADEON_PARAM_GART_BUFFER_OFFSET 1 /* card offset of 1st GART buffer */
657#define RADEON_PARAM_LAST_FRAME 2
658#define RADEON_PARAM_LAST_DISPATCH 3
659#define RADEON_PARAM_LAST_CLEAR 4
660/* Added with DRM version 1.6. */
661#define RADEON_PARAM_IRQ_NR 5
662#define RADEON_PARAM_GART_BASE 6 /* card offset of GART base */
663/* Added with DRM version 1.8. */
664#define RADEON_PARAM_REGISTER_HANDLE 7 /* for drmMap() */
665#define RADEON_PARAM_STATUS_HANDLE 8
666#define RADEON_PARAM_SAREA_HANDLE 9
667#define RADEON_PARAM_GART_TEX_HANDLE 10
668#define RADEON_PARAM_SCRATCH_OFFSET 11
669#define RADEON_PARAM_CARD_TYPE 12
670#define RADEON_PARAM_VBLANK_CRTC 13 /* VBLANK CRTC */
671#define RADEON_PARAM_FB_LOCATION 14 /* FB location */
672
673typedef struct drm_radeon_getparam {
674 int param;
675 void __user *value;
676} drm_radeon_getparam_t;
677
678/* 1.6: Set up a memory manager for regions of shared memory:
679 */
680#define RADEON_MEM_REGION_GART 1
681#define RADEON_MEM_REGION_FB 2
682
683typedef struct drm_radeon_mem_alloc {
684 int region;
685 int alignment;
686 int size;
687 int __user *region_offset; /* offset from start of fb or GART */
688} drm_radeon_mem_alloc_t;
689
690typedef struct drm_radeon_mem_free {
691 int region;
692 int region_offset;
693} drm_radeon_mem_free_t;
694
695typedef struct drm_radeon_mem_init_heap {
696 int region;
697 int size;
698 int start;
699} drm_radeon_mem_init_heap_t;
700
701/* 1.6: Userspace can request & wait on irq's:
702 */
703typedef struct drm_radeon_irq_emit {
704 int __user *irq_seq;
705} drm_radeon_irq_emit_t;
706
707typedef struct drm_radeon_irq_wait {
708 int irq_seq;
709} drm_radeon_irq_wait_t;
710
711/* 1.10: Clients tell the DRM where they think the framebuffer is located in
712 * the card's address space, via a new generic ioctl to set parameters
713 */
714
715typedef struct drm_radeon_setparam {
716 unsigned int param;
717 int64_t value;
718} drm_radeon_setparam_t;
719
720#define RADEON_SETPARAM_FB_LOCATION 1 /* determined framebuffer location */
721#define RADEON_SETPARAM_SWITCH_TILING 2 /* enable/disable color tiling */
722#define RADEON_SETPARAM_PCIGART_LOCATION 3 /* PCI Gart Location */
723#define RADEON_SETPARAM_NEW_MEMMAP 4 /* Use new memory map */
724#define RADEON_SETPARAM_PCIGART_TABLE_SIZE 5 /* PCI GART Table Size */
725#define RADEON_SETPARAM_VBLANK_CRTC 6 /* VBLANK CRTC */
726/* 1.14: Clients can allocate/free a surface
727 */
728typedef struct drm_radeon_surface_alloc {
729 unsigned int address;
730 unsigned int size;
731 unsigned int flags;
732} drm_radeon_surface_alloc_t;
733
734typedef struct drm_radeon_surface_free {
735 unsigned int address;
736} drm_radeon_surface_free_t;
737
738#define DRM_RADEON_VBLANK_CRTC1 1
739#define DRM_RADEON_VBLANK_CRTC2 2
740
741#endif
diff --git a/drivers/char/drm/radeon_drv.c b/drivers/char/drm/radeon_drv.c
deleted file mode 100644
index a2610319624d..000000000000
--- a/drivers/char/drm/radeon_drv.c
+++ /dev/null
@@ -1,126 +0,0 @@
1/**
2 * \file radeon_drv.c
3 * ATI Radeon driver
4 *
5 * \author Gareth Hughes <gareth@valinux.com>
6 */
7
8/*
9 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
10 * All Rights Reserved.
11 *
12 * Permission is hereby granted, free of charge, to any person obtaining a
13 * copy of this software and associated documentation files (the "Software"),
14 * to deal in the Software without restriction, including without limitation
15 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
16 * and/or sell copies of the Software, and to permit persons to whom the
17 * Software is furnished to do so, subject to the following conditions:
18 *
19 * The above copyright notice and this permission notice (including the next
20 * paragraph) shall be included in all copies or substantial portions of the
21 * Software.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
27 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
28 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
29 * OTHER DEALINGS IN THE SOFTWARE.
30 */
31
32#include "drmP.h"
33#include "drm.h"
34#include "radeon_drm.h"
35#include "radeon_drv.h"
36
37#include "drm_pciids.h"
38
39int radeon_no_wb;
40
41MODULE_PARM_DESC(no_wb, "Disable AGP writeback for scratch registers\n");
42module_param_named(no_wb, radeon_no_wb, int, 0444);
43
44static int dri_library_name(struct drm_device *dev, char *buf)
45{
46 drm_radeon_private_t *dev_priv = dev->dev_private;
47 int family = dev_priv->flags & RADEON_FAMILY_MASK;
48
49 return snprintf(buf, PAGE_SIZE, "%s\n",
50 (family < CHIP_R200) ? "radeon" :
51 ((family < CHIP_R300) ? "r200" :
52 "r300"));
53}
54
55static struct pci_device_id pciidlist[] = {
56 radeon_PCI_IDS
57};
58
59static struct drm_driver driver = {
60 .driver_features =
61 DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_PCI_DMA | DRIVER_SG |
62 DRIVER_HAVE_IRQ | DRIVER_HAVE_DMA | DRIVER_IRQ_SHARED,
63 .dev_priv_size = sizeof(drm_radeon_buf_priv_t),
64 .load = radeon_driver_load,
65 .firstopen = radeon_driver_firstopen,
66 .open = radeon_driver_open,
67 .preclose = radeon_driver_preclose,
68 .postclose = radeon_driver_postclose,
69 .lastclose = radeon_driver_lastclose,
70 .unload = radeon_driver_unload,
71 .get_vblank_counter = radeon_get_vblank_counter,
72 .enable_vblank = radeon_enable_vblank,
73 .disable_vblank = radeon_disable_vblank,
74 .dri_library_name = dri_library_name,
75 .irq_preinstall = radeon_driver_irq_preinstall,
76 .irq_postinstall = radeon_driver_irq_postinstall,
77 .irq_uninstall = radeon_driver_irq_uninstall,
78 .irq_handler = radeon_driver_irq_handler,
79 .reclaim_buffers = drm_core_reclaim_buffers,
80 .get_map_ofs = drm_core_get_map_ofs,
81 .get_reg_ofs = drm_core_get_reg_ofs,
82 .ioctls = radeon_ioctls,
83 .dma_ioctl = radeon_cp_buffers,
84 .fops = {
85 .owner = THIS_MODULE,
86 .open = drm_open,
87 .release = drm_release,
88 .ioctl = drm_ioctl,
89 .mmap = drm_mmap,
90 .poll = drm_poll,
91 .fasync = drm_fasync,
92#ifdef CONFIG_COMPAT
93 .compat_ioctl = radeon_compat_ioctl,
94#endif
95 },
96
97 .pci_driver = {
98 .name = DRIVER_NAME,
99 .id_table = pciidlist,
100 },
101
102 .name = DRIVER_NAME,
103 .desc = DRIVER_DESC,
104 .date = DRIVER_DATE,
105 .major = DRIVER_MAJOR,
106 .minor = DRIVER_MINOR,
107 .patchlevel = DRIVER_PATCHLEVEL,
108};
109
110static int __init radeon_init(void)
111{
112 driver.num_ioctls = radeon_max_ioctl;
113 return drm_init(&driver);
114}
115
116static void __exit radeon_exit(void)
117{
118 drm_exit(&driver);
119}
120
121module_init(radeon_init);
122module_exit(radeon_exit);
123
124MODULE_AUTHOR(DRIVER_AUTHOR);
125MODULE_DESCRIPTION(DRIVER_DESC);
126MODULE_LICENSE("GPL and additional rights");
diff --git a/drivers/char/drm/radeon_drv.h b/drivers/char/drm/radeon_drv.h
deleted file mode 100644
index b791420bd3d9..000000000000
--- a/drivers/char/drm/radeon_drv.h
+++ /dev/null
@@ -1,1308 +0,0 @@
1/* radeon_drv.h -- Private header for radeon driver -*- linux-c -*-
2 *
3 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
4 * Copyright 2000 VA Linux Systems, Inc., Fremont, California.
5 * All rights reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the next
15 * paragraph) shall be included in all copies or substantial portions of the
16 * Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
22 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 * DEALINGS IN THE SOFTWARE.
25 *
26 * Authors:
27 * Kevin E. Martin <martin@valinux.com>
28 * Gareth Hughes <gareth@valinux.com>
29 */
30
31#ifndef __RADEON_DRV_H__
32#define __RADEON_DRV_H__
33
34/* General customization:
35 */
36
37#define DRIVER_AUTHOR "Gareth Hughes, Keith Whitwell, others."
38
39#define DRIVER_NAME "radeon"
40#define DRIVER_DESC "ATI Radeon"
41#define DRIVER_DATE "20060524"
42
43/* Interface history:
44 *
45 * 1.1 - ??
46 * 1.2 - Add vertex2 ioctl (keith)
47 * - Add stencil capability to clear ioctl (gareth, keith)
48 * - Increase MAX_TEXTURE_LEVELS (brian)
49 * 1.3 - Add cmdbuf ioctl (keith)
50 * - Add support for new radeon packets (keith)
51 * - Add getparam ioctl (keith)
52 * - Add flip-buffers ioctl, deprecate fullscreen foo (keith).
53 * 1.4 - Add scratch registers to get_param ioctl.
54 * 1.5 - Add r200 packets to cmdbuf ioctl
55 * - Add r200 function to init ioctl
56 * - Add 'scalar2' instruction to cmdbuf
57 * 1.6 - Add static GART memory manager
58 * Add irq handler (won't be turned on unless X server knows to)
59 * Add irq ioctls and irq_active getparam.
60 * Add wait command for cmdbuf ioctl
61 * Add GART offset query for getparam
62 * 1.7 - Add support for cube map registers: R200_PP_CUBIC_FACES_[0..5]
63 * and R200_PP_CUBIC_OFFSET_F1_[0..5].
64 * Added packets R200_EMIT_PP_CUBIC_FACES_[0..5] and
65 * R200_EMIT_PP_CUBIC_OFFSETS_[0..5]. (brian)
66 * 1.8 - Remove need to call cleanup ioctls on last client exit (keith)
67 * Add 'GET' queries for starting additional clients on different VT's.
68 * 1.9 - Add DRM_IOCTL_RADEON_CP_RESUME ioctl.
69 * Add texture rectangle support for r100.
70 * 1.10- Add SETPARAM ioctl; first parameter to set is FB_LOCATION, which
71 * clients use to tell the DRM where they think the framebuffer is
72 * located in the card's address space
73 * 1.11- Add packet R200_EMIT_RB3D_BLENDCOLOR to support GL_EXT_blend_color
74 * and GL_EXT_blend_[func|equation]_separate on r200
75 * 1.12- Add R300 CP microcode support - this just loads the CP on r300
76 * (No 3D support yet - just microcode loading).
77 * 1.13- Add packet R200_EMIT_TCL_POINT_SPRITE_CNTL for ARB_point_parameters
78 * - Add hyperz support, add hyperz flags to clear ioctl.
79 * 1.14- Add support for color tiling
80 * - Add R100/R200 surface allocation/free support
81 * 1.15- Add support for texture micro tiling
82 * - Add support for r100 cube maps
83 * 1.16- Add R200_EMIT_PP_TRI_PERF_CNTL packet to support brilinear
84 * texture filtering on r200
85 * 1.17- Add initial support for R300 (3D).
86 * 1.18- Add support for GL_ATI_fragment_shader, new packets
87 * R200_EMIT_PP_AFS_0/1, R200_EMIT_PP_TXCTLALL_0-5 (replaces
88 * R200_EMIT_PP_TXFILTER_0-5, 2 more regs) and R200_EMIT_ATF_TFACTOR
89 * (replaces R200_EMIT_TFACTOR_0 (8 consts instead of 6)
90 * 1.19- Add support for gart table in FB memory and PCIE r300
91 * 1.20- Add support for r300 texrect
92 * 1.21- Add support for card type getparam
93 * 1.22- Add support for texture cache flushes (R300_TX_CNTL)
94 * 1.23- Add new radeon memory map work from benh
95 * 1.24- Add general-purpose packet for manipulating scratch registers (r300)
96 * 1.25- Add support for r200 vertex programs (R200_EMIT_VAP_PVS_CNTL,
97 * new packet type)
98 * 1.26- Add support for variable size PCI(E) gart aperture
99 * 1.27- Add support for IGP GART
100 * 1.28- Add support for VBL on CRTC2
101 */
102#define DRIVER_MAJOR 1
103#define DRIVER_MINOR 28
104#define DRIVER_PATCHLEVEL 0
105
106/*
107 * Radeon chip families
108 */
109enum radeon_family {
110 CHIP_R100,
111 CHIP_RV100,
112 CHIP_RS100,
113 CHIP_RV200,
114 CHIP_RS200,
115 CHIP_R200,
116 CHIP_RV250,
117 CHIP_RS300,
118 CHIP_RV280,
119 CHIP_R300,
120 CHIP_R350,
121 CHIP_RV350,
122 CHIP_RV380,
123 CHIP_R420,
124 CHIP_RV410,
125 CHIP_RS400,
126 CHIP_RS690,
127 CHIP_RV515,
128 CHIP_R520,
129 CHIP_RV530,
130 CHIP_RV560,
131 CHIP_RV570,
132 CHIP_R580,
133 CHIP_LAST,
134};
135
136enum radeon_cp_microcode_version {
137 UCODE_R100,
138 UCODE_R200,
139 UCODE_R300,
140};
141
142/*
143 * Chip flags
144 */
145enum radeon_chip_flags {
146 RADEON_FAMILY_MASK = 0x0000ffffUL,
147 RADEON_FLAGS_MASK = 0xffff0000UL,
148 RADEON_IS_MOBILITY = 0x00010000UL,
149 RADEON_IS_IGP = 0x00020000UL,
150 RADEON_SINGLE_CRTC = 0x00040000UL,
151 RADEON_IS_AGP = 0x00080000UL,
152 RADEON_HAS_HIERZ = 0x00100000UL,
153 RADEON_IS_PCIE = 0x00200000UL,
154 RADEON_NEW_MEMMAP = 0x00400000UL,
155 RADEON_IS_PCI = 0x00800000UL,
156 RADEON_IS_IGPGART = 0x01000000UL,
157};
158
159#define GET_RING_HEAD(dev_priv) (dev_priv->writeback_works ? \
160 DRM_READ32( (dev_priv)->ring_rptr, 0 ) : RADEON_READ(RADEON_CP_RB_RPTR))
161#define SET_RING_HEAD(dev_priv,val) DRM_WRITE32( (dev_priv)->ring_rptr, 0, (val) )
162
163typedef struct drm_radeon_freelist {
164 unsigned int age;
165 struct drm_buf *buf;
166 struct drm_radeon_freelist *next;
167 struct drm_radeon_freelist *prev;
168} drm_radeon_freelist_t;
169
170typedef struct drm_radeon_ring_buffer {
171 u32 *start;
172 u32 *end;
173 int size;
174 int size_l2qw;
175
176 int rptr_update; /* Double Words */
177 int rptr_update_l2qw; /* log2 Quad Words */
178
179 int fetch_size; /* Double Words */
180 int fetch_size_l2ow; /* log2 Oct Words */
181
182 u32 tail;
183 u32 tail_mask;
184 int space;
185
186 int high_mark;
187} drm_radeon_ring_buffer_t;
188
189typedef struct drm_radeon_depth_clear_t {
190 u32 rb3d_cntl;
191 u32 rb3d_zstencilcntl;
192 u32 se_cntl;
193} drm_radeon_depth_clear_t;
194
195struct drm_radeon_driver_file_fields {
196 int64_t radeon_fb_delta;
197};
198
199struct mem_block {
200 struct mem_block *next;
201 struct mem_block *prev;
202 int start;
203 int size;
204 struct drm_file *file_priv; /* NULL: free, -1: heap, other: real files */
205};
206
207struct radeon_surface {
208 int refcount;
209 u32 lower;
210 u32 upper;
211 u32 flags;
212};
213
214struct radeon_virt_surface {
215 int surface_index;
216 u32 lower;
217 u32 upper;
218 u32 flags;
219 struct drm_file *file_priv;
220};
221
222typedef struct drm_radeon_private {
223 drm_radeon_ring_buffer_t ring;
224 drm_radeon_sarea_t *sarea_priv;
225
226 u32 fb_location;
227 u32 fb_size;
228 int new_memmap;
229
230 int gart_size;
231 u32 gart_vm_start;
232 unsigned long gart_buffers_offset;
233
234 int cp_mode;
235 int cp_running;
236
237 drm_radeon_freelist_t *head;
238 drm_radeon_freelist_t *tail;
239 int last_buf;
240 volatile u32 *scratch;
241 int writeback_works;
242
243 int usec_timeout;
244
245 int microcode_version;
246
247 struct {
248 u32 boxes;
249 int freelist_timeouts;
250 int freelist_loops;
251 int requested_bufs;
252 int last_frame_reads;
253 int last_clear_reads;
254 int clears;
255 int texture_uploads;
256 } stats;
257
258 int do_boxes;
259 int page_flipping;
260
261 u32 color_fmt;
262 unsigned int front_offset;
263 unsigned int front_pitch;
264 unsigned int back_offset;
265 unsigned int back_pitch;
266
267 u32 depth_fmt;
268 unsigned int depth_offset;
269 unsigned int depth_pitch;
270
271 u32 front_pitch_offset;
272 u32 back_pitch_offset;
273 u32 depth_pitch_offset;
274
275 drm_radeon_depth_clear_t depth_clear;
276
277 unsigned long ring_offset;
278 unsigned long ring_rptr_offset;
279 unsigned long buffers_offset;
280 unsigned long gart_textures_offset;
281
282 drm_local_map_t *sarea;
283 drm_local_map_t *mmio;
284 drm_local_map_t *cp_ring;
285 drm_local_map_t *ring_rptr;
286 drm_local_map_t *gart_textures;
287
288 struct mem_block *gart_heap;
289 struct mem_block *fb_heap;
290
291 /* SW interrupt */
292 wait_queue_head_t swi_queue;
293 atomic_t swi_emitted;
294 int vblank_crtc;
295 uint32_t irq_enable_reg;
296 int irq_enabled;
297
298 struct radeon_surface surfaces[RADEON_MAX_SURFACES];
299 struct radeon_virt_surface virt_surfaces[2 * RADEON_MAX_SURFACES];
300
301 unsigned long pcigart_offset;
302 unsigned int pcigart_offset_set;
303 struct drm_ati_pcigart_info gart_info;
304
305 u32 scratch_ages[5];
306
307 unsigned int crtc_last_cnt;
308 unsigned int crtc2_last_cnt;
309
310 /* starting from here on, data is preserved accross an open */
311 uint32_t flags; /* see radeon_chip_flags */
312 unsigned long fb_aper_offset;
313} drm_radeon_private_t;
314
315typedef struct drm_radeon_buf_priv {
316 u32 age;
317} drm_radeon_buf_priv_t;
318
319typedef struct drm_radeon_kcmd_buffer {
320 int bufsz;
321 char *buf;
322 int nbox;
323 struct drm_clip_rect __user *boxes;
324} drm_radeon_kcmd_buffer_t;
325
326extern int radeon_no_wb;
327extern struct drm_ioctl_desc radeon_ioctls[];
328extern int radeon_max_ioctl;
329
330/* Check whether the given hardware address is inside the framebuffer or the
331 * GART area.
332 */
333static __inline__ int radeon_check_offset(drm_radeon_private_t *dev_priv,
334 u64 off)
335{
336 u32 fb_start = dev_priv->fb_location;
337 u32 fb_end = fb_start + dev_priv->fb_size - 1;
338 u32 gart_start = dev_priv->gart_vm_start;
339 u32 gart_end = gart_start + dev_priv->gart_size - 1;
340
341 return ((off >= fb_start && off <= fb_end) ||
342 (off >= gart_start && off <= gart_end));
343}
344
345 /* radeon_cp.c */
346extern int radeon_cp_init(struct drm_device *dev, void *data, struct drm_file *file_priv);
347extern int radeon_cp_start(struct drm_device *dev, void *data, struct drm_file *file_priv);
348extern int radeon_cp_stop(struct drm_device *dev, void *data, struct drm_file *file_priv);
349extern int radeon_cp_reset(struct drm_device *dev, void *data, struct drm_file *file_priv);
350extern int radeon_cp_idle(struct drm_device *dev, void *data, struct drm_file *file_priv);
351extern int radeon_cp_resume(struct drm_device *dev, void *data, struct drm_file *file_priv);
352extern int radeon_engine_reset(struct drm_device *dev, void *data, struct drm_file *file_priv);
353extern int radeon_fullscreen(struct drm_device *dev, void *data, struct drm_file *file_priv);
354extern int radeon_cp_buffers(struct drm_device *dev, void *data, struct drm_file *file_priv);
355extern u32 radeon_read_fb_location(drm_radeon_private_t *dev_priv);
356
357extern void radeon_freelist_reset(struct drm_device * dev);
358extern struct drm_buf *radeon_freelist_get(struct drm_device * dev);
359
360extern int radeon_wait_ring(drm_radeon_private_t * dev_priv, int n);
361
362extern int radeon_do_cp_idle(drm_radeon_private_t * dev_priv);
363
364extern int radeon_driver_preinit(struct drm_device *dev, unsigned long flags);
365extern int radeon_presetup(struct drm_device *dev);
366extern int radeon_driver_postcleanup(struct drm_device *dev);
367
368extern int radeon_mem_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv);
369extern int radeon_mem_free(struct drm_device *dev, void *data, struct drm_file *file_priv);
370extern int radeon_mem_init_heap(struct drm_device *dev, void *data, struct drm_file *file_priv);
371extern void radeon_mem_takedown(struct mem_block **heap);
372extern void radeon_mem_release(struct drm_file *file_priv,
373 struct mem_block *heap);
374
375 /* radeon_irq.c */
376extern int radeon_irq_emit(struct drm_device *dev, void *data, struct drm_file *file_priv);
377extern int radeon_irq_wait(struct drm_device *dev, void *data, struct drm_file *file_priv);
378
379extern void radeon_do_release(struct drm_device * dev);
380extern u32 radeon_get_vblank_counter(struct drm_device *dev, int crtc);
381extern int radeon_enable_vblank(struct drm_device *dev, int crtc);
382extern void radeon_disable_vblank(struct drm_device *dev, int crtc);
383extern void radeon_do_release(struct drm_device * dev);
384extern irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS);
385extern void radeon_driver_irq_preinstall(struct drm_device * dev);
386extern int radeon_driver_irq_postinstall(struct drm_device * dev);
387extern void radeon_driver_irq_uninstall(struct drm_device * dev);
388extern int radeon_vblank_crtc_get(struct drm_device *dev);
389extern int radeon_vblank_crtc_set(struct drm_device *dev, int64_t value);
390
391extern int radeon_driver_load(struct drm_device *dev, unsigned long flags);
392extern int radeon_driver_unload(struct drm_device *dev);
393extern int radeon_driver_firstopen(struct drm_device *dev);
394extern void radeon_driver_preclose(struct drm_device * dev, struct drm_file *file_priv);
395extern void radeon_driver_postclose(struct drm_device * dev, struct drm_file * filp);
396extern void radeon_driver_lastclose(struct drm_device * dev);
397extern int radeon_driver_open(struct drm_device * dev, struct drm_file * filp_priv);
398extern long radeon_compat_ioctl(struct file *filp, unsigned int cmd,
399 unsigned long arg);
400
401/* r300_cmdbuf.c */
402extern void r300_init_reg_flags(struct drm_device *dev);
403
404extern int r300_do_cp_cmdbuf(struct drm_device * dev,
405 struct drm_file *file_priv,
406 drm_radeon_kcmd_buffer_t * cmdbuf);
407
408/* Flags for stats.boxes
409 */
410#define RADEON_BOX_DMA_IDLE 0x1
411#define RADEON_BOX_RING_FULL 0x2
412#define RADEON_BOX_FLIP 0x4
413#define RADEON_BOX_WAIT_IDLE 0x8
414#define RADEON_BOX_TEXTURE_LOAD 0x10
415
416/* Register definitions, register access macros and drmAddMap constants
417 * for Radeon kernel driver.
418 */
419
420#define RADEON_AGP_COMMAND 0x0f60
421#define RADEON_AGP_COMMAND_PCI_CONFIG 0x0060 /* offset in PCI config */
422# define RADEON_AGP_ENABLE (1<<8)
423#define RADEON_AUX_SCISSOR_CNTL 0x26f0
424# define RADEON_EXCLUSIVE_SCISSOR_0 (1 << 24)
425# define RADEON_EXCLUSIVE_SCISSOR_1 (1 << 25)
426# define RADEON_EXCLUSIVE_SCISSOR_2 (1 << 26)
427# define RADEON_SCISSOR_0_ENABLE (1 << 28)
428# define RADEON_SCISSOR_1_ENABLE (1 << 29)
429# define RADEON_SCISSOR_2_ENABLE (1 << 30)
430
431#define RADEON_BUS_CNTL 0x0030
432# define RADEON_BUS_MASTER_DIS (1 << 6)
433
434#define RADEON_CLOCK_CNTL_DATA 0x000c
435# define RADEON_PLL_WR_EN (1 << 7)
436#define RADEON_CLOCK_CNTL_INDEX 0x0008
437#define RADEON_CONFIG_APER_SIZE 0x0108
438#define RADEON_CONFIG_MEMSIZE 0x00f8
439#define RADEON_CRTC_OFFSET 0x0224
440#define RADEON_CRTC_OFFSET_CNTL 0x0228
441# define RADEON_CRTC_TILE_EN (1 << 15)
442# define RADEON_CRTC_OFFSET_FLIP_CNTL (1 << 16)
443#define RADEON_CRTC2_OFFSET 0x0324
444#define RADEON_CRTC2_OFFSET_CNTL 0x0328
445
446#define RADEON_PCIE_INDEX 0x0030
447#define RADEON_PCIE_DATA 0x0034
448#define RADEON_PCIE_TX_GART_CNTL 0x10
449# define RADEON_PCIE_TX_GART_EN (1 << 0)
450# define RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_PASS_THRU (0<<1)
451# define RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_CLAMP_LO (1<<1)
452# define RADEON_PCIE_TX_GART_UNMAPPED_ACCESS_DISCARD (3<<1)
453# define RADEON_PCIE_TX_GART_MODE_32_128_CACHE (0<<3)
454# define RADEON_PCIE_TX_GART_MODE_8_4_128_CACHE (1<<3)
455# define RADEON_PCIE_TX_GART_CHK_RW_VALID_EN (1<<5)
456# define RADEON_PCIE_TX_GART_INVALIDATE_TLB (1<<8)
457#define RADEON_PCIE_TX_DISCARD_RD_ADDR_LO 0x11
458#define RADEON_PCIE_TX_DISCARD_RD_ADDR_HI 0x12
459#define RADEON_PCIE_TX_GART_BASE 0x13
460#define RADEON_PCIE_TX_GART_START_LO 0x14
461#define RADEON_PCIE_TX_GART_START_HI 0x15
462#define RADEON_PCIE_TX_GART_END_LO 0x16
463#define RADEON_PCIE_TX_GART_END_HI 0x17
464
465#define RADEON_IGPGART_INDEX 0x168
466#define RADEON_IGPGART_DATA 0x16c
467#define RADEON_IGPGART_UNK_18 0x18
468#define RADEON_IGPGART_CTRL 0x2b
469#define RADEON_IGPGART_BASE_ADDR 0x2c
470#define RADEON_IGPGART_FLUSH 0x2e
471#define RADEON_IGPGART_ENABLE 0x38
472#define RADEON_IGPGART_UNK_39 0x39
473
474#define RS690_MC_INDEX 0x78
475# define RS690_MC_INDEX_MASK 0x1ff
476# define RS690_MC_INDEX_WR_EN (1 << 9)
477# define RS690_MC_INDEX_WR_ACK 0x7f
478#define RS690_MC_DATA 0x7c
479
480#define RS690_MC_MISC_CNTL 0x18
481#define RS690_MC_GART_FEATURE_ID 0x2b
482#define RS690_MC_GART_BASE 0x2c
483#define RS690_MC_GART_CACHE_CNTL 0x2e
484# define RS690_MC_GART_CC_NO_CHANGE 0x0
485# define RS690_MC_GART_CC_CLEAR 0x1
486# define RS690_MC_GART_CLEAR_STATUS (1 << 1)
487# define RS690_MC_GART_CLEAR_DONE (0 << 1)
488# define RS690_MC_GART_CLEAR_PENDING (1 << 1)
489#define RS690_MC_AGP_SIZE 0x38
490# define RS690_MC_GART_DIS 0x0
491# define RS690_MC_GART_EN 0x1
492# define RS690_MC_AGP_SIZE_32MB (0 << 1)
493# define RS690_MC_AGP_SIZE_64MB (1 << 1)
494# define RS690_MC_AGP_SIZE_128MB (2 << 1)
495# define RS690_MC_AGP_SIZE_256MB (3 << 1)
496# define RS690_MC_AGP_SIZE_512MB (4 << 1)
497# define RS690_MC_AGP_SIZE_1GB (5 << 1)
498# define RS690_MC_AGP_SIZE_2GB (6 << 1)
499#define RS690_MC_AGP_MODE_CONTROL 0x39
500#define RS690_MC_FB_LOCATION 0x100
501#define RS690_MC_AGP_LOCATION 0x101
502#define RS690_MC_AGP_BASE 0x102
503
504#define R520_MC_IND_INDEX 0x70
505#define R520_MC_IND_WR_EN (1<<24)
506#define R520_MC_IND_DATA 0x74
507
508#define RV515_MC_FB_LOCATION 0x01
509#define RV515_MC_AGP_LOCATION 0x02
510
511#define R520_MC_FB_LOCATION 0x04
512#define R520_MC_AGP_LOCATION 0x05
513
514#define RADEON_MPP_TB_CONFIG 0x01c0
515#define RADEON_MEM_CNTL 0x0140
516#define RADEON_MEM_SDRAM_MODE_REG 0x0158
517#define RADEON_AGP_BASE 0x0170
518
519#define RADEON_RB3D_COLOROFFSET 0x1c40
520#define RADEON_RB3D_COLORPITCH 0x1c48
521
522#define RADEON_SRC_X_Y 0x1590
523
524#define RADEON_DP_GUI_MASTER_CNTL 0x146c
525# define RADEON_GMC_SRC_PITCH_OFFSET_CNTL (1 << 0)
526# define RADEON_GMC_DST_PITCH_OFFSET_CNTL (1 << 1)
527# define RADEON_GMC_BRUSH_SOLID_COLOR (13 << 4)
528# define RADEON_GMC_BRUSH_NONE (15 << 4)
529# define RADEON_GMC_DST_16BPP (4 << 8)
530# define RADEON_GMC_DST_24BPP (5 << 8)
531# define RADEON_GMC_DST_32BPP (6 << 8)
532# define RADEON_GMC_DST_DATATYPE_SHIFT 8
533# define RADEON_GMC_SRC_DATATYPE_COLOR (3 << 12)
534# define RADEON_DP_SRC_SOURCE_MEMORY (2 << 24)
535# define RADEON_DP_SRC_SOURCE_HOST_DATA (3 << 24)
536# define RADEON_GMC_CLR_CMP_CNTL_DIS (1 << 28)
537# define RADEON_GMC_WR_MSK_DIS (1 << 30)
538# define RADEON_ROP3_S 0x00cc0000
539# define RADEON_ROP3_P 0x00f00000
540#define RADEON_DP_WRITE_MASK 0x16cc
541#define RADEON_SRC_PITCH_OFFSET 0x1428
542#define RADEON_DST_PITCH_OFFSET 0x142c
543#define RADEON_DST_PITCH_OFFSET_C 0x1c80
544# define RADEON_DST_TILE_LINEAR (0 << 30)
545# define RADEON_DST_TILE_MACRO (1 << 30)
546# define RADEON_DST_TILE_MICRO (2 << 30)
547# define RADEON_DST_TILE_BOTH (3 << 30)
548
549#define RADEON_SCRATCH_REG0 0x15e0
550#define RADEON_SCRATCH_REG1 0x15e4
551#define RADEON_SCRATCH_REG2 0x15e8
552#define RADEON_SCRATCH_REG3 0x15ec
553#define RADEON_SCRATCH_REG4 0x15f0
554#define RADEON_SCRATCH_REG5 0x15f4
555#define RADEON_SCRATCH_UMSK 0x0770
556#define RADEON_SCRATCH_ADDR 0x0774
557
558#define RADEON_SCRATCHOFF( x ) (RADEON_SCRATCH_REG_OFFSET + 4*(x))
559
560#define GET_SCRATCH( x ) (dev_priv->writeback_works \
561 ? DRM_READ32( dev_priv->ring_rptr, RADEON_SCRATCHOFF(x) ) \
562 : RADEON_READ( RADEON_SCRATCH_REG0 + 4*(x) ) )
563
564#define RADEON_CRTC_CRNT_FRAME 0x0214
565#define RADEON_CRTC2_CRNT_FRAME 0x0314
566
567#define RADEON_CRTC_STATUS 0x005c
568#define RADEON_CRTC2_STATUS 0x03fc
569
570#define RADEON_GEN_INT_CNTL 0x0040
571# define RADEON_CRTC_VBLANK_MASK (1 << 0)
572# define RADEON_CRTC2_VBLANK_MASK (1 << 9)
573# define RADEON_GUI_IDLE_INT_ENABLE (1 << 19)
574# define RADEON_SW_INT_ENABLE (1 << 25)
575
576#define RADEON_GEN_INT_STATUS 0x0044
577# define RADEON_CRTC_VBLANK_STAT (1 << 0)
578# define RADEON_CRTC_VBLANK_STAT_ACK (1 << 0)
579# define RADEON_CRTC2_VBLANK_STAT (1 << 9)
580# define RADEON_CRTC2_VBLANK_STAT_ACK (1 << 9)
581# define RADEON_GUI_IDLE_INT_TEST_ACK (1 << 19)
582# define RADEON_SW_INT_TEST (1 << 25)
583# define RADEON_SW_INT_TEST_ACK (1 << 25)
584# define RADEON_SW_INT_FIRE (1 << 26)
585
586#define RADEON_HOST_PATH_CNTL 0x0130
587# define RADEON_HDP_SOFT_RESET (1 << 26)
588# define RADEON_HDP_WC_TIMEOUT_MASK (7 << 28)
589# define RADEON_HDP_WC_TIMEOUT_28BCLK (7 << 28)
590
591#define RADEON_ISYNC_CNTL 0x1724
592# define RADEON_ISYNC_ANY2D_IDLE3D (1 << 0)
593# define RADEON_ISYNC_ANY3D_IDLE2D (1 << 1)
594# define RADEON_ISYNC_TRIG2D_IDLE3D (1 << 2)
595# define RADEON_ISYNC_TRIG3D_IDLE2D (1 << 3)
596# define RADEON_ISYNC_WAIT_IDLEGUI (1 << 4)
597# define RADEON_ISYNC_CPSCRATCH_IDLEGUI (1 << 5)
598
599#define RADEON_RBBM_GUICNTL 0x172c
600# define RADEON_HOST_DATA_SWAP_NONE (0 << 0)
601# define RADEON_HOST_DATA_SWAP_16BIT (1 << 0)
602# define RADEON_HOST_DATA_SWAP_32BIT (2 << 0)
603# define RADEON_HOST_DATA_SWAP_HDW (3 << 0)
604
605#define RADEON_MC_AGP_LOCATION 0x014c
606#define RADEON_MC_FB_LOCATION 0x0148
607#define RADEON_MCLK_CNTL 0x0012
608# define RADEON_FORCEON_MCLKA (1 << 16)
609# define RADEON_FORCEON_MCLKB (1 << 17)
610# define RADEON_FORCEON_YCLKA (1 << 18)
611# define RADEON_FORCEON_YCLKB (1 << 19)
612# define RADEON_FORCEON_MC (1 << 20)
613# define RADEON_FORCEON_AIC (1 << 21)
614
615#define RADEON_PP_BORDER_COLOR_0 0x1d40
616#define RADEON_PP_BORDER_COLOR_1 0x1d44
617#define RADEON_PP_BORDER_COLOR_2 0x1d48
618#define RADEON_PP_CNTL 0x1c38
619# define RADEON_SCISSOR_ENABLE (1 << 1)
620#define RADEON_PP_LUM_MATRIX 0x1d00
621#define RADEON_PP_MISC 0x1c14
622#define RADEON_PP_ROT_MATRIX_0 0x1d58
623#define RADEON_PP_TXFILTER_0 0x1c54
624#define RADEON_PP_TXOFFSET_0 0x1c5c
625#define RADEON_PP_TXFILTER_1 0x1c6c
626#define RADEON_PP_TXFILTER_2 0x1c84
627
628#define RADEON_RB2D_DSTCACHE_CTLSTAT 0x342c
629# define RADEON_RB2D_DC_FLUSH (3 << 0)
630# define RADEON_RB2D_DC_FREE (3 << 2)
631# define RADEON_RB2D_DC_FLUSH_ALL 0xf
632# define RADEON_RB2D_DC_BUSY (1 << 31)
633#define RADEON_RB3D_CNTL 0x1c3c
634# define RADEON_ALPHA_BLEND_ENABLE (1 << 0)
635# define RADEON_PLANE_MASK_ENABLE (1 << 1)
636# define RADEON_DITHER_ENABLE (1 << 2)
637# define RADEON_ROUND_ENABLE (1 << 3)
638# define RADEON_SCALE_DITHER_ENABLE (1 << 4)
639# define RADEON_DITHER_INIT (1 << 5)
640# define RADEON_ROP_ENABLE (1 << 6)
641# define RADEON_STENCIL_ENABLE (1 << 7)
642# define RADEON_Z_ENABLE (1 << 8)
643# define RADEON_ZBLOCK16 (1 << 15)
644#define RADEON_RB3D_DEPTHOFFSET 0x1c24
645#define RADEON_RB3D_DEPTHCLEARVALUE 0x3230
646#define RADEON_RB3D_DEPTHPITCH 0x1c28
647#define RADEON_RB3D_PLANEMASK 0x1d84
648#define RADEON_RB3D_STENCILREFMASK 0x1d7c
649#define RADEON_RB3D_ZCACHE_MODE 0x3250
650#define RADEON_RB3D_ZCACHE_CTLSTAT 0x3254
651# define RADEON_RB3D_ZC_FLUSH (1 << 0)
652# define RADEON_RB3D_ZC_FREE (1 << 2)
653# define RADEON_RB3D_ZC_FLUSH_ALL 0x5
654# define RADEON_RB3D_ZC_BUSY (1 << 31)
655#define RADEON_RB3D_DSTCACHE_CTLSTAT 0x325c
656# define RADEON_RB3D_DC_FLUSH (3 << 0)
657# define RADEON_RB3D_DC_FREE (3 << 2)
658# define RADEON_RB3D_DC_FLUSH_ALL 0xf
659# define RADEON_RB3D_DC_BUSY (1 << 31)
660#define RADEON_RB3D_ZSTENCILCNTL 0x1c2c
661# define RADEON_Z_TEST_MASK (7 << 4)
662# define RADEON_Z_TEST_ALWAYS (7 << 4)
663# define RADEON_Z_HIERARCHY_ENABLE (1 << 8)
664# define RADEON_STENCIL_TEST_ALWAYS (7 << 12)
665# define RADEON_STENCIL_S_FAIL_REPLACE (2 << 16)
666# define RADEON_STENCIL_ZPASS_REPLACE (2 << 20)
667# define RADEON_STENCIL_ZFAIL_REPLACE (2 << 24)
668# define RADEON_Z_COMPRESSION_ENABLE (1 << 28)
669# define RADEON_FORCE_Z_DIRTY (1 << 29)
670# define RADEON_Z_WRITE_ENABLE (1 << 30)
671# define RADEON_Z_DECOMPRESSION_ENABLE (1 << 31)
672#define RADEON_RBBM_SOFT_RESET 0x00f0
673# define RADEON_SOFT_RESET_CP (1 << 0)
674# define RADEON_SOFT_RESET_HI (1 << 1)
675# define RADEON_SOFT_RESET_SE (1 << 2)
676# define RADEON_SOFT_RESET_RE (1 << 3)
677# define RADEON_SOFT_RESET_PP (1 << 4)
678# define RADEON_SOFT_RESET_E2 (1 << 5)
679# define RADEON_SOFT_RESET_RB (1 << 6)
680# define RADEON_SOFT_RESET_HDP (1 << 7)
681/*
682 * 6:0 Available slots in the FIFO
683 * 8 Host Interface active
684 * 9 CP request active
685 * 10 FIFO request active
686 * 11 Host Interface retry active
687 * 12 CP retry active
688 * 13 FIFO retry active
689 * 14 FIFO pipeline busy
690 * 15 Event engine busy
691 * 16 CP command stream busy
692 * 17 2D engine busy
693 * 18 2D portion of render backend busy
694 * 20 3D setup engine busy
695 * 26 GA engine busy
696 * 27 CBA 2D engine busy
697 * 31 2D engine busy or 3D engine busy or FIFO not empty or CP busy or
698 * command stream queue not empty or Ring Buffer not empty
699 */
700#define RADEON_RBBM_STATUS 0x0e40
701/* Same as the previous RADEON_RBBM_STATUS; this is a mirror of that register. */
702/* #define RADEON_RBBM_STATUS 0x1740 */
703/* bits 6:0 are dword slots available in the cmd fifo */
704# define RADEON_RBBM_FIFOCNT_MASK 0x007f
705# define RADEON_HIRQ_ON_RBB (1 << 8)
706# define RADEON_CPRQ_ON_RBB (1 << 9)
707# define RADEON_CFRQ_ON_RBB (1 << 10)
708# define RADEON_HIRQ_IN_RTBUF (1 << 11)
709# define RADEON_CPRQ_IN_RTBUF (1 << 12)
710# define RADEON_CFRQ_IN_RTBUF (1 << 13)
711# define RADEON_PIPE_BUSY (1 << 14)
712# define RADEON_ENG_EV_BUSY (1 << 15)
713# define RADEON_CP_CMDSTRM_BUSY (1 << 16)
714# define RADEON_E2_BUSY (1 << 17)
715# define RADEON_RB2D_BUSY (1 << 18)
716# define RADEON_RB3D_BUSY (1 << 19) /* not used on r300 */
717# define RADEON_VAP_BUSY (1 << 20)
718# define RADEON_RE_BUSY (1 << 21) /* not used on r300 */
719# define RADEON_TAM_BUSY (1 << 22) /* not used on r300 */
720# define RADEON_TDM_BUSY (1 << 23) /* not used on r300 */
721# define RADEON_PB_BUSY (1 << 24) /* not used on r300 */
722# define RADEON_TIM_BUSY (1 << 25) /* not used on r300 */
723# define RADEON_GA_BUSY (1 << 26)
724# define RADEON_CBA2D_BUSY (1 << 27)
725# define RADEON_RBBM_ACTIVE (1 << 31)
726#define RADEON_RE_LINE_PATTERN 0x1cd0
727#define RADEON_RE_MISC 0x26c4
728#define RADEON_RE_TOP_LEFT 0x26c0
729#define RADEON_RE_WIDTH_HEIGHT 0x1c44
730#define RADEON_RE_STIPPLE_ADDR 0x1cc8
731#define RADEON_RE_STIPPLE_DATA 0x1ccc
732
733#define RADEON_SCISSOR_TL_0 0x1cd8
734#define RADEON_SCISSOR_BR_0 0x1cdc
735#define RADEON_SCISSOR_TL_1 0x1ce0
736#define RADEON_SCISSOR_BR_1 0x1ce4
737#define RADEON_SCISSOR_TL_2 0x1ce8
738#define RADEON_SCISSOR_BR_2 0x1cec
739#define RADEON_SE_COORD_FMT 0x1c50
740#define RADEON_SE_CNTL 0x1c4c
741# define RADEON_FFACE_CULL_CW (0 << 0)
742# define RADEON_BFACE_SOLID (3 << 1)
743# define RADEON_FFACE_SOLID (3 << 3)
744# define RADEON_FLAT_SHADE_VTX_LAST (3 << 6)
745# define RADEON_DIFFUSE_SHADE_FLAT (1 << 8)
746# define RADEON_DIFFUSE_SHADE_GOURAUD (2 << 8)
747# define RADEON_ALPHA_SHADE_FLAT (1 << 10)
748# define RADEON_ALPHA_SHADE_GOURAUD (2 << 10)
749# define RADEON_SPECULAR_SHADE_FLAT (1 << 12)
750# define RADEON_SPECULAR_SHADE_GOURAUD (2 << 12)
751# define RADEON_FOG_SHADE_FLAT (1 << 14)
752# define RADEON_FOG_SHADE_GOURAUD (2 << 14)
753# define RADEON_VPORT_XY_XFORM_ENABLE (1 << 24)
754# define RADEON_VPORT_Z_XFORM_ENABLE (1 << 25)
755# define RADEON_VTX_PIX_CENTER_OGL (1 << 27)
756# define RADEON_ROUND_MODE_TRUNC (0 << 28)
757# define RADEON_ROUND_PREC_8TH_PIX (1 << 30)
758#define RADEON_SE_CNTL_STATUS 0x2140
759#define RADEON_SE_LINE_WIDTH 0x1db8
760#define RADEON_SE_VPORT_XSCALE 0x1d98
761#define RADEON_SE_ZBIAS_FACTOR 0x1db0
762#define RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED 0x2210
763#define RADEON_SE_TCL_OUTPUT_VTX_FMT 0x2254
764#define RADEON_SE_TCL_VECTOR_INDX_REG 0x2200
765# define RADEON_VEC_INDX_OCTWORD_STRIDE_SHIFT 16
766# define RADEON_VEC_INDX_DWORD_COUNT_SHIFT 28
767#define RADEON_SE_TCL_VECTOR_DATA_REG 0x2204
768#define RADEON_SE_TCL_SCALAR_INDX_REG 0x2208
769# define RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT 16
770#define RADEON_SE_TCL_SCALAR_DATA_REG 0x220C
771#define RADEON_SURFACE_ACCESS_FLAGS 0x0bf8
772#define RADEON_SURFACE_ACCESS_CLR 0x0bfc
773#define RADEON_SURFACE_CNTL 0x0b00
774# define RADEON_SURF_TRANSLATION_DIS (1 << 8)
775# define RADEON_NONSURF_AP0_SWP_MASK (3 << 20)
776# define RADEON_NONSURF_AP0_SWP_LITTLE (0 << 20)
777# define RADEON_NONSURF_AP0_SWP_BIG16 (1 << 20)
778# define RADEON_NONSURF_AP0_SWP_BIG32 (2 << 20)
779# define RADEON_NONSURF_AP1_SWP_MASK (3 << 22)
780# define RADEON_NONSURF_AP1_SWP_LITTLE (0 << 22)
781# define RADEON_NONSURF_AP1_SWP_BIG16 (1 << 22)
782# define RADEON_NONSURF_AP1_SWP_BIG32 (2 << 22)
783#define RADEON_SURFACE0_INFO 0x0b0c
784# define RADEON_SURF_PITCHSEL_MASK (0x1ff << 0)
785# define RADEON_SURF_TILE_MODE_MASK (3 << 16)
786# define RADEON_SURF_TILE_MODE_MACRO (0 << 16)
787# define RADEON_SURF_TILE_MODE_MICRO (1 << 16)
788# define RADEON_SURF_TILE_MODE_32BIT_Z (2 << 16)
789# define RADEON_SURF_TILE_MODE_16BIT_Z (3 << 16)
790#define RADEON_SURFACE0_LOWER_BOUND 0x0b04
791#define RADEON_SURFACE0_UPPER_BOUND 0x0b08
792# define RADEON_SURF_ADDRESS_FIXED_MASK (0x3ff << 0)
793#define RADEON_SURFACE1_INFO 0x0b1c
794#define RADEON_SURFACE1_LOWER_BOUND 0x0b14
795#define RADEON_SURFACE1_UPPER_BOUND 0x0b18
796#define RADEON_SURFACE2_INFO 0x0b2c
797#define RADEON_SURFACE2_LOWER_BOUND 0x0b24
798#define RADEON_SURFACE2_UPPER_BOUND 0x0b28
799#define RADEON_SURFACE3_INFO 0x0b3c
800#define RADEON_SURFACE3_LOWER_BOUND 0x0b34
801#define RADEON_SURFACE3_UPPER_BOUND 0x0b38
802#define RADEON_SURFACE4_INFO 0x0b4c
803#define RADEON_SURFACE4_LOWER_BOUND 0x0b44
804#define RADEON_SURFACE4_UPPER_BOUND 0x0b48
805#define RADEON_SURFACE5_INFO 0x0b5c
806#define RADEON_SURFACE5_LOWER_BOUND 0x0b54
807#define RADEON_SURFACE5_UPPER_BOUND 0x0b58
808#define RADEON_SURFACE6_INFO 0x0b6c
809#define RADEON_SURFACE6_LOWER_BOUND 0x0b64
810#define RADEON_SURFACE6_UPPER_BOUND 0x0b68
811#define RADEON_SURFACE7_INFO 0x0b7c
812#define RADEON_SURFACE7_LOWER_BOUND 0x0b74
813#define RADEON_SURFACE7_UPPER_BOUND 0x0b78
814#define RADEON_SW_SEMAPHORE 0x013c
815
816#define RADEON_WAIT_UNTIL 0x1720
817# define RADEON_WAIT_CRTC_PFLIP (1 << 0)
818# define RADEON_WAIT_2D_IDLE (1 << 14)
819# define RADEON_WAIT_3D_IDLE (1 << 15)
820# define RADEON_WAIT_2D_IDLECLEAN (1 << 16)
821# define RADEON_WAIT_3D_IDLECLEAN (1 << 17)
822# define RADEON_WAIT_HOST_IDLECLEAN (1 << 18)
823
824#define RADEON_RB3D_ZMASKOFFSET 0x3234
825#define RADEON_RB3D_ZSTENCILCNTL 0x1c2c
826# define RADEON_DEPTH_FORMAT_16BIT_INT_Z (0 << 0)
827# define RADEON_DEPTH_FORMAT_24BIT_INT_Z (2 << 0)
828
829/* CP registers */
830#define RADEON_CP_ME_RAM_ADDR 0x07d4
831#define RADEON_CP_ME_RAM_RADDR 0x07d8
832#define RADEON_CP_ME_RAM_DATAH 0x07dc
833#define RADEON_CP_ME_RAM_DATAL 0x07e0
834
835#define RADEON_CP_RB_BASE 0x0700
836#define RADEON_CP_RB_CNTL 0x0704
837# define RADEON_BUF_SWAP_32BIT (2 << 16)
838# define RADEON_RB_NO_UPDATE (1 << 27)
839#define RADEON_CP_RB_RPTR_ADDR 0x070c
840#define RADEON_CP_RB_RPTR 0x0710
841#define RADEON_CP_RB_WPTR 0x0714
842
843#define RADEON_CP_RB_WPTR_DELAY 0x0718
844# define RADEON_PRE_WRITE_TIMER_SHIFT 0
845# define RADEON_PRE_WRITE_LIMIT_SHIFT 23
846
847#define RADEON_CP_IB_BASE 0x0738
848
849#define RADEON_CP_CSQ_CNTL 0x0740
850# define RADEON_CSQ_CNT_PRIMARY_MASK (0xff << 0)
851# define RADEON_CSQ_PRIDIS_INDDIS (0 << 28)
852# define RADEON_CSQ_PRIPIO_INDDIS (1 << 28)
853# define RADEON_CSQ_PRIBM_INDDIS (2 << 28)
854# define RADEON_CSQ_PRIPIO_INDBM (3 << 28)
855# define RADEON_CSQ_PRIBM_INDBM (4 << 28)
856# define RADEON_CSQ_PRIPIO_INDPIO (15 << 28)
857
858#define RADEON_AIC_CNTL 0x01d0
859# define RADEON_PCIGART_TRANSLATE_EN (1 << 0)
860#define RADEON_AIC_STAT 0x01d4
861#define RADEON_AIC_PT_BASE 0x01d8
862#define RADEON_AIC_LO_ADDR 0x01dc
863#define RADEON_AIC_HI_ADDR 0x01e0
864#define RADEON_AIC_TLB_ADDR 0x01e4
865#define RADEON_AIC_TLB_DATA 0x01e8
866
867/* CP command packets */
868#define RADEON_CP_PACKET0 0x00000000
869# define RADEON_ONE_REG_WR (1 << 15)
870#define RADEON_CP_PACKET1 0x40000000
871#define RADEON_CP_PACKET2 0x80000000
872#define RADEON_CP_PACKET3 0xC0000000
873# define RADEON_CP_NOP 0x00001000
874# define RADEON_CP_NEXT_CHAR 0x00001900
875# define RADEON_CP_PLY_NEXTSCAN 0x00001D00
876# define RADEON_CP_SET_SCISSORS 0x00001E00
877 /* GEN_INDX_PRIM is unsupported starting with R300 */
878# define RADEON_3D_RNDR_GEN_INDX_PRIM 0x00002300
879# define RADEON_WAIT_FOR_IDLE 0x00002600
880# define RADEON_3D_DRAW_VBUF 0x00002800
881# define RADEON_3D_DRAW_IMMD 0x00002900
882# define RADEON_3D_DRAW_INDX 0x00002A00
883# define RADEON_CP_LOAD_PALETTE 0x00002C00
884# define RADEON_3D_LOAD_VBPNTR 0x00002F00
885# define RADEON_MPEG_IDCT_MACROBLOCK 0x00003000
886# define RADEON_MPEG_IDCT_MACROBLOCK_REV 0x00003100
887# define RADEON_3D_CLEAR_ZMASK 0x00003200
888# define RADEON_CP_INDX_BUFFER 0x00003300
889# define RADEON_CP_3D_DRAW_VBUF_2 0x00003400
890# define RADEON_CP_3D_DRAW_IMMD_2 0x00003500
891# define RADEON_CP_3D_DRAW_INDX_2 0x00003600
892# define RADEON_3D_CLEAR_HIZ 0x00003700
893# define RADEON_CP_3D_CLEAR_CMASK 0x00003802
894# define RADEON_CNTL_HOSTDATA_BLT 0x00009400
895# define RADEON_CNTL_PAINT_MULTI 0x00009A00
896# define RADEON_CNTL_BITBLT_MULTI 0x00009B00
897# define RADEON_CNTL_SET_SCISSORS 0xC0001E00
898
899#define RADEON_CP_PACKET_MASK 0xC0000000
900#define RADEON_CP_PACKET_COUNT_MASK 0x3fff0000
901#define RADEON_CP_PACKET0_REG_MASK 0x000007ff
902#define RADEON_CP_PACKET1_REG0_MASK 0x000007ff
903#define RADEON_CP_PACKET1_REG1_MASK 0x003ff800
904
905#define RADEON_VTX_Z_PRESENT (1 << 31)
906#define RADEON_VTX_PKCOLOR_PRESENT (1 << 3)
907
908#define RADEON_PRIM_TYPE_NONE (0 << 0)
909#define RADEON_PRIM_TYPE_POINT (1 << 0)
910#define RADEON_PRIM_TYPE_LINE (2 << 0)
911#define RADEON_PRIM_TYPE_LINE_STRIP (3 << 0)
912#define RADEON_PRIM_TYPE_TRI_LIST (4 << 0)
913#define RADEON_PRIM_TYPE_TRI_FAN (5 << 0)
914#define RADEON_PRIM_TYPE_TRI_STRIP (6 << 0)
915#define RADEON_PRIM_TYPE_TRI_TYPE2 (7 << 0)
916#define RADEON_PRIM_TYPE_RECT_LIST (8 << 0)
917#define RADEON_PRIM_TYPE_3VRT_POINT_LIST (9 << 0)
918#define RADEON_PRIM_TYPE_3VRT_LINE_LIST (10 << 0)
919#define RADEON_PRIM_TYPE_MASK 0xf
920#define RADEON_PRIM_WALK_IND (1 << 4)
921#define RADEON_PRIM_WALK_LIST (2 << 4)
922#define RADEON_PRIM_WALK_RING (3 << 4)
923#define RADEON_COLOR_ORDER_BGRA (0 << 6)
924#define RADEON_COLOR_ORDER_RGBA (1 << 6)
925#define RADEON_MAOS_ENABLE (1 << 7)
926#define RADEON_VTX_FMT_R128_MODE (0 << 8)
927#define RADEON_VTX_FMT_RADEON_MODE (1 << 8)
928#define RADEON_NUM_VERTICES_SHIFT 16
929
930#define RADEON_COLOR_FORMAT_CI8 2
931#define RADEON_COLOR_FORMAT_ARGB1555 3
932#define RADEON_COLOR_FORMAT_RGB565 4
933#define RADEON_COLOR_FORMAT_ARGB8888 6
934#define RADEON_COLOR_FORMAT_RGB332 7
935#define RADEON_COLOR_FORMAT_RGB8 9
936#define RADEON_COLOR_FORMAT_ARGB4444 15
937
938#define RADEON_TXFORMAT_I8 0
939#define RADEON_TXFORMAT_AI88 1
940#define RADEON_TXFORMAT_RGB332 2
941#define RADEON_TXFORMAT_ARGB1555 3
942#define RADEON_TXFORMAT_RGB565 4
943#define RADEON_TXFORMAT_ARGB4444 5
944#define RADEON_TXFORMAT_ARGB8888 6
945#define RADEON_TXFORMAT_RGBA8888 7
946#define RADEON_TXFORMAT_Y8 8
947#define RADEON_TXFORMAT_VYUY422 10
948#define RADEON_TXFORMAT_YVYU422 11
949#define RADEON_TXFORMAT_DXT1 12
950#define RADEON_TXFORMAT_DXT23 14
951#define RADEON_TXFORMAT_DXT45 15
952
953#define R200_PP_TXCBLEND_0 0x2f00
954#define R200_PP_TXCBLEND_1 0x2f10
955#define R200_PP_TXCBLEND_2 0x2f20
956#define R200_PP_TXCBLEND_3 0x2f30
957#define R200_PP_TXCBLEND_4 0x2f40
958#define R200_PP_TXCBLEND_5 0x2f50
959#define R200_PP_TXCBLEND_6 0x2f60
960#define R200_PP_TXCBLEND_7 0x2f70
961#define R200_SE_TCL_LIGHT_MODEL_CTL_0 0x2268
962#define R200_PP_TFACTOR_0 0x2ee0
963#define R200_SE_VTX_FMT_0 0x2088
964#define R200_SE_VAP_CNTL 0x2080
965#define R200_SE_TCL_MATRIX_SEL_0 0x2230
966#define R200_SE_TCL_TEX_PROC_CTL_2 0x22a8
967#define R200_SE_TCL_UCP_VERT_BLEND_CTL 0x22c0
968#define R200_PP_TXFILTER_5 0x2ca0
969#define R200_PP_TXFILTER_4 0x2c80
970#define R200_PP_TXFILTER_3 0x2c60
971#define R200_PP_TXFILTER_2 0x2c40
972#define R200_PP_TXFILTER_1 0x2c20
973#define R200_PP_TXFILTER_0 0x2c00
974#define R200_PP_TXOFFSET_5 0x2d78
975#define R200_PP_TXOFFSET_4 0x2d60
976#define R200_PP_TXOFFSET_3 0x2d48
977#define R200_PP_TXOFFSET_2 0x2d30
978#define R200_PP_TXOFFSET_1 0x2d18
979#define R200_PP_TXOFFSET_0 0x2d00
980
981#define R200_PP_CUBIC_FACES_0 0x2c18
982#define R200_PP_CUBIC_FACES_1 0x2c38
983#define R200_PP_CUBIC_FACES_2 0x2c58
984#define R200_PP_CUBIC_FACES_3 0x2c78
985#define R200_PP_CUBIC_FACES_4 0x2c98
986#define R200_PP_CUBIC_FACES_5 0x2cb8
987#define R200_PP_CUBIC_OFFSET_F1_0 0x2d04
988#define R200_PP_CUBIC_OFFSET_F2_0 0x2d08
989#define R200_PP_CUBIC_OFFSET_F3_0 0x2d0c
990#define R200_PP_CUBIC_OFFSET_F4_0 0x2d10
991#define R200_PP_CUBIC_OFFSET_F5_0 0x2d14
992#define R200_PP_CUBIC_OFFSET_F1_1 0x2d1c
993#define R200_PP_CUBIC_OFFSET_F2_1 0x2d20
994#define R200_PP_CUBIC_OFFSET_F3_1 0x2d24
995#define R200_PP_CUBIC_OFFSET_F4_1 0x2d28
996#define R200_PP_CUBIC_OFFSET_F5_1 0x2d2c
997#define R200_PP_CUBIC_OFFSET_F1_2 0x2d34
998#define R200_PP_CUBIC_OFFSET_F2_2 0x2d38
999#define R200_PP_CUBIC_OFFSET_F3_2 0x2d3c
1000#define R200_PP_CUBIC_OFFSET_F4_2 0x2d40
1001#define R200_PP_CUBIC_OFFSET_F5_2 0x2d44
1002#define R200_PP_CUBIC_OFFSET_F1_3 0x2d4c
1003#define R200_PP_CUBIC_OFFSET_F2_3 0x2d50
1004#define R200_PP_CUBIC_OFFSET_F3_3 0x2d54
1005#define R200_PP_CUBIC_OFFSET_F4_3 0x2d58
1006#define R200_PP_CUBIC_OFFSET_F5_3 0x2d5c
1007#define R200_PP_CUBIC_OFFSET_F1_4 0x2d64
1008#define R200_PP_CUBIC_OFFSET_F2_4 0x2d68
1009#define R200_PP_CUBIC_OFFSET_F3_4 0x2d6c
1010#define R200_PP_CUBIC_OFFSET_F4_4 0x2d70
1011#define R200_PP_CUBIC_OFFSET_F5_4 0x2d74
1012#define R200_PP_CUBIC_OFFSET_F1_5 0x2d7c
1013#define R200_PP_CUBIC_OFFSET_F2_5 0x2d80
1014#define R200_PP_CUBIC_OFFSET_F3_5 0x2d84
1015#define R200_PP_CUBIC_OFFSET_F4_5 0x2d88
1016#define R200_PP_CUBIC_OFFSET_F5_5 0x2d8c
1017
1018#define R200_RE_AUX_SCISSOR_CNTL 0x26f0
1019#define R200_SE_VTE_CNTL 0x20b0
1020#define R200_SE_TCL_OUTPUT_VTX_COMP_SEL 0x2250
1021#define R200_PP_TAM_DEBUG3 0x2d9c
1022#define R200_PP_CNTL_X 0x2cc4
1023#define R200_SE_VAP_CNTL_STATUS 0x2140
1024#define R200_RE_SCISSOR_TL_0 0x1cd8
1025#define R200_RE_SCISSOR_TL_1 0x1ce0
1026#define R200_RE_SCISSOR_TL_2 0x1ce8
1027#define R200_RB3D_DEPTHXY_OFFSET 0x1d60
1028#define R200_RE_AUX_SCISSOR_CNTL 0x26f0
1029#define R200_SE_VTX_STATE_CNTL 0x2180
1030#define R200_RE_POINTSIZE 0x2648
1031#define R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0 0x2254
1032
1033#define RADEON_PP_TEX_SIZE_0 0x1d04 /* NPOT */
1034#define RADEON_PP_TEX_SIZE_1 0x1d0c
1035#define RADEON_PP_TEX_SIZE_2 0x1d14
1036
1037#define RADEON_PP_CUBIC_FACES_0 0x1d24
1038#define RADEON_PP_CUBIC_FACES_1 0x1d28
1039#define RADEON_PP_CUBIC_FACES_2 0x1d2c
1040#define RADEON_PP_CUBIC_OFFSET_T0_0 0x1dd0 /* bits [31:5] */
1041#define RADEON_PP_CUBIC_OFFSET_T1_0 0x1e00
1042#define RADEON_PP_CUBIC_OFFSET_T2_0 0x1e14
1043
1044#define RADEON_SE_TCL_STATE_FLUSH 0x2284
1045
1046#define SE_VAP_CNTL__TCL_ENA_MASK 0x00000001
1047#define SE_VAP_CNTL__FORCE_W_TO_ONE_MASK 0x00010000
1048#define SE_VAP_CNTL__VF_MAX_VTX_NUM__SHIFT 0x00000012
1049#define SE_VTE_CNTL__VTX_XY_FMT_MASK 0x00000100
1050#define SE_VTE_CNTL__VTX_Z_FMT_MASK 0x00000200
1051#define SE_VTX_FMT_0__VTX_Z0_PRESENT_MASK 0x00000001
1052#define SE_VTX_FMT_0__VTX_W0_PRESENT_MASK 0x00000002
1053#define SE_VTX_FMT_0__VTX_COLOR_0_FMT__SHIFT 0x0000000b
1054#define R200_3D_DRAW_IMMD_2 0xC0003500
1055#define R200_SE_VTX_FMT_1 0x208c
1056#define R200_RE_CNTL 0x1c50
1057
1058#define R200_RB3D_BLENDCOLOR 0x3218
1059
1060#define R200_SE_TCL_POINT_SPRITE_CNTL 0x22c4
1061
1062#define R200_PP_TRI_PERF 0x2cf8
1063
1064#define R200_PP_AFS_0 0x2f80
1065#define R200_PP_AFS_1 0x2f00 /* same as txcblend_0 */
1066
1067#define R200_VAP_PVS_CNTL_1 0x22D0
1068
1069/* Constants */
1070#define RADEON_MAX_USEC_TIMEOUT 100000 /* 100 ms */
1071
1072#define RADEON_LAST_FRAME_REG RADEON_SCRATCH_REG0
1073#define RADEON_LAST_DISPATCH_REG RADEON_SCRATCH_REG1
1074#define RADEON_LAST_CLEAR_REG RADEON_SCRATCH_REG2
1075#define RADEON_LAST_SWI_REG RADEON_SCRATCH_REG3
1076#define RADEON_LAST_DISPATCH 1
1077
1078#define RADEON_MAX_VB_AGE 0x7fffffff
1079#define RADEON_MAX_VB_VERTS (0xffff)
1080
1081#define RADEON_RING_HIGH_MARK 128
1082
1083#define RADEON_PCIGART_TABLE_SIZE (32*1024)
1084
1085#define RADEON_READ(reg) DRM_READ32( dev_priv->mmio, (reg) )
1086#define RADEON_WRITE(reg,val) DRM_WRITE32( dev_priv->mmio, (reg), (val) )
1087#define RADEON_READ8(reg) DRM_READ8( dev_priv->mmio, (reg) )
1088#define RADEON_WRITE8(reg,val) DRM_WRITE8( dev_priv->mmio, (reg), (val) )
1089
1090#define RADEON_WRITE_PLL( addr, val ) \
1091do { \
1092 RADEON_WRITE8( RADEON_CLOCK_CNTL_INDEX, \
1093 ((addr) & 0x1f) | RADEON_PLL_WR_EN ); \
1094 RADEON_WRITE( RADEON_CLOCK_CNTL_DATA, (val) ); \
1095} while (0)
1096
1097#define RADEON_WRITE_IGPGART( addr, val ) \
1098do { \
1099 RADEON_WRITE( RADEON_IGPGART_INDEX, \
1100 ((addr) & 0x7f) | (1 << 8)); \
1101 RADEON_WRITE( RADEON_IGPGART_DATA, (val) ); \
1102 RADEON_WRITE( RADEON_IGPGART_INDEX, 0x7f ); \
1103} while (0)
1104
1105#define RADEON_WRITE_PCIE( addr, val ) \
1106do { \
1107 RADEON_WRITE8( RADEON_PCIE_INDEX, \
1108 ((addr) & 0xff)); \
1109 RADEON_WRITE( RADEON_PCIE_DATA, (val) ); \
1110} while (0)
1111
1112#define RADEON_WRITE_MCIND( addr, val ) \
1113 do { \
1114 RADEON_WRITE(R520_MC_IND_INDEX, 0xff0000 | ((addr) & 0xff)); \
1115 RADEON_WRITE(R520_MC_IND_DATA, (val)); \
1116 RADEON_WRITE(R520_MC_IND_INDEX, 0); \
1117 } while (0)
1118
1119#define RS690_WRITE_MCIND( addr, val ) \
1120do { \
1121 RADEON_WRITE(RS690_MC_INDEX, RS690_MC_INDEX_WR_EN | ((addr) & RS690_MC_INDEX_MASK)); \
1122 RADEON_WRITE(RS690_MC_DATA, val); \
1123 RADEON_WRITE(RS690_MC_INDEX, RS690_MC_INDEX_WR_ACK); \
1124} while (0)
1125
1126#define CP_PACKET0( reg, n ) \
1127 (RADEON_CP_PACKET0 | ((n) << 16) | ((reg) >> 2))
1128#define CP_PACKET0_TABLE( reg, n ) \
1129 (RADEON_CP_PACKET0 | RADEON_ONE_REG_WR | ((n) << 16) | ((reg) >> 2))
1130#define CP_PACKET1( reg0, reg1 ) \
1131 (RADEON_CP_PACKET1 | (((reg1) >> 2) << 15) | ((reg0) >> 2))
1132#define CP_PACKET2() \
1133 (RADEON_CP_PACKET2)
1134#define CP_PACKET3( pkt, n ) \
1135 (RADEON_CP_PACKET3 | (pkt) | ((n) << 16))
1136
1137/* ================================================================
1138 * Engine control helper macros
1139 */
1140
1141#define RADEON_WAIT_UNTIL_2D_IDLE() do { \
1142 OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) ); \
1143 OUT_RING( (RADEON_WAIT_2D_IDLECLEAN | \
1144 RADEON_WAIT_HOST_IDLECLEAN) ); \
1145} while (0)
1146
1147#define RADEON_WAIT_UNTIL_3D_IDLE() do { \
1148 OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) ); \
1149 OUT_RING( (RADEON_WAIT_3D_IDLECLEAN | \
1150 RADEON_WAIT_HOST_IDLECLEAN) ); \
1151} while (0)
1152
1153#define RADEON_WAIT_UNTIL_IDLE() do { \
1154 OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) ); \
1155 OUT_RING( (RADEON_WAIT_2D_IDLECLEAN | \
1156 RADEON_WAIT_3D_IDLECLEAN | \
1157 RADEON_WAIT_HOST_IDLECLEAN) ); \
1158} while (0)
1159
1160#define RADEON_WAIT_UNTIL_PAGE_FLIPPED() do { \
1161 OUT_RING( CP_PACKET0( RADEON_WAIT_UNTIL, 0 ) ); \
1162 OUT_RING( RADEON_WAIT_CRTC_PFLIP ); \
1163} while (0)
1164
1165#define RADEON_FLUSH_CACHE() do { \
1166 OUT_RING( CP_PACKET0( RADEON_RB3D_DSTCACHE_CTLSTAT, 0 ) ); \
1167 OUT_RING( RADEON_RB3D_DC_FLUSH ); \
1168} while (0)
1169
1170#define RADEON_PURGE_CACHE() do { \
1171 OUT_RING( CP_PACKET0( RADEON_RB3D_DSTCACHE_CTLSTAT, 0 ) ); \
1172 OUT_RING( RADEON_RB3D_DC_FLUSH_ALL ); \
1173} while (0)
1174
1175#define RADEON_FLUSH_ZCACHE() do { \
1176 OUT_RING( CP_PACKET0( RADEON_RB3D_ZCACHE_CTLSTAT, 0 ) ); \
1177 OUT_RING( RADEON_RB3D_ZC_FLUSH ); \
1178} while (0)
1179
1180#define RADEON_PURGE_ZCACHE() do { \
1181 OUT_RING( CP_PACKET0( RADEON_RB3D_ZCACHE_CTLSTAT, 0 ) ); \
1182 OUT_RING( RADEON_RB3D_ZC_FLUSH_ALL ); \
1183} while (0)
1184
1185/* ================================================================
1186 * Misc helper macros
1187 */
1188
1189/* Perfbox functionality only.
1190 */
1191#define RING_SPACE_TEST_WITH_RETURN( dev_priv ) \
1192do { \
1193 if (!(dev_priv->stats.boxes & RADEON_BOX_DMA_IDLE)) { \
1194 u32 head = GET_RING_HEAD( dev_priv ); \
1195 if (head == dev_priv->ring.tail) \
1196 dev_priv->stats.boxes |= RADEON_BOX_DMA_IDLE; \
1197 } \
1198} while (0)
1199
1200#define VB_AGE_TEST_WITH_RETURN( dev_priv ) \
1201do { \
1202 drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv; \
1203 if ( sarea_priv->last_dispatch >= RADEON_MAX_VB_AGE ) { \
1204 int __ret = radeon_do_cp_idle( dev_priv ); \
1205 if ( __ret ) return __ret; \
1206 sarea_priv->last_dispatch = 0; \
1207 radeon_freelist_reset( dev ); \
1208 } \
1209} while (0)
1210
1211#define RADEON_DISPATCH_AGE( age ) do { \
1212 OUT_RING( CP_PACKET0( RADEON_LAST_DISPATCH_REG, 0 ) ); \
1213 OUT_RING( age ); \
1214} while (0)
1215
1216#define RADEON_FRAME_AGE( age ) do { \
1217 OUT_RING( CP_PACKET0( RADEON_LAST_FRAME_REG, 0 ) ); \
1218 OUT_RING( age ); \
1219} while (0)
1220
1221#define RADEON_CLEAR_AGE( age ) do { \
1222 OUT_RING( CP_PACKET0( RADEON_LAST_CLEAR_REG, 0 ) ); \
1223 OUT_RING( age ); \
1224} while (0)
1225
1226/* ================================================================
1227 * Ring control
1228 */
1229
1230#define RADEON_VERBOSE 0
1231
1232#define RING_LOCALS int write, _nr; unsigned int mask; u32 *ring;
1233
1234#define BEGIN_RING( n ) do { \
1235 if ( RADEON_VERBOSE ) { \
1236 DRM_INFO( "BEGIN_RING( %d )\n", (n)); \
1237 } \
1238 if ( dev_priv->ring.space <= (n) * sizeof(u32) ) { \
1239 COMMIT_RING(); \
1240 radeon_wait_ring( dev_priv, (n) * sizeof(u32) ); \
1241 } \
1242 _nr = n; dev_priv->ring.space -= (n) * sizeof(u32); \
1243 ring = dev_priv->ring.start; \
1244 write = dev_priv->ring.tail; \
1245 mask = dev_priv->ring.tail_mask; \
1246} while (0)
1247
1248#define ADVANCE_RING() do { \
1249 if ( RADEON_VERBOSE ) { \
1250 DRM_INFO( "ADVANCE_RING() wr=0x%06x tail=0x%06x\n", \
1251 write, dev_priv->ring.tail ); \
1252 } \
1253 if (((dev_priv->ring.tail + _nr) & mask) != write) { \
1254 DRM_ERROR( \
1255 "ADVANCE_RING(): mismatch: nr: %x write: %x line: %d\n", \
1256 ((dev_priv->ring.tail + _nr) & mask), \
1257 write, __LINE__); \
1258 } else \
1259 dev_priv->ring.tail = write; \
1260} while (0)
1261
1262#define COMMIT_RING() do { \
1263 /* Flush writes to ring */ \
1264 DRM_MEMORYBARRIER(); \
1265 GET_RING_HEAD( dev_priv ); \
1266 RADEON_WRITE( RADEON_CP_RB_WPTR, dev_priv->ring.tail ); \
1267 /* read from PCI bus to ensure correct posting */ \
1268 RADEON_READ( RADEON_CP_RB_RPTR ); \
1269} while (0)
1270
1271#define OUT_RING( x ) do { \
1272 if ( RADEON_VERBOSE ) { \
1273 DRM_INFO( " OUT_RING( 0x%08x ) at 0x%x\n", \
1274 (unsigned int)(x), write ); \
1275 } \
1276 ring[write++] = (x); \
1277 write &= mask; \
1278} while (0)
1279
1280#define OUT_RING_REG( reg, val ) do { \
1281 OUT_RING( CP_PACKET0( reg, 0 ) ); \
1282 OUT_RING( val ); \
1283} while (0)
1284
1285#define OUT_RING_TABLE( tab, sz ) do { \
1286 int _size = (sz); \
1287 int *_tab = (int *)(tab); \
1288 \
1289 if (write + _size > mask) { \
1290 int _i = (mask+1) - write; \
1291 _size -= _i; \
1292 while (_i > 0 ) { \
1293 *(int *)(ring + write) = *_tab++; \
1294 write++; \
1295 _i--; \
1296 } \
1297 write = 0; \
1298 _tab += _i; \
1299 } \
1300 while (_size > 0) { \
1301 *(ring + write) = *_tab++; \
1302 write++; \
1303 _size--; \
1304 } \
1305 write &= mask; \
1306} while (0)
1307
1308#endif /* __RADEON_DRV_H__ */
diff --git a/drivers/char/drm/radeon_ioc32.c b/drivers/char/drm/radeon_ioc32.c
deleted file mode 100644
index 56decda2a71f..000000000000
--- a/drivers/char/drm/radeon_ioc32.c
+++ /dev/null
@@ -1,424 +0,0 @@
1/**
2 * \file radeon_ioc32.c
3 *
4 * 32-bit ioctl compatibility routines for the Radeon DRM.
5 *
6 * \author Paul Mackerras <paulus@samba.org>
7 *
8 * Copyright (C) Paul Mackerras 2005
9 * All Rights Reserved.
10 *
11 * Permission is hereby granted, free of charge, to any person obtaining a
12 * copy of this software and associated documentation files (the "Software"),
13 * to deal in the Software without restriction, including without limitation
14 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
15 * and/or sell copies of the Software, and to permit persons to whom the
16 * Software is furnished to do so, subject to the following conditions:
17 *
18 * The above copyright notice and this permission notice (including the next
19 * paragraph) shall be included in all copies or substantial portions of the
20 * Software.
21 *
22 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
25 * THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
26 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
28 * IN THE SOFTWARE.
29 */
30#include <linux/compat.h>
31
32#include "drmP.h"
33#include "drm.h"
34#include "radeon_drm.h"
35#include "radeon_drv.h"
36
37typedef struct drm_radeon_init32 {
38 int func;
39 u32 sarea_priv_offset;
40 int is_pci;
41 int cp_mode;
42 int gart_size;
43 int ring_size;
44 int usec_timeout;
45
46 unsigned int fb_bpp;
47 unsigned int front_offset, front_pitch;
48 unsigned int back_offset, back_pitch;
49 unsigned int depth_bpp;
50 unsigned int depth_offset, depth_pitch;
51
52 u32 fb_offset;
53 u32 mmio_offset;
54 u32 ring_offset;
55 u32 ring_rptr_offset;
56 u32 buffers_offset;
57 u32 gart_textures_offset;
58} drm_radeon_init32_t;
59
60static int compat_radeon_cp_init(struct file *file, unsigned int cmd,
61 unsigned long arg)
62{
63 drm_radeon_init32_t init32;
64 drm_radeon_init_t __user *init;
65
66 if (copy_from_user(&init32, (void __user *)arg, sizeof(init32)))
67 return -EFAULT;
68
69 init = compat_alloc_user_space(sizeof(*init));
70 if (!access_ok(VERIFY_WRITE, init, sizeof(*init))
71 || __put_user(init32.func, &init->func)
72 || __put_user(init32.sarea_priv_offset, &init->sarea_priv_offset)
73 || __put_user(init32.is_pci, &init->is_pci)
74 || __put_user(init32.cp_mode, &init->cp_mode)
75 || __put_user(init32.gart_size, &init->gart_size)
76 || __put_user(init32.ring_size, &init->ring_size)
77 || __put_user(init32.usec_timeout, &init->usec_timeout)
78 || __put_user(init32.fb_bpp, &init->fb_bpp)
79 || __put_user(init32.front_offset, &init->front_offset)
80 || __put_user(init32.front_pitch, &init->front_pitch)
81 || __put_user(init32.back_offset, &init->back_offset)
82 || __put_user(init32.back_pitch, &init->back_pitch)
83 || __put_user(init32.depth_bpp, &init->depth_bpp)
84 || __put_user(init32.depth_offset, &init->depth_offset)
85 || __put_user(init32.depth_pitch, &init->depth_pitch)
86 || __put_user(init32.fb_offset, &init->fb_offset)
87 || __put_user(init32.mmio_offset, &init->mmio_offset)
88 || __put_user(init32.ring_offset, &init->ring_offset)
89 || __put_user(init32.ring_rptr_offset, &init->ring_rptr_offset)
90 || __put_user(init32.buffers_offset, &init->buffers_offset)
91 || __put_user(init32.gart_textures_offset,
92 &init->gart_textures_offset))
93 return -EFAULT;
94
95 return drm_ioctl(file->f_path.dentry->d_inode, file,
96 DRM_IOCTL_RADEON_CP_INIT, (unsigned long)init);
97}
98
99typedef struct drm_radeon_clear32 {
100 unsigned int flags;
101 unsigned int clear_color;
102 unsigned int clear_depth;
103 unsigned int color_mask;
104 unsigned int depth_mask; /* misnamed field: should be stencil */
105 u32 depth_boxes;
106} drm_radeon_clear32_t;
107
108static int compat_radeon_cp_clear(struct file *file, unsigned int cmd,
109 unsigned long arg)
110{
111 drm_radeon_clear32_t clr32;
112 drm_radeon_clear_t __user *clr;
113
114 if (copy_from_user(&clr32, (void __user *)arg, sizeof(clr32)))
115 return -EFAULT;
116
117 clr = compat_alloc_user_space(sizeof(*clr));
118 if (!access_ok(VERIFY_WRITE, clr, sizeof(*clr))
119 || __put_user(clr32.flags, &clr->flags)
120 || __put_user(clr32.clear_color, &clr->clear_color)
121 || __put_user(clr32.clear_depth, &clr->clear_depth)
122 || __put_user(clr32.color_mask, &clr->color_mask)
123 || __put_user(clr32.depth_mask, &clr->depth_mask)
124 || __put_user((void __user *)(unsigned long)clr32.depth_boxes,
125 &clr->depth_boxes))
126 return -EFAULT;
127
128 return drm_ioctl(file->f_path.dentry->d_inode, file,
129 DRM_IOCTL_RADEON_CLEAR, (unsigned long)clr);
130}
131
132typedef struct drm_radeon_stipple32 {
133 u32 mask;
134} drm_radeon_stipple32_t;
135
136static int compat_radeon_cp_stipple(struct file *file, unsigned int cmd,
137 unsigned long arg)
138{
139 drm_radeon_stipple32_t __user *argp = (void __user *)arg;
140 drm_radeon_stipple_t __user *request;
141 u32 mask;
142
143 if (get_user(mask, &argp->mask))
144 return -EFAULT;
145
146 request = compat_alloc_user_space(sizeof(*request));
147 if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
148 || __put_user((unsigned int __user *)(unsigned long)mask,
149 &request->mask))
150 return -EFAULT;
151
152 return drm_ioctl(file->f_path.dentry->d_inode, file,
153 DRM_IOCTL_RADEON_STIPPLE, (unsigned long)request);
154}
155
156typedef struct drm_radeon_tex_image32 {
157 unsigned int x, y; /* Blit coordinates */
158 unsigned int width, height;
159 u32 data;
160} drm_radeon_tex_image32_t;
161
162typedef struct drm_radeon_texture32 {
163 unsigned int offset;
164 int pitch;
165 int format;
166 int width; /* Texture image coordinates */
167 int height;
168 u32 image;
169} drm_radeon_texture32_t;
170
171static int compat_radeon_cp_texture(struct file *file, unsigned int cmd,
172 unsigned long arg)
173{
174 drm_radeon_texture32_t req32;
175 drm_radeon_texture_t __user *request;
176 drm_radeon_tex_image32_t img32;
177 drm_radeon_tex_image_t __user *image;
178
179 if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
180 return -EFAULT;
181 if (req32.image == 0)
182 return -EINVAL;
183 if (copy_from_user(&img32, (void __user *)(unsigned long)req32.image,
184 sizeof(img32)))
185 return -EFAULT;
186
187 request = compat_alloc_user_space(sizeof(*request) + sizeof(*image));
188 if (!access_ok(VERIFY_WRITE, request,
189 sizeof(*request) + sizeof(*image)))
190 return -EFAULT;
191 image = (drm_radeon_tex_image_t __user *) (request + 1);
192
193 if (__put_user(req32.offset, &request->offset)
194 || __put_user(req32.pitch, &request->pitch)
195 || __put_user(req32.format, &request->format)
196 || __put_user(req32.width, &request->width)
197 || __put_user(req32.height, &request->height)
198 || __put_user(image, &request->image)
199 || __put_user(img32.x, &image->x)
200 || __put_user(img32.y, &image->y)
201 || __put_user(img32.width, &image->width)
202 || __put_user(img32.height, &image->height)
203 || __put_user((const void __user *)(unsigned long)img32.data,
204 &image->data))
205 return -EFAULT;
206
207 return drm_ioctl(file->f_path.dentry->d_inode, file,
208 DRM_IOCTL_RADEON_TEXTURE, (unsigned long)request);
209}
210
211typedef struct drm_radeon_vertex2_32 {
212 int idx; /* Index of vertex buffer */
213 int discard; /* Client finished with buffer? */
214 int nr_states;
215 u32 state;
216 int nr_prims;
217 u32 prim;
218} drm_radeon_vertex2_32_t;
219
220static int compat_radeon_cp_vertex2(struct file *file, unsigned int cmd,
221 unsigned long arg)
222{
223 drm_radeon_vertex2_32_t req32;
224 drm_radeon_vertex2_t __user *request;
225
226 if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
227 return -EFAULT;
228
229 request = compat_alloc_user_space(sizeof(*request));
230 if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
231 || __put_user(req32.idx, &request->idx)
232 || __put_user(req32.discard, &request->discard)
233 || __put_user(req32.nr_states, &request->nr_states)
234 || __put_user((void __user *)(unsigned long)req32.state,
235 &request->state)
236 || __put_user(req32.nr_prims, &request->nr_prims)
237 || __put_user((void __user *)(unsigned long)req32.prim,
238 &request->prim))
239 return -EFAULT;
240
241 return drm_ioctl(file->f_path.dentry->d_inode, file,
242 DRM_IOCTL_RADEON_VERTEX2, (unsigned long)request);
243}
244
245typedef struct drm_radeon_cmd_buffer32 {
246 int bufsz;
247 u32 buf;
248 int nbox;
249 u32 boxes;
250} drm_radeon_cmd_buffer32_t;
251
252static int compat_radeon_cp_cmdbuf(struct file *file, unsigned int cmd,
253 unsigned long arg)
254{
255 drm_radeon_cmd_buffer32_t req32;
256 drm_radeon_cmd_buffer_t __user *request;
257
258 if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
259 return -EFAULT;
260
261 request = compat_alloc_user_space(sizeof(*request));
262 if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
263 || __put_user(req32.bufsz, &request->bufsz)
264 || __put_user((void __user *)(unsigned long)req32.buf,
265 &request->buf)
266 || __put_user(req32.nbox, &request->nbox)
267 || __put_user((void __user *)(unsigned long)req32.boxes,
268 &request->boxes))
269 return -EFAULT;
270
271 return drm_ioctl(file->f_path.dentry->d_inode, file,
272 DRM_IOCTL_RADEON_CMDBUF, (unsigned long)request);
273}
274
275typedef struct drm_radeon_getparam32 {
276 int param;
277 u32 value;
278} drm_radeon_getparam32_t;
279
280static int compat_radeon_cp_getparam(struct file *file, unsigned int cmd,
281 unsigned long arg)
282{
283 drm_radeon_getparam32_t req32;
284 drm_radeon_getparam_t __user *request;
285
286 if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
287 return -EFAULT;
288
289 request = compat_alloc_user_space(sizeof(*request));
290 if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
291 || __put_user(req32.param, &request->param)
292 || __put_user((void __user *)(unsigned long)req32.value,
293 &request->value))
294 return -EFAULT;
295
296 return drm_ioctl(file->f_path.dentry->d_inode, file,
297 DRM_IOCTL_RADEON_GETPARAM, (unsigned long)request);
298}
299
300typedef struct drm_radeon_mem_alloc32 {
301 int region;
302 int alignment;
303 int size;
304 u32 region_offset; /* offset from start of fb or GART */
305} drm_radeon_mem_alloc32_t;
306
307static int compat_radeon_mem_alloc(struct file *file, unsigned int cmd,
308 unsigned long arg)
309{
310 drm_radeon_mem_alloc32_t req32;
311 drm_radeon_mem_alloc_t __user *request;
312
313 if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
314 return -EFAULT;
315
316 request = compat_alloc_user_space(sizeof(*request));
317 if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
318 || __put_user(req32.region, &request->region)
319 || __put_user(req32.alignment, &request->alignment)
320 || __put_user(req32.size, &request->size)
321 || __put_user((int __user *)(unsigned long)req32.region_offset,
322 &request->region_offset))
323 return -EFAULT;
324
325 return drm_ioctl(file->f_path.dentry->d_inode, file,
326 DRM_IOCTL_RADEON_ALLOC, (unsigned long)request);
327}
328
329typedef struct drm_radeon_irq_emit32 {
330 u32 irq_seq;
331} drm_radeon_irq_emit32_t;
332
333static int compat_radeon_irq_emit(struct file *file, unsigned int cmd,
334 unsigned long arg)
335{
336 drm_radeon_irq_emit32_t req32;
337 drm_radeon_irq_emit_t __user *request;
338
339 if (copy_from_user(&req32, (void __user *)arg, sizeof(req32)))
340 return -EFAULT;
341
342 request = compat_alloc_user_space(sizeof(*request));
343 if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
344 || __put_user((int __user *)(unsigned long)req32.irq_seq,
345 &request->irq_seq))
346 return -EFAULT;
347
348 return drm_ioctl(file->f_path.dentry->d_inode, file,
349 DRM_IOCTL_RADEON_IRQ_EMIT, (unsigned long)request);
350}
351
352/* The two 64-bit arches where alignof(u64)==4 in 32-bit code */
353#if defined (CONFIG_X86_64) || defined(CONFIG_IA64)
354typedef struct drm_radeon_setparam32 {
355 int param;
356 u64 value;
357} __attribute__((packed)) drm_radeon_setparam32_t;
358
359static int compat_radeon_cp_setparam(struct file *file, unsigned int cmd,
360 unsigned long arg)
361{
362 drm_radeon_setparam32_t req32;
363 drm_radeon_setparam_t __user *request;
364
365 if (copy_from_user(&req32, (void __user *) arg, sizeof(req32)))
366 return -EFAULT;
367
368 request = compat_alloc_user_space(sizeof(*request));
369 if (!access_ok(VERIFY_WRITE, request, sizeof(*request))
370 || __put_user(req32.param, &request->param)
371 || __put_user((void __user *)(unsigned long)req32.value,
372 &request->value))
373 return -EFAULT;
374
375 return drm_ioctl(file->f_dentry->d_inode, file,
376 DRM_IOCTL_RADEON_SETPARAM, (unsigned long) request);
377}
378#else
379#define compat_radeon_cp_setparam NULL
380#endif /* X86_64 || IA64 */
381
382drm_ioctl_compat_t *radeon_compat_ioctls[] = {
383 [DRM_RADEON_CP_INIT] = compat_radeon_cp_init,
384 [DRM_RADEON_CLEAR] = compat_radeon_cp_clear,
385 [DRM_RADEON_STIPPLE] = compat_radeon_cp_stipple,
386 [DRM_RADEON_TEXTURE] = compat_radeon_cp_texture,
387 [DRM_RADEON_VERTEX2] = compat_radeon_cp_vertex2,
388 [DRM_RADEON_CMDBUF] = compat_radeon_cp_cmdbuf,
389 [DRM_RADEON_GETPARAM] = compat_radeon_cp_getparam,
390 [DRM_RADEON_SETPARAM] = compat_radeon_cp_setparam,
391 [DRM_RADEON_ALLOC] = compat_radeon_mem_alloc,
392 [DRM_RADEON_IRQ_EMIT] = compat_radeon_irq_emit,
393};
394
395/**
396 * Called whenever a 32-bit process running under a 64-bit kernel
397 * performs an ioctl on /dev/dri/card<n>.
398 *
399 * \param filp file pointer.
400 * \param cmd command.
401 * \param arg user argument.
402 * \return zero on success or negative number on failure.
403 */
404long radeon_compat_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
405{
406 unsigned int nr = DRM_IOCTL_NR(cmd);
407 drm_ioctl_compat_t *fn = NULL;
408 int ret;
409
410 if (nr < DRM_COMMAND_BASE)
411 return drm_compat_ioctl(filp, cmd, arg);
412
413 if (nr < DRM_COMMAND_BASE + DRM_ARRAY_SIZE(radeon_compat_ioctls))
414 fn = radeon_compat_ioctls[nr - DRM_COMMAND_BASE];
415
416 lock_kernel(); /* XXX for now */
417 if (fn != NULL)
418 ret = (*fn) (filp, cmd, arg);
419 else
420 ret = drm_ioctl(filp->f_path.dentry->d_inode, filp, cmd, arg);
421 unlock_kernel();
422
423 return ret;
424}
diff --git a/drivers/char/drm/radeon_irq.c b/drivers/char/drm/radeon_irq.c
deleted file mode 100644
index 507d6b747a13..000000000000
--- a/drivers/char/drm/radeon_irq.c
+++ /dev/null
@@ -1,315 +0,0 @@
1/* radeon_irq.c -- IRQ handling for radeon -*- linux-c -*- */
2/*
3 * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
4 *
5 * The Weather Channel (TM) funded Tungsten Graphics to develop the
6 * initial release of the Radeon 8500 driver under the XFree86 license.
7 * This notice must be preserved.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice (including the next
17 * paragraph) shall be included in all copies or substantial portions of the
18 * Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
24 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
25 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 * DEALINGS IN THE SOFTWARE.
27 *
28 * Authors:
29 * Keith Whitwell <keith@tungstengraphics.com>
30 * Michel Dänzer <michel@daenzer.net>
31 */
32
33#include "drmP.h"
34#include "drm.h"
35#include "radeon_drm.h"
36#include "radeon_drv.h"
37
38static void radeon_irq_set_state(struct drm_device *dev, u32 mask, int state)
39{
40 drm_radeon_private_t *dev_priv = dev->dev_private;
41
42 if (state)
43 dev_priv->irq_enable_reg |= mask;
44 else
45 dev_priv->irq_enable_reg &= ~mask;
46
47 RADEON_WRITE(RADEON_GEN_INT_CNTL, dev_priv->irq_enable_reg);
48}
49
50int radeon_enable_vblank(struct drm_device *dev, int crtc)
51{
52 switch (crtc) {
53 case 0:
54 radeon_irq_set_state(dev, RADEON_CRTC_VBLANK_MASK, 1);
55 break;
56 case 1:
57 radeon_irq_set_state(dev, RADEON_CRTC2_VBLANK_MASK, 1);
58 break;
59 default:
60 DRM_ERROR("tried to enable vblank on non-existent crtc %d\n",
61 crtc);
62 return EINVAL;
63 }
64
65 return 0;
66}
67
68void radeon_disable_vblank(struct drm_device *dev, int crtc)
69{
70 switch (crtc) {
71 case 0:
72 radeon_irq_set_state(dev, RADEON_CRTC_VBLANK_MASK, 0);
73 break;
74 case 1:
75 radeon_irq_set_state(dev, RADEON_CRTC2_VBLANK_MASK, 0);
76 break;
77 default:
78 DRM_ERROR("tried to enable vblank on non-existent crtc %d\n",
79 crtc);
80 break;
81 }
82}
83
84static __inline__ u32 radeon_acknowledge_irqs(drm_radeon_private_t * dev_priv)
85{
86 u32 irqs = RADEON_READ(RADEON_GEN_INT_STATUS) &
87 (RADEON_SW_INT_TEST | RADEON_CRTC_VBLANK_STAT |
88 RADEON_CRTC2_VBLANK_STAT);
89
90 if (irqs)
91 RADEON_WRITE(RADEON_GEN_INT_STATUS, irqs);
92
93 return irqs;
94}
95
96/* Interrupts - Used for device synchronization and flushing in the
97 * following circumstances:
98 *
99 * - Exclusive FB access with hw idle:
100 * - Wait for GUI Idle (?) interrupt, then do normal flush.
101 *
102 * - Frame throttling, NV_fence:
103 * - Drop marker irq's into command stream ahead of time.
104 * - Wait on irq's with lock *not held*
105 * - Check each for termination condition
106 *
107 * - Internally in cp_getbuffer, etc:
108 * - as above, but wait with lock held???
109 *
110 * NOTE: These functions are misleadingly named -- the irq's aren't
111 * tied to dma at all, this is just a hangover from dri prehistory.
112 */
113
114irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS)
115{
116 struct drm_device *dev = (struct drm_device *) arg;
117 drm_radeon_private_t *dev_priv =
118 (drm_radeon_private_t *) dev->dev_private;
119 u32 stat;
120
121 /* Only consider the bits we're interested in - others could be used
122 * outside the DRM
123 */
124 stat = radeon_acknowledge_irqs(dev_priv);
125 if (!stat)
126 return IRQ_NONE;
127
128 stat &= dev_priv->irq_enable_reg;
129
130 /* SW interrupt */
131 if (stat & RADEON_SW_INT_TEST)
132 DRM_WAKEUP(&dev_priv->swi_queue);
133
134 /* VBLANK interrupt */
135 if (stat & RADEON_CRTC_VBLANK_STAT)
136 drm_handle_vblank(dev, 0);
137 if (stat & RADEON_CRTC2_VBLANK_STAT)
138 drm_handle_vblank(dev, 1);
139
140 return IRQ_HANDLED;
141}
142
143static int radeon_emit_irq(struct drm_device * dev)
144{
145 drm_radeon_private_t *dev_priv = dev->dev_private;
146 unsigned int ret;
147 RING_LOCALS;
148
149 atomic_inc(&dev_priv->swi_emitted);
150 ret = atomic_read(&dev_priv->swi_emitted);
151
152 BEGIN_RING(4);
153 OUT_RING_REG(RADEON_LAST_SWI_REG, ret);
154 OUT_RING_REG(RADEON_GEN_INT_STATUS, RADEON_SW_INT_FIRE);
155 ADVANCE_RING();
156 COMMIT_RING();
157
158 return ret;
159}
160
161static int radeon_wait_irq(struct drm_device * dev, int swi_nr)
162{
163 drm_radeon_private_t *dev_priv =
164 (drm_radeon_private_t *) dev->dev_private;
165 int ret = 0;
166
167 if (RADEON_READ(RADEON_LAST_SWI_REG) >= swi_nr)
168 return 0;
169
170 dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
171
172 DRM_WAIT_ON(ret, dev_priv->swi_queue, 3 * DRM_HZ,
173 RADEON_READ(RADEON_LAST_SWI_REG) >= swi_nr);
174
175 return ret;
176}
177
178u32 radeon_get_vblank_counter(struct drm_device *dev, int crtc)
179{
180 drm_radeon_private_t *dev_priv = dev->dev_private;
181 u32 crtc_cnt_reg, crtc_status_reg;
182
183 if (!dev_priv) {
184 DRM_ERROR("called with no initialization\n");
185 return -EINVAL;
186 }
187
188 if (crtc == 0) {
189 crtc_cnt_reg = RADEON_CRTC_CRNT_FRAME;
190 crtc_status_reg = RADEON_CRTC_STATUS;
191 } else if (crtc == 1) {
192 crtc_cnt_reg = RADEON_CRTC2_CRNT_FRAME;
193 crtc_status_reg = RADEON_CRTC2_STATUS;
194 } else {
195 return -EINVAL;
196 }
197
198 return RADEON_READ(crtc_cnt_reg) + (RADEON_READ(crtc_status_reg) & 1);
199}
200
201/* Needs the lock as it touches the ring.
202 */
203int radeon_irq_emit(struct drm_device *dev, void *data, struct drm_file *file_priv)
204{
205 drm_radeon_private_t *dev_priv = dev->dev_private;
206 drm_radeon_irq_emit_t *emit = data;
207 int result;
208
209 LOCK_TEST_WITH_RETURN(dev, file_priv);
210
211 if (!dev_priv) {
212 DRM_ERROR("called with no initialization\n");
213 return -EINVAL;
214 }
215
216 result = radeon_emit_irq(dev);
217
218 if (DRM_COPY_TO_USER(emit->irq_seq, &result, sizeof(int))) {
219 DRM_ERROR("copy_to_user\n");
220 return -EFAULT;
221 }
222
223 return 0;
224}
225
226/* Doesn't need the hardware lock.
227 */
228int radeon_irq_wait(struct drm_device *dev, void *data, struct drm_file *file_priv)
229{
230 drm_radeon_private_t *dev_priv = dev->dev_private;
231 drm_radeon_irq_wait_t *irqwait = data;
232
233 if (!dev_priv) {
234 DRM_ERROR("called with no initialization\n");
235 return -EINVAL;
236 }
237
238 return radeon_wait_irq(dev, irqwait->irq_seq);
239}
240
241/* drm_dma.h hooks
242*/
243void radeon_driver_irq_preinstall(struct drm_device * dev)
244{
245 drm_radeon_private_t *dev_priv =
246 (drm_radeon_private_t *) dev->dev_private;
247
248 /* Disable *all* interrupts */
249 RADEON_WRITE(RADEON_GEN_INT_CNTL, 0);
250
251 /* Clear bits if they're already high */
252 radeon_acknowledge_irqs(dev_priv);
253}
254
255int radeon_driver_irq_postinstall(struct drm_device * dev)
256{
257 drm_radeon_private_t *dev_priv =
258 (drm_radeon_private_t *) dev->dev_private;
259 int ret;
260
261 atomic_set(&dev_priv->swi_emitted, 0);
262 DRM_INIT_WAITQUEUE(&dev_priv->swi_queue);
263
264 ret = drm_vblank_init(dev, 2);
265 if (ret)
266 return ret;
267
268 dev->max_vblank_count = 0x001fffff;
269
270 radeon_irq_set_state(dev, RADEON_SW_INT_ENABLE, 1);
271
272 return 0;
273}
274
275void radeon_driver_irq_uninstall(struct drm_device * dev)
276{
277 drm_radeon_private_t *dev_priv =
278 (drm_radeon_private_t *) dev->dev_private;
279 if (!dev_priv)
280 return;
281
282 dev_priv->irq_enabled = 0;
283
284 /* Disable *all* interrupts */
285 RADEON_WRITE(RADEON_GEN_INT_CNTL, 0);
286}
287
288
289int radeon_vblank_crtc_get(struct drm_device *dev)
290{
291 drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private;
292 u32 flag;
293 u32 value;
294
295 flag = RADEON_READ(RADEON_GEN_INT_CNTL);
296 value = 0;
297
298 if (flag & RADEON_CRTC_VBLANK_MASK)
299 value |= DRM_RADEON_VBLANK_CRTC1;
300
301 if (flag & RADEON_CRTC2_VBLANK_MASK)
302 value |= DRM_RADEON_VBLANK_CRTC2;
303 return value;
304}
305
306int radeon_vblank_crtc_set(struct drm_device *dev, int64_t value)
307{
308 drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private;
309 if (value & ~(DRM_RADEON_VBLANK_CRTC1 | DRM_RADEON_VBLANK_CRTC2)) {
310 DRM_ERROR("called with invalid crtc 0x%x\n", (unsigned int)value);
311 return -EINVAL;
312 }
313 dev_priv->vblank_crtc = (unsigned int)value;
314 return 0;
315}
diff --git a/drivers/char/drm/radeon_mem.c b/drivers/char/drm/radeon_mem.c
deleted file mode 100644
index 4af5286a36fb..000000000000
--- a/drivers/char/drm/radeon_mem.c
+++ /dev/null
@@ -1,302 +0,0 @@
1/* radeon_mem.c -- Simple GART/fb memory manager for radeon -*- linux-c -*- */
2/*
3 * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved.
4 *
5 * The Weather Channel (TM) funded Tungsten Graphics to develop the
6 * initial release of the Radeon 8500 driver under the XFree86 license.
7 * This notice must be preserved.
8 *
9 * Permission is hereby granted, free of charge, to any person obtaining a
10 * copy of this software and associated documentation files (the "Software"),
11 * to deal in the Software without restriction, including without limitation
12 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
13 * and/or sell copies of the Software, and to permit persons to whom the
14 * Software is furnished to do so, subject to the following conditions:
15 *
16 * The above copyright notice and this permission notice (including the next
17 * paragraph) shall be included in all copies or substantial portions of the
18 * Software.
19 *
20 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
24 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
25 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 * DEALINGS IN THE SOFTWARE.
27 *
28 * Authors:
29 * Keith Whitwell <keith@tungstengraphics.com>
30 */
31
32#include "drmP.h"
33#include "drm.h"
34#include "radeon_drm.h"
35#include "radeon_drv.h"
36
37/* Very simple allocator for GART memory, working on a static range
38 * already mapped into each client's address space.
39 */
40
41static struct mem_block *split_block(struct mem_block *p, int start, int size,
42 struct drm_file *file_priv)
43{
44 /* Maybe cut off the start of an existing block */
45 if (start > p->start) {
46 struct mem_block *newblock =
47 drm_alloc(sizeof(*newblock), DRM_MEM_BUFS);
48 if (!newblock)
49 goto out;
50 newblock->start = start;
51 newblock->size = p->size - (start - p->start);
52 newblock->file_priv = NULL;
53 newblock->next = p->next;
54 newblock->prev = p;
55 p->next->prev = newblock;
56 p->next = newblock;
57 p->size -= newblock->size;
58 p = newblock;
59 }
60
61 /* Maybe cut off the end of an existing block */
62 if (size < p->size) {
63 struct mem_block *newblock =
64 drm_alloc(sizeof(*newblock), DRM_MEM_BUFS);
65 if (!newblock)
66 goto out;
67 newblock->start = start + size;
68 newblock->size = p->size - size;
69 newblock->file_priv = NULL;
70 newblock->next = p->next;
71 newblock->prev = p;
72 p->next->prev = newblock;
73 p->next = newblock;
74 p->size = size;
75 }
76
77 out:
78 /* Our block is in the middle */
79 p->file_priv = file_priv;
80 return p;
81}
82
83static struct mem_block *alloc_block(struct mem_block *heap, int size,
84 int align2, struct drm_file *file_priv)
85{
86 struct mem_block *p;
87 int mask = (1 << align2) - 1;
88
89 list_for_each(p, heap) {
90 int start = (p->start + mask) & ~mask;
91 if (p->file_priv == NULL && start + size <= p->start + p->size)
92 return split_block(p, start, size, file_priv);
93 }
94
95 return NULL;
96}
97
98static struct mem_block *find_block(struct mem_block *heap, int start)
99{
100 struct mem_block *p;
101
102 list_for_each(p, heap)
103 if (p->start == start)
104 return p;
105
106 return NULL;
107}
108
109static void free_block(struct mem_block *p)
110{
111 p->file_priv = NULL;
112
113 /* Assumes a single contiguous range. Needs a special file_priv in
114 * 'heap' to stop it being subsumed.
115 */
116 if (p->next->file_priv == NULL) {
117 struct mem_block *q = p->next;
118 p->size += q->size;
119 p->next = q->next;
120 p->next->prev = p;
121 drm_free(q, sizeof(*q), DRM_MEM_BUFS);
122 }
123
124 if (p->prev->file_priv == NULL) {
125 struct mem_block *q = p->prev;
126 q->size += p->size;
127 q->next = p->next;
128 q->next->prev = q;
129 drm_free(p, sizeof(*q), DRM_MEM_BUFS);
130 }
131}
132
133/* Initialize. How to check for an uninitialized heap?
134 */
135static int init_heap(struct mem_block **heap, int start, int size)
136{
137 struct mem_block *blocks = drm_alloc(sizeof(*blocks), DRM_MEM_BUFS);
138
139 if (!blocks)
140 return -ENOMEM;
141
142 *heap = drm_alloc(sizeof(**heap), DRM_MEM_BUFS);
143 if (!*heap) {
144 drm_free(blocks, sizeof(*blocks), DRM_MEM_BUFS);
145 return -ENOMEM;
146 }
147
148 blocks->start = start;
149 blocks->size = size;
150 blocks->file_priv = NULL;
151 blocks->next = blocks->prev = *heap;
152
153 memset(*heap, 0, sizeof(**heap));
154 (*heap)->file_priv = (struct drm_file *) - 1;
155 (*heap)->next = (*heap)->prev = blocks;
156 return 0;
157}
158
159/* Free all blocks associated with the releasing file.
160 */
161void radeon_mem_release(struct drm_file *file_priv, struct mem_block *heap)
162{
163 struct mem_block *p;
164
165 if (!heap || !heap->next)
166 return;
167
168 list_for_each(p, heap) {
169 if (p->file_priv == file_priv)
170 p->file_priv = NULL;
171 }
172
173 /* Assumes a single contiguous range. Needs a special file_priv in
174 * 'heap' to stop it being subsumed.
175 */
176 list_for_each(p, heap) {
177 while (p->file_priv == NULL && p->next->file_priv == NULL) {
178 struct mem_block *q = p->next;
179 p->size += q->size;
180 p->next = q->next;
181 p->next->prev = p;
182 drm_free(q, sizeof(*q), DRM_MEM_DRIVER);
183 }
184 }
185}
186
187/* Shutdown.
188 */
189void radeon_mem_takedown(struct mem_block **heap)
190{
191 struct mem_block *p;
192
193 if (!*heap)
194 return;
195
196 for (p = (*heap)->next; p != *heap;) {
197 struct mem_block *q = p;
198 p = p->next;
199 drm_free(q, sizeof(*q), DRM_MEM_DRIVER);
200 }
201
202 drm_free(*heap, sizeof(**heap), DRM_MEM_DRIVER);
203 *heap = NULL;
204}
205
206/* IOCTL HANDLERS */
207
208static struct mem_block **get_heap(drm_radeon_private_t * dev_priv, int region)
209{
210 switch (region) {
211 case RADEON_MEM_REGION_GART:
212 return &dev_priv->gart_heap;
213 case RADEON_MEM_REGION_FB:
214 return &dev_priv->fb_heap;
215 default:
216 return NULL;
217 }
218}
219
220int radeon_mem_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv)
221{
222 drm_radeon_private_t *dev_priv = dev->dev_private;
223 drm_radeon_mem_alloc_t *alloc = data;
224 struct mem_block *block, **heap;
225
226 if (!dev_priv) {
227 DRM_ERROR("called with no initialization\n");
228 return -EINVAL;
229 }
230
231 heap = get_heap(dev_priv, alloc->region);
232 if (!heap || !*heap)
233 return -EFAULT;
234
235 /* Make things easier on ourselves: all allocations at least
236 * 4k aligned.
237 */
238 if (alloc->alignment < 12)
239 alloc->alignment = 12;
240
241 block = alloc_block(*heap, alloc->size, alloc->alignment, file_priv);
242
243 if (!block)
244 return -ENOMEM;
245
246 if (DRM_COPY_TO_USER(alloc->region_offset, &block->start,
247 sizeof(int))) {
248 DRM_ERROR("copy_to_user\n");
249 return -EFAULT;
250 }
251
252 return 0;
253}
254
255int radeon_mem_free(struct drm_device *dev, void *data, struct drm_file *file_priv)
256{
257 drm_radeon_private_t *dev_priv = dev->dev_private;
258 drm_radeon_mem_free_t *memfree = data;
259 struct mem_block *block, **heap;
260
261 if (!dev_priv) {
262 DRM_ERROR("called with no initialization\n");
263 return -EINVAL;
264 }
265
266 heap = get_heap(dev_priv, memfree->region);
267 if (!heap || !*heap)
268 return -EFAULT;
269
270 block = find_block(*heap, memfree->region_offset);
271 if (!block)
272 return -EFAULT;
273
274 if (block->file_priv != file_priv)
275 return -EPERM;
276
277 free_block(block);
278 return 0;
279}
280
281int radeon_mem_init_heap(struct drm_device *dev, void *data, struct drm_file *file_priv)
282{
283 drm_radeon_private_t *dev_priv = dev->dev_private;
284 drm_radeon_mem_init_heap_t *initheap = data;
285 struct mem_block **heap;
286
287 if (!dev_priv) {
288 DRM_ERROR("called with no initialization\n");
289 return -EINVAL;
290 }
291
292 heap = get_heap(dev_priv, initheap->region);
293 if (!heap)
294 return -EFAULT;
295
296 if (*heap) {
297 DRM_ERROR("heap already initialized?");
298 return -EFAULT;
299 }
300
301 return init_heap(heap, initheap->start, initheap->size);
302}
diff --git a/drivers/char/drm/radeon_state.c b/drivers/char/drm/radeon_state.c
deleted file mode 100644
index 6f75512f591e..000000000000
--- a/drivers/char/drm/radeon_state.c
+++ /dev/null
@@ -1,3192 +0,0 @@
1/* radeon_state.c -- State support for Radeon -*- linux-c -*- */
2/*
3 * Copyright 2000 VA Linux Systems, Inc., Fremont, California.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the next
14 * paragraph) shall be included in all copies or substantial portions of the
15 * Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
21 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
22 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23 * DEALINGS IN THE SOFTWARE.
24 *
25 * Authors:
26 * Gareth Hughes <gareth@valinux.com>
27 * Kevin E. Martin <martin@valinux.com>
28 */
29
30#include "drmP.h"
31#include "drm.h"
32#include "drm_sarea.h"
33#include "radeon_drm.h"
34#include "radeon_drv.h"
35
36/* ================================================================
37 * Helper functions for client state checking and fixup
38 */
39
40static __inline__ int radeon_check_and_fixup_offset(drm_radeon_private_t *
41 dev_priv,
42 struct drm_file * file_priv,
43 u32 *offset)
44{
45 u64 off = *offset;
46 u32 fb_end = dev_priv->fb_location + dev_priv->fb_size - 1;
47 struct drm_radeon_driver_file_fields *radeon_priv;
48
49 /* Hrm ... the story of the offset ... So this function converts
50 * the various ideas of what userland clients might have for an
51 * offset in the card address space into an offset into the card
52 * address space :) So with a sane client, it should just keep
53 * the value intact and just do some boundary checking. However,
54 * not all clients are sane. Some older clients pass us 0 based
55 * offsets relative to the start of the framebuffer and some may
56 * assume the AGP aperture it appended to the framebuffer, so we
57 * try to detect those cases and fix them up.
58 *
59 * Note: It might be a good idea here to make sure the offset lands
60 * in some "allowed" area to protect things like the PCIE GART...
61 */
62
63 /* First, the best case, the offset already lands in either the
64 * framebuffer or the GART mapped space
65 */
66 if (radeon_check_offset(dev_priv, off))
67 return 0;
68
69 /* Ok, that didn't happen... now check if we have a zero based
70 * offset that fits in the framebuffer + gart space, apply the
71 * magic offset we get from SETPARAM or calculated from fb_location
72 */
73 if (off < (dev_priv->fb_size + dev_priv->gart_size)) {
74 radeon_priv = file_priv->driver_priv;
75 off += radeon_priv->radeon_fb_delta;
76 }
77
78 /* Finally, assume we aimed at a GART offset if beyond the fb */
79 if (off > fb_end)
80 off = off - fb_end - 1 + dev_priv->gart_vm_start;
81
82 /* Now recheck and fail if out of bounds */
83 if (radeon_check_offset(dev_priv, off)) {
84 DRM_DEBUG("offset fixed up to 0x%x\n", (unsigned int)off);
85 *offset = off;
86 return 0;
87 }
88 return -EINVAL;
89}
90
91static __inline__ int radeon_check_and_fixup_packets(drm_radeon_private_t *
92 dev_priv,
93 struct drm_file *file_priv,
94 int id, u32 *data)
95{
96 switch (id) {
97
98 case RADEON_EMIT_PP_MISC:
99 if (radeon_check_and_fixup_offset(dev_priv, file_priv,
100 &data[(RADEON_RB3D_DEPTHOFFSET - RADEON_PP_MISC) / 4])) {
101 DRM_ERROR("Invalid depth buffer offset\n");
102 return -EINVAL;
103 }
104 break;
105
106 case RADEON_EMIT_PP_CNTL:
107 if (radeon_check_and_fixup_offset(dev_priv, file_priv,
108 &data[(RADEON_RB3D_COLOROFFSET - RADEON_PP_CNTL) / 4])) {
109 DRM_ERROR("Invalid colour buffer offset\n");
110 return -EINVAL;
111 }
112 break;
113
114 case R200_EMIT_PP_TXOFFSET_0:
115 case R200_EMIT_PP_TXOFFSET_1:
116 case R200_EMIT_PP_TXOFFSET_2:
117 case R200_EMIT_PP_TXOFFSET_3:
118 case R200_EMIT_PP_TXOFFSET_4:
119 case R200_EMIT_PP_TXOFFSET_5:
120 if (radeon_check_and_fixup_offset(dev_priv, file_priv,
121 &data[0])) {
122 DRM_ERROR("Invalid R200 texture offset\n");
123 return -EINVAL;
124 }
125 break;
126
127 case RADEON_EMIT_PP_TXFILTER_0:
128 case RADEON_EMIT_PP_TXFILTER_1:
129 case RADEON_EMIT_PP_TXFILTER_2:
130 if (radeon_check_and_fixup_offset(dev_priv, file_priv,
131 &data[(RADEON_PP_TXOFFSET_0 - RADEON_PP_TXFILTER_0) / 4])) {
132 DRM_ERROR("Invalid R100 texture offset\n");
133 return -EINVAL;
134 }
135 break;
136
137 case R200_EMIT_PP_CUBIC_OFFSETS_0:
138 case R200_EMIT_PP_CUBIC_OFFSETS_1:
139 case R200_EMIT_PP_CUBIC_OFFSETS_2:
140 case R200_EMIT_PP_CUBIC_OFFSETS_3:
141 case R200_EMIT_PP_CUBIC_OFFSETS_4:
142 case R200_EMIT_PP_CUBIC_OFFSETS_5:{
143 int i;
144 for (i = 0; i < 5; i++) {
145 if (radeon_check_and_fixup_offset(dev_priv,
146 file_priv,
147 &data[i])) {
148 DRM_ERROR
149 ("Invalid R200 cubic texture offset\n");
150 return -EINVAL;
151 }
152 }
153 break;
154 }
155
156 case RADEON_EMIT_PP_CUBIC_OFFSETS_T0:
157 case RADEON_EMIT_PP_CUBIC_OFFSETS_T1:
158 case RADEON_EMIT_PP_CUBIC_OFFSETS_T2:{
159 int i;
160 for (i = 0; i < 5; i++) {
161 if (radeon_check_and_fixup_offset(dev_priv,
162 file_priv,
163 &data[i])) {
164 DRM_ERROR
165 ("Invalid R100 cubic texture offset\n");
166 return -EINVAL;
167 }
168 }
169 }
170 break;
171
172 case R200_EMIT_VAP_CTL:{
173 RING_LOCALS;
174 BEGIN_RING(2);
175 OUT_RING_REG(RADEON_SE_TCL_STATE_FLUSH, 0);
176 ADVANCE_RING();
177 }
178 break;
179
180 case RADEON_EMIT_RB3D_COLORPITCH:
181 case RADEON_EMIT_RE_LINE_PATTERN:
182 case RADEON_EMIT_SE_LINE_WIDTH:
183 case RADEON_EMIT_PP_LUM_MATRIX:
184 case RADEON_EMIT_PP_ROT_MATRIX_0:
185 case RADEON_EMIT_RB3D_STENCILREFMASK:
186 case RADEON_EMIT_SE_VPORT_XSCALE:
187 case RADEON_EMIT_SE_CNTL:
188 case RADEON_EMIT_SE_CNTL_STATUS:
189 case RADEON_EMIT_RE_MISC:
190 case RADEON_EMIT_PP_BORDER_COLOR_0:
191 case RADEON_EMIT_PP_BORDER_COLOR_1:
192 case RADEON_EMIT_PP_BORDER_COLOR_2:
193 case RADEON_EMIT_SE_ZBIAS_FACTOR:
194 case RADEON_EMIT_SE_TCL_OUTPUT_VTX_FMT:
195 case RADEON_EMIT_SE_TCL_MATERIAL_EMMISSIVE_RED:
196 case R200_EMIT_PP_TXCBLEND_0:
197 case R200_EMIT_PP_TXCBLEND_1:
198 case R200_EMIT_PP_TXCBLEND_2:
199 case R200_EMIT_PP_TXCBLEND_3:
200 case R200_EMIT_PP_TXCBLEND_4:
201 case R200_EMIT_PP_TXCBLEND_5:
202 case R200_EMIT_PP_TXCBLEND_6:
203 case R200_EMIT_PP_TXCBLEND_7:
204 case R200_EMIT_TCL_LIGHT_MODEL_CTL_0:
205 case R200_EMIT_TFACTOR_0:
206 case R200_EMIT_VTX_FMT_0:
207 case R200_EMIT_MATRIX_SELECT_0:
208 case R200_EMIT_TEX_PROC_CTL_2:
209 case R200_EMIT_TCL_UCP_VERT_BLEND_CTL:
210 case R200_EMIT_PP_TXFILTER_0:
211 case R200_EMIT_PP_TXFILTER_1:
212 case R200_EMIT_PP_TXFILTER_2:
213 case R200_EMIT_PP_TXFILTER_3:
214 case R200_EMIT_PP_TXFILTER_4:
215 case R200_EMIT_PP_TXFILTER_5:
216 case R200_EMIT_VTE_CNTL:
217 case R200_EMIT_OUTPUT_VTX_COMP_SEL:
218 case R200_EMIT_PP_TAM_DEBUG3:
219 case R200_EMIT_PP_CNTL_X:
220 case R200_EMIT_RB3D_DEPTHXY_OFFSET:
221 case R200_EMIT_RE_AUX_SCISSOR_CNTL:
222 case R200_EMIT_RE_SCISSOR_TL_0:
223 case R200_EMIT_RE_SCISSOR_TL_1:
224 case R200_EMIT_RE_SCISSOR_TL_2:
225 case R200_EMIT_SE_VAP_CNTL_STATUS:
226 case R200_EMIT_SE_VTX_STATE_CNTL:
227 case R200_EMIT_RE_POINTSIZE:
228 case R200_EMIT_TCL_INPUT_VTX_VECTOR_ADDR_0:
229 case R200_EMIT_PP_CUBIC_FACES_0:
230 case R200_EMIT_PP_CUBIC_FACES_1:
231 case R200_EMIT_PP_CUBIC_FACES_2:
232 case R200_EMIT_PP_CUBIC_FACES_3:
233 case R200_EMIT_PP_CUBIC_FACES_4:
234 case R200_EMIT_PP_CUBIC_FACES_5:
235 case RADEON_EMIT_PP_TEX_SIZE_0:
236 case RADEON_EMIT_PP_TEX_SIZE_1:
237 case RADEON_EMIT_PP_TEX_SIZE_2:
238 case R200_EMIT_RB3D_BLENDCOLOR:
239 case R200_EMIT_TCL_POINT_SPRITE_CNTL:
240 case RADEON_EMIT_PP_CUBIC_FACES_0:
241 case RADEON_EMIT_PP_CUBIC_FACES_1:
242 case RADEON_EMIT_PP_CUBIC_FACES_2:
243 case R200_EMIT_PP_TRI_PERF_CNTL:
244 case R200_EMIT_PP_AFS_0:
245 case R200_EMIT_PP_AFS_1:
246 case R200_EMIT_ATF_TFACTOR:
247 case R200_EMIT_PP_TXCTLALL_0:
248 case R200_EMIT_PP_TXCTLALL_1:
249 case R200_EMIT_PP_TXCTLALL_2:
250 case R200_EMIT_PP_TXCTLALL_3:
251 case R200_EMIT_PP_TXCTLALL_4:
252 case R200_EMIT_PP_TXCTLALL_5:
253 case R200_EMIT_VAP_PVS_CNTL:
254 /* These packets don't contain memory offsets */
255 break;
256
257 default:
258 DRM_ERROR("Unknown state packet ID %d\n", id);
259 return -EINVAL;
260 }
261
262 return 0;
263}
264
265static __inline__ int radeon_check_and_fixup_packet3(drm_radeon_private_t *
266 dev_priv,
267 struct drm_file *file_priv,
268 drm_radeon_kcmd_buffer_t *
269 cmdbuf,
270 unsigned int *cmdsz)
271{
272 u32 *cmd = (u32 *) cmdbuf->buf;
273 u32 offset, narrays;
274 int count, i, k;
275
276 *cmdsz = 2 + ((cmd[0] & RADEON_CP_PACKET_COUNT_MASK) >> 16);
277
278 if ((cmd[0] & 0xc0000000) != RADEON_CP_PACKET3) {
279 DRM_ERROR("Not a type 3 packet\n");
280 return -EINVAL;
281 }
282
283 if (4 * *cmdsz > cmdbuf->bufsz) {
284 DRM_ERROR("Packet size larger than size of data provided\n");
285 return -EINVAL;
286 }
287
288 switch(cmd[0] & 0xff00) {
289 /* XXX Are there old drivers needing other packets? */
290
291 case RADEON_3D_DRAW_IMMD:
292 case RADEON_3D_DRAW_VBUF:
293 case RADEON_3D_DRAW_INDX:
294 case RADEON_WAIT_FOR_IDLE:
295 case RADEON_CP_NOP:
296 case RADEON_3D_CLEAR_ZMASK:
297/* case RADEON_CP_NEXT_CHAR:
298 case RADEON_CP_PLY_NEXTSCAN:
299 case RADEON_CP_SET_SCISSORS: */ /* probably safe but will never need them? */
300 /* these packets are safe */
301 break;
302
303 case RADEON_CP_3D_DRAW_IMMD_2:
304 case RADEON_CP_3D_DRAW_VBUF_2:
305 case RADEON_CP_3D_DRAW_INDX_2:
306 case RADEON_3D_CLEAR_HIZ:
307 /* safe but r200 only */
308 if (dev_priv->microcode_version != UCODE_R200) {
309 DRM_ERROR("Invalid 3d packet for r100-class chip\n");
310 return -EINVAL;
311 }
312 break;
313
314 case RADEON_3D_LOAD_VBPNTR:
315 count = (cmd[0] >> 16) & 0x3fff;
316
317 if (count > 18) { /* 12 arrays max */
318 DRM_ERROR("Too large payload in 3D_LOAD_VBPNTR (count=%d)\n",
319 count);
320 return -EINVAL;
321 }
322
323 /* carefully check packet contents */
324 narrays = cmd[1] & ~0xc000;
325 k = 0;
326 i = 2;
327 while ((k < narrays) && (i < (count + 2))) {
328 i++; /* skip attribute field */
329 if (radeon_check_and_fixup_offset(dev_priv, file_priv,
330 &cmd[i])) {
331 DRM_ERROR
332 ("Invalid offset (k=%d i=%d) in 3D_LOAD_VBPNTR packet.\n",
333 k, i);
334 return -EINVAL;
335 }
336 k++;
337 i++;
338 if (k == narrays)
339 break;
340 /* have one more to process, they come in pairs */
341 if (radeon_check_and_fixup_offset(dev_priv,
342 file_priv, &cmd[i]))
343 {
344 DRM_ERROR
345 ("Invalid offset (k=%d i=%d) in 3D_LOAD_VBPNTR packet.\n",
346 k, i);
347 return -EINVAL;
348 }
349 k++;
350 i++;
351 }
352 /* do the counts match what we expect ? */
353 if ((k != narrays) || (i != (count + 2))) {
354 DRM_ERROR
355 ("Malformed 3D_LOAD_VBPNTR packet (k=%d i=%d narrays=%d count+1=%d).\n",
356 k, i, narrays, count + 1);
357 return -EINVAL;
358 }
359 break;
360
361 case RADEON_3D_RNDR_GEN_INDX_PRIM:
362 if (dev_priv->microcode_version != UCODE_R100) {
363 DRM_ERROR("Invalid 3d packet for r200-class chip\n");
364 return -EINVAL;
365 }
366 if (radeon_check_and_fixup_offset(dev_priv, file_priv, &cmd[1])) {
367 DRM_ERROR("Invalid rndr_gen_indx offset\n");
368 return -EINVAL;
369 }
370 break;
371
372 case RADEON_CP_INDX_BUFFER:
373 if (dev_priv->microcode_version != UCODE_R200) {
374 DRM_ERROR("Invalid 3d packet for r100-class chip\n");
375 return -EINVAL;
376 }
377 if ((cmd[1] & 0x8000ffff) != 0x80000810) {
378 DRM_ERROR("Invalid indx_buffer reg address %08X\n", cmd[1]);
379 return -EINVAL;
380 }
381 if (radeon_check_and_fixup_offset(dev_priv, file_priv, &cmd[2])) {
382 DRM_ERROR("Invalid indx_buffer offset is %08X\n", cmd[2]);
383 return -EINVAL;
384 }
385 break;
386
387 case RADEON_CNTL_HOSTDATA_BLT:
388 case RADEON_CNTL_PAINT_MULTI:
389 case RADEON_CNTL_BITBLT_MULTI:
390 /* MSB of opcode: next DWORD GUI_CNTL */
391 if (cmd[1] & (RADEON_GMC_SRC_PITCH_OFFSET_CNTL
392 | RADEON_GMC_DST_PITCH_OFFSET_CNTL)) {
393 offset = cmd[2] << 10;
394 if (radeon_check_and_fixup_offset
395 (dev_priv, file_priv, &offset)) {
396 DRM_ERROR("Invalid first packet offset\n");
397 return -EINVAL;
398 }
399 cmd[2] = (cmd[2] & 0xffc00000) | offset >> 10;
400 }
401
402 if ((cmd[1] & RADEON_GMC_SRC_PITCH_OFFSET_CNTL) &&
403 (cmd[1] & RADEON_GMC_DST_PITCH_OFFSET_CNTL)) {
404 offset = cmd[3] << 10;
405 if (radeon_check_and_fixup_offset
406 (dev_priv, file_priv, &offset)) {
407 DRM_ERROR("Invalid second packet offset\n");
408 return -EINVAL;
409 }
410 cmd[3] = (cmd[3] & 0xffc00000) | offset >> 10;
411 }
412 break;
413
414 default:
415 DRM_ERROR("Invalid packet type %x\n", cmd[0] & 0xff00);
416 return -EINVAL;
417 }
418
419 return 0;
420}
421
422/* ================================================================
423 * CP hardware state programming functions
424 */
425
426static __inline__ void radeon_emit_clip_rect(drm_radeon_private_t * dev_priv,
427 struct drm_clip_rect * box)
428{
429 RING_LOCALS;
430
431 DRM_DEBUG(" box: x1=%d y1=%d x2=%d y2=%d\n",
432 box->x1, box->y1, box->x2, box->y2);
433
434 BEGIN_RING(4);
435 OUT_RING(CP_PACKET0(RADEON_RE_TOP_LEFT, 0));
436 OUT_RING((box->y1 << 16) | box->x1);
437 OUT_RING(CP_PACKET0(RADEON_RE_WIDTH_HEIGHT, 0));
438 OUT_RING(((box->y2 - 1) << 16) | (box->x2 - 1));
439 ADVANCE_RING();
440}
441
442/* Emit 1.1 state
443 */
444static int radeon_emit_state(drm_radeon_private_t * dev_priv,
445 struct drm_file *file_priv,
446 drm_radeon_context_regs_t * ctx,
447 drm_radeon_texture_regs_t * tex,
448 unsigned int dirty)
449{
450 RING_LOCALS;
451 DRM_DEBUG("dirty=0x%08x\n", dirty);
452
453 if (dirty & RADEON_UPLOAD_CONTEXT) {
454 if (radeon_check_and_fixup_offset(dev_priv, file_priv,
455 &ctx->rb3d_depthoffset)) {
456 DRM_ERROR("Invalid depth buffer offset\n");
457 return -EINVAL;
458 }
459
460 if (radeon_check_and_fixup_offset(dev_priv, file_priv,
461 &ctx->rb3d_coloroffset)) {
462 DRM_ERROR("Invalid depth buffer offset\n");
463 return -EINVAL;
464 }
465
466 BEGIN_RING(14);
467 OUT_RING(CP_PACKET0(RADEON_PP_MISC, 6));
468 OUT_RING(ctx->pp_misc);
469 OUT_RING(ctx->pp_fog_color);
470 OUT_RING(ctx->re_solid_color);
471 OUT_RING(ctx->rb3d_blendcntl);
472 OUT_RING(ctx->rb3d_depthoffset);
473 OUT_RING(ctx->rb3d_depthpitch);
474 OUT_RING(ctx->rb3d_zstencilcntl);
475 OUT_RING(CP_PACKET0(RADEON_PP_CNTL, 2));
476 OUT_RING(ctx->pp_cntl);
477 OUT_RING(ctx->rb3d_cntl);
478 OUT_RING(ctx->rb3d_coloroffset);
479 OUT_RING(CP_PACKET0(RADEON_RB3D_COLORPITCH, 0));
480 OUT_RING(ctx->rb3d_colorpitch);
481 ADVANCE_RING();
482 }
483
484 if (dirty & RADEON_UPLOAD_VERTFMT) {
485 BEGIN_RING(2);
486 OUT_RING(CP_PACKET0(RADEON_SE_COORD_FMT, 0));
487 OUT_RING(ctx->se_coord_fmt);
488 ADVANCE_RING();
489 }
490
491 if (dirty & RADEON_UPLOAD_LINE) {
492 BEGIN_RING(5);
493 OUT_RING(CP_PACKET0(RADEON_RE_LINE_PATTERN, 1));
494 OUT_RING(ctx->re_line_pattern);
495 OUT_RING(ctx->re_line_state);
496 OUT_RING(CP_PACKET0(RADEON_SE_LINE_WIDTH, 0));
497 OUT_RING(ctx->se_line_width);
498 ADVANCE_RING();
499 }
500
501 if (dirty & RADEON_UPLOAD_BUMPMAP) {
502 BEGIN_RING(5);
503 OUT_RING(CP_PACKET0(RADEON_PP_LUM_MATRIX, 0));
504 OUT_RING(ctx->pp_lum_matrix);
505 OUT_RING(CP_PACKET0(RADEON_PP_ROT_MATRIX_0, 1));
506 OUT_RING(ctx->pp_rot_matrix_0);
507 OUT_RING(ctx->pp_rot_matrix_1);
508 ADVANCE_RING();
509 }
510
511 if (dirty & RADEON_UPLOAD_MASKS) {
512 BEGIN_RING(4);
513 OUT_RING(CP_PACKET0(RADEON_RB3D_STENCILREFMASK, 2));
514 OUT_RING(ctx->rb3d_stencilrefmask);
515 OUT_RING(ctx->rb3d_ropcntl);
516 OUT_RING(ctx->rb3d_planemask);
517 ADVANCE_RING();
518 }
519
520 if (dirty & RADEON_UPLOAD_VIEWPORT) {
521 BEGIN_RING(7);
522 OUT_RING(CP_PACKET0(RADEON_SE_VPORT_XSCALE, 5));
523 OUT_RING(ctx->se_vport_xscale);
524 OUT_RING(ctx->se_vport_xoffset);
525 OUT_RING(ctx->se_vport_yscale);
526 OUT_RING(ctx->se_vport_yoffset);
527 OUT_RING(ctx->se_vport_zscale);
528 OUT_RING(ctx->se_vport_zoffset);
529 ADVANCE_RING();
530 }
531
532 if (dirty & RADEON_UPLOAD_SETUP) {
533 BEGIN_RING(4);
534 OUT_RING(CP_PACKET0(RADEON_SE_CNTL, 0));
535 OUT_RING(ctx->se_cntl);
536 OUT_RING(CP_PACKET0(RADEON_SE_CNTL_STATUS, 0));
537 OUT_RING(ctx->se_cntl_status);
538 ADVANCE_RING();
539 }
540
541 if (dirty & RADEON_UPLOAD_MISC) {
542 BEGIN_RING(2);
543 OUT_RING(CP_PACKET0(RADEON_RE_MISC, 0));
544 OUT_RING(ctx->re_misc);
545 ADVANCE_RING();
546 }
547
548 if (dirty & RADEON_UPLOAD_TEX0) {
549 if (radeon_check_and_fixup_offset(dev_priv, file_priv,
550 &tex[0].pp_txoffset)) {
551 DRM_ERROR("Invalid texture offset for unit 0\n");
552 return -EINVAL;
553 }
554
555 BEGIN_RING(9);
556 OUT_RING(CP_PACKET0(RADEON_PP_TXFILTER_0, 5));
557 OUT_RING(tex[0].pp_txfilter);
558 OUT_RING(tex[0].pp_txformat);
559 OUT_RING(tex[0].pp_txoffset);
560 OUT_RING(tex[0].pp_txcblend);
561 OUT_RING(tex[0].pp_txablend);
562 OUT_RING(tex[0].pp_tfactor);
563 OUT_RING(CP_PACKET0(RADEON_PP_BORDER_COLOR_0, 0));
564 OUT_RING(tex[0].pp_border_color);
565 ADVANCE_RING();
566 }
567
568 if (dirty & RADEON_UPLOAD_TEX1) {
569 if (radeon_check_and_fixup_offset(dev_priv, file_priv,
570 &tex[1].pp_txoffset)) {
571 DRM_ERROR("Invalid texture offset for unit 1\n");
572 return -EINVAL;
573 }
574
575 BEGIN_RING(9);
576 OUT_RING(CP_PACKET0(RADEON_PP_TXFILTER_1, 5));
577 OUT_RING(tex[1].pp_txfilter);
578 OUT_RING(tex[1].pp_txformat);
579 OUT_RING(tex[1].pp_txoffset);
580 OUT_RING(tex[1].pp_txcblend);
581 OUT_RING(tex[1].pp_txablend);
582 OUT_RING(tex[1].pp_tfactor);
583 OUT_RING(CP_PACKET0(RADEON_PP_BORDER_COLOR_1, 0));
584 OUT_RING(tex[1].pp_border_color);
585 ADVANCE_RING();
586 }
587
588 if (dirty & RADEON_UPLOAD_TEX2) {
589 if (radeon_check_and_fixup_offset(dev_priv, file_priv,
590 &tex[2].pp_txoffset)) {
591 DRM_ERROR("Invalid texture offset for unit 2\n");
592 return -EINVAL;
593 }
594
595 BEGIN_RING(9);
596 OUT_RING(CP_PACKET0(RADEON_PP_TXFILTER_2, 5));
597 OUT_RING(tex[2].pp_txfilter);
598 OUT_RING(tex[2].pp_txformat);
599 OUT_RING(tex[2].pp_txoffset);
600 OUT_RING(tex[2].pp_txcblend);
601 OUT_RING(tex[2].pp_txablend);
602 OUT_RING(tex[2].pp_tfactor);
603 OUT_RING(CP_PACKET0(RADEON_PP_BORDER_COLOR_2, 0));
604 OUT_RING(tex[2].pp_border_color);
605 ADVANCE_RING();
606 }
607
608 return 0;
609}
610
611/* Emit 1.2 state
612 */
613static int radeon_emit_state2(drm_radeon_private_t * dev_priv,
614 struct drm_file *file_priv,
615 drm_radeon_state_t * state)
616{
617 RING_LOCALS;
618
619 if (state->dirty & RADEON_UPLOAD_ZBIAS) {
620 BEGIN_RING(3);
621 OUT_RING(CP_PACKET0(RADEON_SE_ZBIAS_FACTOR, 1));
622 OUT_RING(state->context2.se_zbias_factor);
623 OUT_RING(state->context2.se_zbias_constant);
624 ADVANCE_RING();
625 }
626
627 return radeon_emit_state(dev_priv, file_priv, &state->context,
628 state->tex, state->dirty);
629}
630
631/* New (1.3) state mechanism. 3 commands (packet, scalar, vector) in
632 * 1.3 cmdbuffers allow all previous state to be updated as well as
633 * the tcl scalar and vector areas.
634 */
635static struct {
636 int start;
637 int len;
638 const char *name;
639} packet[RADEON_MAX_STATE_PACKETS] = {
640 {RADEON_PP_MISC, 7, "RADEON_PP_MISC"},
641 {RADEON_PP_CNTL, 3, "RADEON_PP_CNTL"},
642 {RADEON_RB3D_COLORPITCH, 1, "RADEON_RB3D_COLORPITCH"},
643 {RADEON_RE_LINE_PATTERN, 2, "RADEON_RE_LINE_PATTERN"},
644 {RADEON_SE_LINE_WIDTH, 1, "RADEON_SE_LINE_WIDTH"},
645 {RADEON_PP_LUM_MATRIX, 1, "RADEON_PP_LUM_MATRIX"},
646 {RADEON_PP_ROT_MATRIX_0, 2, "RADEON_PP_ROT_MATRIX_0"},
647 {RADEON_RB3D_STENCILREFMASK, 3, "RADEON_RB3D_STENCILREFMASK"},
648 {RADEON_SE_VPORT_XSCALE, 6, "RADEON_SE_VPORT_XSCALE"},
649 {RADEON_SE_CNTL, 2, "RADEON_SE_CNTL"},
650 {RADEON_SE_CNTL_STATUS, 1, "RADEON_SE_CNTL_STATUS"},
651 {RADEON_RE_MISC, 1, "RADEON_RE_MISC"},
652 {RADEON_PP_TXFILTER_0, 6, "RADEON_PP_TXFILTER_0"},
653 {RADEON_PP_BORDER_COLOR_0, 1, "RADEON_PP_BORDER_COLOR_0"},
654 {RADEON_PP_TXFILTER_1, 6, "RADEON_PP_TXFILTER_1"},
655 {RADEON_PP_BORDER_COLOR_1, 1, "RADEON_PP_BORDER_COLOR_1"},
656 {RADEON_PP_TXFILTER_2, 6, "RADEON_PP_TXFILTER_2"},
657 {RADEON_PP_BORDER_COLOR_2, 1, "RADEON_PP_BORDER_COLOR_2"},
658 {RADEON_SE_ZBIAS_FACTOR, 2, "RADEON_SE_ZBIAS_FACTOR"},
659 {RADEON_SE_TCL_OUTPUT_VTX_FMT, 11, "RADEON_SE_TCL_OUTPUT_VTX_FMT"},
660 {RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED, 17,
661 "RADEON_SE_TCL_MATERIAL_EMMISSIVE_RED"},
662 {R200_PP_TXCBLEND_0, 4, "R200_PP_TXCBLEND_0"},
663 {R200_PP_TXCBLEND_1, 4, "R200_PP_TXCBLEND_1"},
664 {R200_PP_TXCBLEND_2, 4, "R200_PP_TXCBLEND_2"},
665 {R200_PP_TXCBLEND_3, 4, "R200_PP_TXCBLEND_3"},
666 {R200_PP_TXCBLEND_4, 4, "R200_PP_TXCBLEND_4"},
667 {R200_PP_TXCBLEND_5, 4, "R200_PP_TXCBLEND_5"},
668 {R200_PP_TXCBLEND_6, 4, "R200_PP_TXCBLEND_6"},
669 {R200_PP_TXCBLEND_7, 4, "R200_PP_TXCBLEND_7"},
670 {R200_SE_TCL_LIGHT_MODEL_CTL_0, 6, "R200_SE_TCL_LIGHT_MODEL_CTL_0"},
671 {R200_PP_TFACTOR_0, 6, "R200_PP_TFACTOR_0"},
672 {R200_SE_VTX_FMT_0, 4, "R200_SE_VTX_FMT_0"},
673 {R200_SE_VAP_CNTL, 1, "R200_SE_VAP_CNTL"},
674 {R200_SE_TCL_MATRIX_SEL_0, 5, "R200_SE_TCL_MATRIX_SEL_0"},
675 {R200_SE_TCL_TEX_PROC_CTL_2, 5, "R200_SE_TCL_TEX_PROC_CTL_2"},
676 {R200_SE_TCL_UCP_VERT_BLEND_CTL, 1, "R200_SE_TCL_UCP_VERT_BLEND_CTL"},
677 {R200_PP_TXFILTER_0, 6, "R200_PP_TXFILTER_0"},
678 {R200_PP_TXFILTER_1, 6, "R200_PP_TXFILTER_1"},
679 {R200_PP_TXFILTER_2, 6, "R200_PP_TXFILTER_2"},
680 {R200_PP_TXFILTER_3, 6, "R200_PP_TXFILTER_3"},
681 {R200_PP_TXFILTER_4, 6, "R200_PP_TXFILTER_4"},
682 {R200_PP_TXFILTER_5, 6, "R200_PP_TXFILTER_5"},
683 {R200_PP_TXOFFSET_0, 1, "R200_PP_TXOFFSET_0"},
684 {R200_PP_TXOFFSET_1, 1, "R200_PP_TXOFFSET_1"},
685 {R200_PP_TXOFFSET_2, 1, "R200_PP_TXOFFSET_2"},
686 {R200_PP_TXOFFSET_3, 1, "R200_PP_TXOFFSET_3"},
687 {R200_PP_TXOFFSET_4, 1, "R200_PP_TXOFFSET_4"},
688 {R200_PP_TXOFFSET_5, 1, "R200_PP_TXOFFSET_5"},
689 {R200_SE_VTE_CNTL, 1, "R200_SE_VTE_CNTL"},
690 {R200_SE_TCL_OUTPUT_VTX_COMP_SEL, 1,
691 "R200_SE_TCL_OUTPUT_VTX_COMP_SEL"},
692 {R200_PP_TAM_DEBUG3, 1, "R200_PP_TAM_DEBUG3"},
693 {R200_PP_CNTL_X, 1, "R200_PP_CNTL_X"},
694 {R200_RB3D_DEPTHXY_OFFSET, 1, "R200_RB3D_DEPTHXY_OFFSET"},
695 {R200_RE_AUX_SCISSOR_CNTL, 1, "R200_RE_AUX_SCISSOR_CNTL"},
696 {R200_RE_SCISSOR_TL_0, 2, "R200_RE_SCISSOR_TL_0"},
697 {R200_RE_SCISSOR_TL_1, 2, "R200_RE_SCISSOR_TL_1"},
698 {R200_RE_SCISSOR_TL_2, 2, "R200_RE_SCISSOR_TL_2"},
699 {R200_SE_VAP_CNTL_STATUS, 1, "R200_SE_VAP_CNTL_STATUS"},
700 {R200_SE_VTX_STATE_CNTL, 1, "R200_SE_VTX_STATE_CNTL"},
701 {R200_RE_POINTSIZE, 1, "R200_RE_POINTSIZE"},
702 {R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0, 4,
703 "R200_SE_TCL_INPUT_VTX_VECTOR_ADDR_0"},
704 {R200_PP_CUBIC_FACES_0, 1, "R200_PP_CUBIC_FACES_0"}, /* 61 */
705 {R200_PP_CUBIC_OFFSET_F1_0, 5, "R200_PP_CUBIC_OFFSET_F1_0"}, /* 62 */
706 {R200_PP_CUBIC_FACES_1, 1, "R200_PP_CUBIC_FACES_1"},
707 {R200_PP_CUBIC_OFFSET_F1_1, 5, "R200_PP_CUBIC_OFFSET_F1_1"},
708 {R200_PP_CUBIC_FACES_2, 1, "R200_PP_CUBIC_FACES_2"},
709 {R200_PP_CUBIC_OFFSET_F1_2, 5, "R200_PP_CUBIC_OFFSET_F1_2"},
710 {R200_PP_CUBIC_FACES_3, 1, "R200_PP_CUBIC_FACES_3"},
711 {R200_PP_CUBIC_OFFSET_F1_3, 5, "R200_PP_CUBIC_OFFSET_F1_3"},
712 {R200_PP_CUBIC_FACES_4, 1, "R200_PP_CUBIC_FACES_4"},
713 {R200_PP_CUBIC_OFFSET_F1_4, 5, "R200_PP_CUBIC_OFFSET_F1_4"},
714 {R200_PP_CUBIC_FACES_5, 1, "R200_PP_CUBIC_FACES_5"},
715 {R200_PP_CUBIC_OFFSET_F1_5, 5, "R200_PP_CUBIC_OFFSET_F1_5"},
716 {RADEON_PP_TEX_SIZE_0, 2, "RADEON_PP_TEX_SIZE_0"},
717 {RADEON_PP_TEX_SIZE_1, 2, "RADEON_PP_TEX_SIZE_1"},
718 {RADEON_PP_TEX_SIZE_2, 2, "RADEON_PP_TEX_SIZE_2"},
719 {R200_RB3D_BLENDCOLOR, 3, "R200_RB3D_BLENDCOLOR"},
720 {R200_SE_TCL_POINT_SPRITE_CNTL, 1, "R200_SE_TCL_POINT_SPRITE_CNTL"},
721 {RADEON_PP_CUBIC_FACES_0, 1, "RADEON_PP_CUBIC_FACES_0"},
722 {RADEON_PP_CUBIC_OFFSET_T0_0, 5, "RADEON_PP_CUBIC_OFFSET_T0_0"},
723 {RADEON_PP_CUBIC_FACES_1, 1, "RADEON_PP_CUBIC_FACES_1"},
724 {RADEON_PP_CUBIC_OFFSET_T1_0, 5, "RADEON_PP_CUBIC_OFFSET_T1_0"},
725 {RADEON_PP_CUBIC_FACES_2, 1, "RADEON_PP_CUBIC_FACES_2"},
726 {RADEON_PP_CUBIC_OFFSET_T2_0, 5, "RADEON_PP_CUBIC_OFFSET_T2_0"},
727 {R200_PP_TRI_PERF, 2, "R200_PP_TRI_PERF"},
728 {R200_PP_AFS_0, 32, "R200_PP_AFS_0"}, /* 85 */
729 {R200_PP_AFS_1, 32, "R200_PP_AFS_1"},
730 {R200_PP_TFACTOR_0, 8, "R200_ATF_TFACTOR"},
731 {R200_PP_TXFILTER_0, 8, "R200_PP_TXCTLALL_0"},
732 {R200_PP_TXFILTER_1, 8, "R200_PP_TXCTLALL_1"},
733 {R200_PP_TXFILTER_2, 8, "R200_PP_TXCTLALL_2"},
734 {R200_PP_TXFILTER_3, 8, "R200_PP_TXCTLALL_3"},
735 {R200_PP_TXFILTER_4, 8, "R200_PP_TXCTLALL_4"},
736 {R200_PP_TXFILTER_5, 8, "R200_PP_TXCTLALL_5"},
737 {R200_VAP_PVS_CNTL_1, 2, "R200_VAP_PVS_CNTL"},
738};
739
740/* ================================================================
741 * Performance monitoring functions
742 */
743
744static void radeon_clear_box(drm_radeon_private_t * dev_priv,
745 int x, int y, int w, int h, int r, int g, int b)
746{
747 u32 color;
748 RING_LOCALS;
749
750 x += dev_priv->sarea_priv->boxes[0].x1;
751 y += dev_priv->sarea_priv->boxes[0].y1;
752
753 switch (dev_priv->color_fmt) {
754 case RADEON_COLOR_FORMAT_RGB565:
755 color = (((r & 0xf8) << 8) |
756 ((g & 0xfc) << 3) | ((b & 0xf8) >> 3));
757 break;
758 case RADEON_COLOR_FORMAT_ARGB8888:
759 default:
760 color = (((0xff) << 24) | (r << 16) | (g << 8) | b);
761 break;
762 }
763
764 BEGIN_RING(4);
765 RADEON_WAIT_UNTIL_3D_IDLE();
766 OUT_RING(CP_PACKET0(RADEON_DP_WRITE_MASK, 0));
767 OUT_RING(0xffffffff);
768 ADVANCE_RING();
769
770 BEGIN_RING(6);
771
772 OUT_RING(CP_PACKET3(RADEON_CNTL_PAINT_MULTI, 4));
773 OUT_RING(RADEON_GMC_DST_PITCH_OFFSET_CNTL |
774 RADEON_GMC_BRUSH_SOLID_COLOR |
775 (dev_priv->color_fmt << 8) |
776 RADEON_GMC_SRC_DATATYPE_COLOR |
777 RADEON_ROP3_P | RADEON_GMC_CLR_CMP_CNTL_DIS);
778
779 if (dev_priv->sarea_priv->pfCurrentPage == 1) {
780 OUT_RING(dev_priv->front_pitch_offset);
781 } else {
782 OUT_RING(dev_priv->back_pitch_offset);
783 }
784
785 OUT_RING(color);
786
787 OUT_RING((x << 16) | y);
788 OUT_RING((w << 16) | h);
789
790 ADVANCE_RING();
791}
792
793static void radeon_cp_performance_boxes(drm_radeon_private_t * dev_priv)
794{
795 /* Collapse various things into a wait flag -- trying to
796 * guess if userspase slept -- better just to have them tell us.
797 */
798 if (dev_priv->stats.last_frame_reads > 1 ||
799 dev_priv->stats.last_clear_reads > dev_priv->stats.clears) {
800 dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
801 }
802
803 if (dev_priv->stats.freelist_loops) {
804 dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;
805 }
806
807 /* Purple box for page flipping
808 */
809 if (dev_priv->stats.boxes & RADEON_BOX_FLIP)
810 radeon_clear_box(dev_priv, 4, 4, 8, 8, 255, 0, 255);
811
812 /* Red box if we have to wait for idle at any point
813 */
814 if (dev_priv->stats.boxes & RADEON_BOX_WAIT_IDLE)
815 radeon_clear_box(dev_priv, 16, 4, 8, 8, 255, 0, 0);
816
817 /* Blue box: lost context?
818 */
819
820 /* Yellow box for texture swaps
821 */
822 if (dev_priv->stats.boxes & RADEON_BOX_TEXTURE_LOAD)
823 radeon_clear_box(dev_priv, 40, 4, 8, 8, 255, 255, 0);
824
825 /* Green box if hardware never idles (as far as we can tell)
826 */
827 if (!(dev_priv->stats.boxes & RADEON_BOX_DMA_IDLE))
828 radeon_clear_box(dev_priv, 64, 4, 8, 8, 0, 255, 0);
829
830 /* Draw bars indicating number of buffers allocated
831 * (not a great measure, easily confused)
832 */
833 if (dev_priv->stats.requested_bufs) {
834 if (dev_priv->stats.requested_bufs > 100)
835 dev_priv->stats.requested_bufs = 100;
836
837 radeon_clear_box(dev_priv, 4, 16,
838 dev_priv->stats.requested_bufs, 4,
839 196, 128, 128);
840 }
841
842 memset(&dev_priv->stats, 0, sizeof(dev_priv->stats));
843
844}
845
846/* ================================================================
847 * CP command dispatch functions
848 */
849
850static void radeon_cp_dispatch_clear(struct drm_device * dev,
851 drm_radeon_clear_t * clear,
852 drm_radeon_clear_rect_t * depth_boxes)
853{
854 drm_radeon_private_t *dev_priv = dev->dev_private;
855 drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
856 drm_radeon_depth_clear_t *depth_clear = &dev_priv->depth_clear;
857 int nbox = sarea_priv->nbox;
858 struct drm_clip_rect *pbox = sarea_priv->boxes;
859 unsigned int flags = clear->flags;
860 u32 rb3d_cntl = 0, rb3d_stencilrefmask = 0;
861 int i;
862 RING_LOCALS;
863 DRM_DEBUG("flags = 0x%x\n", flags);
864
865 dev_priv->stats.clears++;
866
867 if (dev_priv->sarea_priv->pfCurrentPage == 1) {
868 unsigned int tmp = flags;
869
870 flags &= ~(RADEON_FRONT | RADEON_BACK);
871 if (tmp & RADEON_FRONT)
872 flags |= RADEON_BACK;
873 if (tmp & RADEON_BACK)
874 flags |= RADEON_FRONT;
875 }
876
877 if (flags & (RADEON_FRONT | RADEON_BACK)) {
878
879 BEGIN_RING(4);
880
881 /* Ensure the 3D stream is idle before doing a
882 * 2D fill to clear the front or back buffer.
883 */
884 RADEON_WAIT_UNTIL_3D_IDLE();
885
886 OUT_RING(CP_PACKET0(RADEON_DP_WRITE_MASK, 0));
887 OUT_RING(clear->color_mask);
888
889 ADVANCE_RING();
890
891 /* Make sure we restore the 3D state next time.
892 */
893 dev_priv->sarea_priv->ctx_owner = 0;
894
895 for (i = 0; i < nbox; i++) {
896 int x = pbox[i].x1;
897 int y = pbox[i].y1;
898 int w = pbox[i].x2 - x;
899 int h = pbox[i].y2 - y;
900
901 DRM_DEBUG("%d,%d-%d,%d flags 0x%x\n",
902 x, y, w, h, flags);
903
904 if (flags & RADEON_FRONT) {
905 BEGIN_RING(6);
906
907 OUT_RING(CP_PACKET3
908 (RADEON_CNTL_PAINT_MULTI, 4));
909 OUT_RING(RADEON_GMC_DST_PITCH_OFFSET_CNTL |
910 RADEON_GMC_BRUSH_SOLID_COLOR |
911 (dev_priv->
912 color_fmt << 8) |
913 RADEON_GMC_SRC_DATATYPE_COLOR |
914 RADEON_ROP3_P |
915 RADEON_GMC_CLR_CMP_CNTL_DIS);
916
917 OUT_RING(dev_priv->front_pitch_offset);
918 OUT_RING(clear->clear_color);
919
920 OUT_RING((x << 16) | y);
921 OUT_RING((w << 16) | h);
922
923 ADVANCE_RING();
924 }
925
926 if (flags & RADEON_BACK) {
927 BEGIN_RING(6);
928
929 OUT_RING(CP_PACKET3
930 (RADEON_CNTL_PAINT_MULTI, 4));
931 OUT_RING(RADEON_GMC_DST_PITCH_OFFSET_CNTL |
932 RADEON_GMC_BRUSH_SOLID_COLOR |
933 (dev_priv->
934 color_fmt << 8) |
935 RADEON_GMC_SRC_DATATYPE_COLOR |
936 RADEON_ROP3_P |
937 RADEON_GMC_CLR_CMP_CNTL_DIS);
938
939 OUT_RING(dev_priv->back_pitch_offset);
940 OUT_RING(clear->clear_color);
941
942 OUT_RING((x << 16) | y);
943 OUT_RING((w << 16) | h);
944
945 ADVANCE_RING();
946 }
947 }
948 }
949
950 /* hyper z clear */
951 /* no docs available, based on reverse engeneering by Stephane Marchesin */
952 if ((flags & (RADEON_DEPTH | RADEON_STENCIL))
953 && (flags & RADEON_CLEAR_FASTZ)) {
954
955 int i;
956 int depthpixperline =
957 dev_priv->depth_fmt ==
958 RADEON_DEPTH_FORMAT_16BIT_INT_Z ? (dev_priv->depth_pitch /
959 2) : (dev_priv->
960 depth_pitch / 4);
961
962 u32 clearmask;
963
964 u32 tempRB3D_DEPTHCLEARVALUE = clear->clear_depth |
965 ((clear->depth_mask & 0xff) << 24);
966
967 /* Make sure we restore the 3D state next time.
968 * we haven't touched any "normal" state - still need this?
969 */
970 dev_priv->sarea_priv->ctx_owner = 0;
971
972 if ((dev_priv->flags & RADEON_HAS_HIERZ)
973 && (flags & RADEON_USE_HIERZ)) {
974 /* FIXME : reverse engineer that for Rx00 cards */
975 /* FIXME : the mask supposedly contains low-res z values. So can't set
976 just to the max (0xff? or actually 0x3fff?), need to take z clear
977 value into account? */
978 /* pattern seems to work for r100, though get slight
979 rendering errors with glxgears. If hierz is not enabled for r100,
980 only 4 bits which indicate clear (15,16,31,32, all zero) matter, the
981 other ones are ignored, and the same clear mask can be used. That's
982 very different behaviour than R200 which needs different clear mask
983 and different number of tiles to clear if hierz is enabled or not !?!
984 */
985 clearmask = (0xff << 22) | (0xff << 6) | 0x003f003f;
986 } else {
987 /* clear mask : chooses the clearing pattern.
988 rv250: could be used to clear only parts of macrotiles
989 (but that would get really complicated...)?
990 bit 0 and 1 (either or both of them ?!?!) are used to
991 not clear tile (or maybe one of the bits indicates if the tile is
992 compressed or not), bit 2 and 3 to not clear tile 1,...,.
993 Pattern is as follows:
994 | 0,1 | 4,5 | 8,9 |12,13|16,17|20,21|24,25|28,29|
995 bits -------------------------------------------------
996 | 2,3 | 6,7 |10,11|14,15|18,19|22,23|26,27|30,31|
997 rv100: clearmask covers 2x8 4x1 tiles, but one clear still
998 covers 256 pixels ?!?
999 */
1000 clearmask = 0x0;
1001 }
1002
1003 BEGIN_RING(8);
1004 RADEON_WAIT_UNTIL_2D_IDLE();
1005 OUT_RING_REG(RADEON_RB3D_DEPTHCLEARVALUE,
1006 tempRB3D_DEPTHCLEARVALUE);
1007 /* what offset is this exactly ? */
1008 OUT_RING_REG(RADEON_RB3D_ZMASKOFFSET, 0);
1009 /* need ctlstat, otherwise get some strange black flickering */
1010 OUT_RING_REG(RADEON_RB3D_ZCACHE_CTLSTAT,
1011 RADEON_RB3D_ZC_FLUSH_ALL);
1012 ADVANCE_RING();
1013
1014 for (i = 0; i < nbox; i++) {
1015 int tileoffset, nrtilesx, nrtilesy, j;
1016 /* it looks like r200 needs rv-style clears, at least if hierz is not enabled? */
1017 if ((dev_priv->flags & RADEON_HAS_HIERZ)
1018 && !(dev_priv->microcode_version == UCODE_R200)) {
1019 /* FIXME : figure this out for r200 (when hierz is enabled). Or
1020 maybe r200 actually doesn't need to put the low-res z value into
1021 the tile cache like r100, but just needs to clear the hi-level z-buffer?
1022 Works for R100, both with hierz and without.
1023 R100 seems to operate on 2x1 8x8 tiles, but...
1024 odd: offset/nrtiles need to be 64 pix (4 block) aligned? Potentially
1025 problematic with resolutions which are not 64 pix aligned? */
1026 tileoffset =
1027 ((pbox[i].y1 >> 3) * depthpixperline +
1028 pbox[i].x1) >> 6;
1029 nrtilesx =
1030 ((pbox[i].x2 & ~63) -
1031 (pbox[i].x1 & ~63)) >> 4;
1032 nrtilesy =
1033 (pbox[i].y2 >> 3) - (pbox[i].y1 >> 3);
1034 for (j = 0; j <= nrtilesy; j++) {
1035 BEGIN_RING(4);
1036 OUT_RING(CP_PACKET3
1037 (RADEON_3D_CLEAR_ZMASK, 2));
1038 /* first tile */
1039 OUT_RING(tileoffset * 8);
1040 /* the number of tiles to clear */
1041 OUT_RING(nrtilesx + 4);
1042 /* clear mask : chooses the clearing pattern. */
1043 OUT_RING(clearmask);
1044 ADVANCE_RING();
1045 tileoffset += depthpixperline >> 6;
1046 }
1047 } else if (dev_priv->microcode_version == UCODE_R200) {
1048 /* works for rv250. */
1049 /* find first macro tile (8x2 4x4 z-pixels on rv250) */
1050 tileoffset =
1051 ((pbox[i].y1 >> 3) * depthpixperline +
1052 pbox[i].x1) >> 5;
1053 nrtilesx =
1054 (pbox[i].x2 >> 5) - (pbox[i].x1 >> 5);
1055 nrtilesy =
1056 (pbox[i].y2 >> 3) - (pbox[i].y1 >> 3);
1057 for (j = 0; j <= nrtilesy; j++) {
1058 BEGIN_RING(4);
1059 OUT_RING(CP_PACKET3
1060 (RADEON_3D_CLEAR_ZMASK, 2));
1061 /* first tile */
1062 /* judging by the first tile offset needed, could possibly
1063 directly address/clear 4x4 tiles instead of 8x2 * 4x4
1064 macro tiles, though would still need clear mask for
1065 right/bottom if truely 4x4 granularity is desired ? */
1066 OUT_RING(tileoffset * 16);
1067 /* the number of tiles to clear */
1068 OUT_RING(nrtilesx + 1);
1069 /* clear mask : chooses the clearing pattern. */
1070 OUT_RING(clearmask);
1071 ADVANCE_RING();
1072 tileoffset += depthpixperline >> 5;
1073 }
1074 } else { /* rv 100 */
1075 /* rv100 might not need 64 pix alignment, who knows */
1076 /* offsets are, hmm, weird */
1077 tileoffset =
1078 ((pbox[i].y1 >> 4) * depthpixperline +
1079 pbox[i].x1) >> 6;
1080 nrtilesx =
1081 ((pbox[i].x2 & ~63) -
1082 (pbox[i].x1 & ~63)) >> 4;
1083 nrtilesy =
1084 (pbox[i].y2 >> 4) - (pbox[i].y1 >> 4);
1085 for (j = 0; j <= nrtilesy; j++) {
1086 BEGIN_RING(4);
1087 OUT_RING(CP_PACKET3
1088 (RADEON_3D_CLEAR_ZMASK, 2));
1089 OUT_RING(tileoffset * 128);
1090 /* the number of tiles to clear */
1091 OUT_RING(nrtilesx + 4);
1092 /* clear mask : chooses the clearing pattern. */
1093 OUT_RING(clearmask);
1094 ADVANCE_RING();
1095 tileoffset += depthpixperline >> 6;
1096 }
1097 }
1098 }
1099
1100 /* TODO don't always clear all hi-level z tiles */
1101 if ((dev_priv->flags & RADEON_HAS_HIERZ)
1102 && (dev_priv->microcode_version == UCODE_R200)
1103 && (flags & RADEON_USE_HIERZ))
1104 /* r100 and cards without hierarchical z-buffer have no high-level z-buffer */
1105 /* FIXME : the mask supposedly contains low-res z values. So can't set
1106 just to the max (0xff? or actually 0x3fff?), need to take z clear
1107 value into account? */
1108 {
1109 BEGIN_RING(4);
1110 OUT_RING(CP_PACKET3(RADEON_3D_CLEAR_HIZ, 2));
1111 OUT_RING(0x0); /* First tile */
1112 OUT_RING(0x3cc0);
1113 OUT_RING((0xff << 22) | (0xff << 6) | 0x003f003f);
1114 ADVANCE_RING();
1115 }
1116 }
1117
1118 /* We have to clear the depth and/or stencil buffers by
1119 * rendering a quad into just those buffers. Thus, we have to
1120 * make sure the 3D engine is configured correctly.
1121 */
1122 else if ((dev_priv->microcode_version == UCODE_R200) &&
1123 (flags & (RADEON_DEPTH | RADEON_STENCIL))) {
1124
1125 int tempPP_CNTL;
1126 int tempRE_CNTL;
1127 int tempRB3D_CNTL;
1128 int tempRB3D_ZSTENCILCNTL;
1129 int tempRB3D_STENCILREFMASK;
1130 int tempRB3D_PLANEMASK;
1131 int tempSE_CNTL;
1132 int tempSE_VTE_CNTL;
1133 int tempSE_VTX_FMT_0;
1134 int tempSE_VTX_FMT_1;
1135 int tempSE_VAP_CNTL;
1136 int tempRE_AUX_SCISSOR_CNTL;
1137
1138 tempPP_CNTL = 0;
1139 tempRE_CNTL = 0;
1140
1141 tempRB3D_CNTL = depth_clear->rb3d_cntl;
1142
1143 tempRB3D_ZSTENCILCNTL = depth_clear->rb3d_zstencilcntl;
1144 tempRB3D_STENCILREFMASK = 0x0;
1145
1146 tempSE_CNTL = depth_clear->se_cntl;
1147
1148 /* Disable TCL */
1149
1150 tempSE_VAP_CNTL = ( /* SE_VAP_CNTL__FORCE_W_TO_ONE_MASK | */
1151 (0x9 <<
1152 SE_VAP_CNTL__VF_MAX_VTX_NUM__SHIFT));
1153
1154 tempRB3D_PLANEMASK = 0x0;
1155
1156 tempRE_AUX_SCISSOR_CNTL = 0x0;
1157
1158 tempSE_VTE_CNTL =
1159 SE_VTE_CNTL__VTX_XY_FMT_MASK | SE_VTE_CNTL__VTX_Z_FMT_MASK;
1160
1161 /* Vertex format (X, Y, Z, W) */
1162 tempSE_VTX_FMT_0 =
1163 SE_VTX_FMT_0__VTX_Z0_PRESENT_MASK |
1164 SE_VTX_FMT_0__VTX_W0_PRESENT_MASK;
1165 tempSE_VTX_FMT_1 = 0x0;
1166
1167 /*
1168 * Depth buffer specific enables
1169 */
1170 if (flags & RADEON_DEPTH) {
1171 /* Enable depth buffer */
1172 tempRB3D_CNTL |= RADEON_Z_ENABLE;
1173 } else {
1174 /* Disable depth buffer */
1175 tempRB3D_CNTL &= ~RADEON_Z_ENABLE;
1176 }
1177
1178 /*
1179 * Stencil buffer specific enables
1180 */
1181 if (flags & RADEON_STENCIL) {
1182 tempRB3D_CNTL |= RADEON_STENCIL_ENABLE;
1183 tempRB3D_STENCILREFMASK = clear->depth_mask;
1184 } else {
1185 tempRB3D_CNTL &= ~RADEON_STENCIL_ENABLE;
1186 tempRB3D_STENCILREFMASK = 0x00000000;
1187 }
1188
1189 if (flags & RADEON_USE_COMP_ZBUF) {
1190 tempRB3D_ZSTENCILCNTL |= RADEON_Z_COMPRESSION_ENABLE |
1191 RADEON_Z_DECOMPRESSION_ENABLE;
1192 }
1193 if (flags & RADEON_USE_HIERZ) {
1194 tempRB3D_ZSTENCILCNTL |= RADEON_Z_HIERARCHY_ENABLE;
1195 }
1196
1197 BEGIN_RING(26);
1198 RADEON_WAIT_UNTIL_2D_IDLE();
1199
1200 OUT_RING_REG(RADEON_PP_CNTL, tempPP_CNTL);
1201 OUT_RING_REG(R200_RE_CNTL, tempRE_CNTL);
1202 OUT_RING_REG(RADEON_RB3D_CNTL, tempRB3D_CNTL);
1203 OUT_RING_REG(RADEON_RB3D_ZSTENCILCNTL, tempRB3D_ZSTENCILCNTL);
1204 OUT_RING_REG(RADEON_RB3D_STENCILREFMASK,
1205 tempRB3D_STENCILREFMASK);
1206 OUT_RING_REG(RADEON_RB3D_PLANEMASK, tempRB3D_PLANEMASK);
1207 OUT_RING_REG(RADEON_SE_CNTL, tempSE_CNTL);
1208 OUT_RING_REG(R200_SE_VTE_CNTL, tempSE_VTE_CNTL);
1209 OUT_RING_REG(R200_SE_VTX_FMT_0, tempSE_VTX_FMT_0);
1210 OUT_RING_REG(R200_SE_VTX_FMT_1, tempSE_VTX_FMT_1);
1211 OUT_RING_REG(R200_SE_VAP_CNTL, tempSE_VAP_CNTL);
1212 OUT_RING_REG(R200_RE_AUX_SCISSOR_CNTL, tempRE_AUX_SCISSOR_CNTL);
1213 ADVANCE_RING();
1214
1215 /* Make sure we restore the 3D state next time.
1216 */
1217 dev_priv->sarea_priv->ctx_owner = 0;
1218
1219 for (i = 0; i < nbox; i++) {
1220
1221 /* Funny that this should be required --
1222 * sets top-left?
1223 */
1224 radeon_emit_clip_rect(dev_priv, &sarea_priv->boxes[i]);
1225
1226 BEGIN_RING(14);
1227 OUT_RING(CP_PACKET3(R200_3D_DRAW_IMMD_2, 12));
1228 OUT_RING((RADEON_PRIM_TYPE_RECT_LIST |
1229 RADEON_PRIM_WALK_RING |
1230 (3 << RADEON_NUM_VERTICES_SHIFT)));
1231 OUT_RING(depth_boxes[i].ui[CLEAR_X1]);
1232 OUT_RING(depth_boxes[i].ui[CLEAR_Y1]);
1233 OUT_RING(depth_boxes[i].ui[CLEAR_DEPTH]);
1234 OUT_RING(0x3f800000);
1235 OUT_RING(depth_boxes[i].ui[CLEAR_X1]);
1236 OUT_RING(depth_boxes[i].ui[CLEAR_Y2]);
1237 OUT_RING(depth_boxes[i].ui[CLEAR_DEPTH]);
1238 OUT_RING(0x3f800000);
1239 OUT_RING(depth_boxes[i].ui[CLEAR_X2]);
1240 OUT_RING(depth_boxes[i].ui[CLEAR_Y2]);
1241 OUT_RING(depth_boxes[i].ui[CLEAR_DEPTH]);
1242 OUT_RING(0x3f800000);
1243 ADVANCE_RING();
1244 }
1245 } else if ((flags & (RADEON_DEPTH | RADEON_STENCIL))) {
1246
1247 int tempRB3D_ZSTENCILCNTL = depth_clear->rb3d_zstencilcntl;
1248
1249 rb3d_cntl = depth_clear->rb3d_cntl;
1250
1251 if (flags & RADEON_DEPTH) {
1252 rb3d_cntl |= RADEON_Z_ENABLE;
1253 } else {
1254 rb3d_cntl &= ~RADEON_Z_ENABLE;
1255 }
1256
1257 if (flags & RADEON_STENCIL) {
1258 rb3d_cntl |= RADEON_STENCIL_ENABLE;
1259 rb3d_stencilrefmask = clear->depth_mask; /* misnamed field */
1260 } else {
1261 rb3d_cntl &= ~RADEON_STENCIL_ENABLE;
1262 rb3d_stencilrefmask = 0x00000000;
1263 }
1264
1265 if (flags & RADEON_USE_COMP_ZBUF) {
1266 tempRB3D_ZSTENCILCNTL |= RADEON_Z_COMPRESSION_ENABLE |
1267 RADEON_Z_DECOMPRESSION_ENABLE;
1268 }
1269 if (flags & RADEON_USE_HIERZ) {
1270 tempRB3D_ZSTENCILCNTL |= RADEON_Z_HIERARCHY_ENABLE;
1271 }
1272
1273 BEGIN_RING(13);
1274 RADEON_WAIT_UNTIL_2D_IDLE();
1275
1276 OUT_RING(CP_PACKET0(RADEON_PP_CNTL, 1));
1277 OUT_RING(0x00000000);
1278 OUT_RING(rb3d_cntl);
1279
1280 OUT_RING_REG(RADEON_RB3D_ZSTENCILCNTL, tempRB3D_ZSTENCILCNTL);
1281 OUT_RING_REG(RADEON_RB3D_STENCILREFMASK, rb3d_stencilrefmask);
1282 OUT_RING_REG(RADEON_RB3D_PLANEMASK, 0x00000000);
1283 OUT_RING_REG(RADEON_SE_CNTL, depth_clear->se_cntl);
1284 ADVANCE_RING();
1285
1286 /* Make sure we restore the 3D state next time.
1287 */
1288 dev_priv->sarea_priv->ctx_owner = 0;
1289
1290 for (i = 0; i < nbox; i++) {
1291
1292 /* Funny that this should be required --
1293 * sets top-left?
1294 */
1295 radeon_emit_clip_rect(dev_priv, &sarea_priv->boxes[i]);
1296
1297 BEGIN_RING(15);
1298
1299 OUT_RING(CP_PACKET3(RADEON_3D_DRAW_IMMD, 13));
1300 OUT_RING(RADEON_VTX_Z_PRESENT |
1301 RADEON_VTX_PKCOLOR_PRESENT);
1302 OUT_RING((RADEON_PRIM_TYPE_RECT_LIST |
1303 RADEON_PRIM_WALK_RING |
1304 RADEON_MAOS_ENABLE |
1305 RADEON_VTX_FMT_RADEON_MODE |
1306 (3 << RADEON_NUM_VERTICES_SHIFT)));
1307
1308 OUT_RING(depth_boxes[i].ui[CLEAR_X1]);
1309 OUT_RING(depth_boxes[i].ui[CLEAR_Y1]);
1310 OUT_RING(depth_boxes[i].ui[CLEAR_DEPTH]);
1311 OUT_RING(0x0);
1312
1313 OUT_RING(depth_boxes[i].ui[CLEAR_X1]);
1314 OUT_RING(depth_boxes[i].ui[CLEAR_Y2]);
1315 OUT_RING(depth_boxes[i].ui[CLEAR_DEPTH]);
1316 OUT_RING(0x0);
1317
1318 OUT_RING(depth_boxes[i].ui[CLEAR_X2]);
1319 OUT_RING(depth_boxes[i].ui[CLEAR_Y2]);
1320 OUT_RING(depth_boxes[i].ui[CLEAR_DEPTH]);
1321 OUT_RING(0x0);
1322
1323 ADVANCE_RING();
1324 }
1325 }
1326
1327 /* Increment the clear counter. The client-side 3D driver must
1328 * wait on this value before performing the clear ioctl. We
1329 * need this because the card's so damned fast...
1330 */
1331 dev_priv->sarea_priv->last_clear++;
1332
1333 BEGIN_RING(4);
1334
1335 RADEON_CLEAR_AGE(dev_priv->sarea_priv->last_clear);
1336 RADEON_WAIT_UNTIL_IDLE();
1337
1338 ADVANCE_RING();
1339}
1340
1341static void radeon_cp_dispatch_swap(struct drm_device * dev)
1342{
1343 drm_radeon_private_t *dev_priv = dev->dev_private;
1344 drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
1345 int nbox = sarea_priv->nbox;
1346 struct drm_clip_rect *pbox = sarea_priv->boxes;
1347 int i;
1348 RING_LOCALS;
1349 DRM_DEBUG("\n");
1350
1351 /* Do some trivial performance monitoring...
1352 */
1353 if (dev_priv->do_boxes)
1354 radeon_cp_performance_boxes(dev_priv);
1355
1356 /* Wait for the 3D stream to idle before dispatching the bitblt.
1357 * This will prevent data corruption between the two streams.
1358 */
1359 BEGIN_RING(2);
1360
1361 RADEON_WAIT_UNTIL_3D_IDLE();
1362
1363 ADVANCE_RING();
1364
1365 for (i = 0; i < nbox; i++) {
1366 int x = pbox[i].x1;
1367 int y = pbox[i].y1;
1368 int w = pbox[i].x2 - x;
1369 int h = pbox[i].y2 - y;
1370
1371 DRM_DEBUG("%d,%d-%d,%d\n", x, y, w, h);
1372
1373 BEGIN_RING(9);
1374
1375 OUT_RING(CP_PACKET0(RADEON_DP_GUI_MASTER_CNTL, 0));
1376 OUT_RING(RADEON_GMC_SRC_PITCH_OFFSET_CNTL |
1377 RADEON_GMC_DST_PITCH_OFFSET_CNTL |
1378 RADEON_GMC_BRUSH_NONE |
1379 (dev_priv->color_fmt << 8) |
1380 RADEON_GMC_SRC_DATATYPE_COLOR |
1381 RADEON_ROP3_S |
1382 RADEON_DP_SRC_SOURCE_MEMORY |
1383 RADEON_GMC_CLR_CMP_CNTL_DIS | RADEON_GMC_WR_MSK_DIS);
1384
1385 /* Make this work even if front & back are flipped:
1386 */
1387 OUT_RING(CP_PACKET0(RADEON_SRC_PITCH_OFFSET, 1));
1388 if (dev_priv->sarea_priv->pfCurrentPage == 0) {
1389 OUT_RING(dev_priv->back_pitch_offset);
1390 OUT_RING(dev_priv->front_pitch_offset);
1391 } else {
1392 OUT_RING(dev_priv->front_pitch_offset);
1393 OUT_RING(dev_priv->back_pitch_offset);
1394 }
1395
1396 OUT_RING(CP_PACKET0(RADEON_SRC_X_Y, 2));
1397 OUT_RING((x << 16) | y);
1398 OUT_RING((x << 16) | y);
1399 OUT_RING((w << 16) | h);
1400
1401 ADVANCE_RING();
1402 }
1403
1404 /* Increment the frame counter. The client-side 3D driver must
1405 * throttle the framerate by waiting for this value before
1406 * performing the swapbuffer ioctl.
1407 */
1408 dev_priv->sarea_priv->last_frame++;
1409
1410 BEGIN_RING(4);
1411
1412 RADEON_FRAME_AGE(dev_priv->sarea_priv->last_frame);
1413 RADEON_WAIT_UNTIL_2D_IDLE();
1414
1415 ADVANCE_RING();
1416}
1417
1418static void radeon_cp_dispatch_flip(struct drm_device * dev)
1419{
1420 drm_radeon_private_t *dev_priv = dev->dev_private;
1421 struct drm_sarea *sarea = (struct drm_sarea *) dev_priv->sarea->handle;
1422 int offset = (dev_priv->sarea_priv->pfCurrentPage == 1)
1423 ? dev_priv->front_offset : dev_priv->back_offset;
1424 RING_LOCALS;
1425 DRM_DEBUG("pfCurrentPage=%d\n",
1426 dev_priv->sarea_priv->pfCurrentPage);
1427
1428 /* Do some trivial performance monitoring...
1429 */
1430 if (dev_priv->do_boxes) {
1431 dev_priv->stats.boxes |= RADEON_BOX_FLIP;
1432 radeon_cp_performance_boxes(dev_priv);
1433 }
1434
1435 /* Update the frame offsets for both CRTCs
1436 */
1437 BEGIN_RING(6);
1438
1439 RADEON_WAIT_UNTIL_3D_IDLE();
1440 OUT_RING_REG(RADEON_CRTC_OFFSET,
1441 ((sarea->frame.y * dev_priv->front_pitch +
1442 sarea->frame.x * (dev_priv->color_fmt - 2)) & ~7)
1443 + offset);
1444 OUT_RING_REG(RADEON_CRTC2_OFFSET, dev_priv->sarea_priv->crtc2_base
1445 + offset);
1446
1447 ADVANCE_RING();
1448
1449 /* Increment the frame counter. The client-side 3D driver must
1450 * throttle the framerate by waiting for this value before
1451 * performing the swapbuffer ioctl.
1452 */
1453 dev_priv->sarea_priv->last_frame++;
1454 dev_priv->sarea_priv->pfCurrentPage =
1455 1 - dev_priv->sarea_priv->pfCurrentPage;
1456
1457 BEGIN_RING(2);
1458
1459 RADEON_FRAME_AGE(dev_priv->sarea_priv->last_frame);
1460
1461 ADVANCE_RING();
1462}
1463
1464static int bad_prim_vertex_nr(int primitive, int nr)
1465{
1466 switch (primitive & RADEON_PRIM_TYPE_MASK) {
1467 case RADEON_PRIM_TYPE_NONE:
1468 case RADEON_PRIM_TYPE_POINT:
1469 return nr < 1;
1470 case RADEON_PRIM_TYPE_LINE:
1471 return (nr & 1) || nr == 0;
1472 case RADEON_PRIM_TYPE_LINE_STRIP:
1473 return nr < 2;
1474 case RADEON_PRIM_TYPE_TRI_LIST:
1475 case RADEON_PRIM_TYPE_3VRT_POINT_LIST:
1476 case RADEON_PRIM_TYPE_3VRT_LINE_LIST:
1477 case RADEON_PRIM_TYPE_RECT_LIST:
1478 return nr % 3 || nr == 0;
1479 case RADEON_PRIM_TYPE_TRI_FAN:
1480 case RADEON_PRIM_TYPE_TRI_STRIP:
1481 return nr < 3;
1482 default:
1483 return 1;
1484 }
1485}
1486
1487typedef struct {
1488 unsigned int start;
1489 unsigned int finish;
1490 unsigned int prim;
1491 unsigned int numverts;
1492 unsigned int offset;
1493 unsigned int vc_format;
1494} drm_radeon_tcl_prim_t;
1495
1496static void radeon_cp_dispatch_vertex(struct drm_device * dev,
1497 struct drm_buf * buf,
1498 drm_radeon_tcl_prim_t * prim)
1499{
1500 drm_radeon_private_t *dev_priv = dev->dev_private;
1501 drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
1502 int offset = dev_priv->gart_buffers_offset + buf->offset + prim->start;
1503 int numverts = (int)prim->numverts;
1504 int nbox = sarea_priv->nbox;
1505 int i = 0;
1506 RING_LOCALS;
1507
1508 DRM_DEBUG("hwprim 0x%x vfmt 0x%x %d..%d %d verts\n",
1509 prim->prim,
1510 prim->vc_format, prim->start, prim->finish, prim->numverts);
1511
1512 if (bad_prim_vertex_nr(prim->prim, prim->numverts)) {
1513 DRM_ERROR("bad prim %x numverts %d\n",
1514 prim->prim, prim->numverts);
1515 return;
1516 }
1517
1518 do {
1519 /* Emit the next cliprect */
1520 if (i < nbox) {
1521 radeon_emit_clip_rect(dev_priv, &sarea_priv->boxes[i]);
1522 }
1523
1524 /* Emit the vertex buffer rendering commands */
1525 BEGIN_RING(5);
1526
1527 OUT_RING(CP_PACKET3(RADEON_3D_RNDR_GEN_INDX_PRIM, 3));
1528 OUT_RING(offset);
1529 OUT_RING(numverts);
1530 OUT_RING(prim->vc_format);
1531 OUT_RING(prim->prim | RADEON_PRIM_WALK_LIST |
1532 RADEON_COLOR_ORDER_RGBA |
1533 RADEON_VTX_FMT_RADEON_MODE |
1534 (numverts << RADEON_NUM_VERTICES_SHIFT));
1535
1536 ADVANCE_RING();
1537
1538 i++;
1539 } while (i < nbox);
1540}
1541
1542static void radeon_cp_discard_buffer(struct drm_device * dev, struct drm_buf * buf)
1543{
1544 drm_radeon_private_t *dev_priv = dev->dev_private;
1545 drm_radeon_buf_priv_t *buf_priv = buf->dev_private;
1546 RING_LOCALS;
1547
1548 buf_priv->age = ++dev_priv->sarea_priv->last_dispatch;
1549
1550 /* Emit the vertex buffer age */
1551 BEGIN_RING(2);
1552 RADEON_DISPATCH_AGE(buf_priv->age);
1553 ADVANCE_RING();
1554
1555 buf->pending = 1;
1556 buf->used = 0;
1557}
1558
1559static void radeon_cp_dispatch_indirect(struct drm_device * dev,
1560 struct drm_buf * buf, int start, int end)
1561{
1562 drm_radeon_private_t *dev_priv = dev->dev_private;
1563 RING_LOCALS;
1564 DRM_DEBUG("buf=%d s=0x%x e=0x%x\n", buf->idx, start, end);
1565
1566 if (start != end) {
1567 int offset = (dev_priv->gart_buffers_offset
1568 + buf->offset + start);
1569 int dwords = (end - start + 3) / sizeof(u32);
1570
1571 /* Indirect buffer data must be an even number of
1572 * dwords, so if we've been given an odd number we must
1573 * pad the data with a Type-2 CP packet.
1574 */
1575 if (dwords & 1) {
1576 u32 *data = (u32 *)
1577 ((char *)dev->agp_buffer_map->handle
1578 + buf->offset + start);
1579 data[dwords++] = RADEON_CP_PACKET2;
1580 }
1581
1582 /* Fire off the indirect buffer */
1583 BEGIN_RING(3);
1584
1585 OUT_RING(CP_PACKET0(RADEON_CP_IB_BASE, 1));
1586 OUT_RING(offset);
1587 OUT_RING(dwords);
1588
1589 ADVANCE_RING();
1590 }
1591}
1592
1593static void radeon_cp_dispatch_indices(struct drm_device * dev,
1594 struct drm_buf * elt_buf,
1595 drm_radeon_tcl_prim_t * prim)
1596{
1597 drm_radeon_private_t *dev_priv = dev->dev_private;
1598 drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
1599 int offset = dev_priv->gart_buffers_offset + prim->offset;
1600 u32 *data;
1601 int dwords;
1602 int i = 0;
1603 int start = prim->start + RADEON_INDEX_PRIM_OFFSET;
1604 int count = (prim->finish - start) / sizeof(u16);
1605 int nbox = sarea_priv->nbox;
1606
1607 DRM_DEBUG("hwprim 0x%x vfmt 0x%x %d..%d offset: %x nr %d\n",
1608 prim->prim,
1609 prim->vc_format,
1610 prim->start, prim->finish, prim->offset, prim->numverts);
1611
1612 if (bad_prim_vertex_nr(prim->prim, count)) {
1613 DRM_ERROR("bad prim %x count %d\n", prim->prim, count);
1614 return;
1615 }
1616
1617 if (start >= prim->finish || (prim->start & 0x7)) {
1618 DRM_ERROR("buffer prim %d\n", prim->prim);
1619 return;
1620 }
1621
1622 dwords = (prim->finish - prim->start + 3) / sizeof(u32);
1623
1624 data = (u32 *) ((char *)dev->agp_buffer_map->handle +
1625 elt_buf->offset + prim->start);
1626
1627 data[0] = CP_PACKET3(RADEON_3D_RNDR_GEN_INDX_PRIM, dwords - 2);
1628 data[1] = offset;
1629 data[2] = prim->numverts;
1630 data[3] = prim->vc_format;
1631 data[4] = (prim->prim |
1632 RADEON_PRIM_WALK_IND |
1633 RADEON_COLOR_ORDER_RGBA |
1634 RADEON_VTX_FMT_RADEON_MODE |
1635 (count << RADEON_NUM_VERTICES_SHIFT));
1636
1637 do {
1638 if (i < nbox)
1639 radeon_emit_clip_rect(dev_priv, &sarea_priv->boxes[i]);
1640
1641 radeon_cp_dispatch_indirect(dev, elt_buf,
1642 prim->start, prim->finish);
1643
1644 i++;
1645 } while (i < nbox);
1646
1647}
1648
1649#define RADEON_MAX_TEXTURE_SIZE RADEON_BUFFER_SIZE
1650
1651static int radeon_cp_dispatch_texture(struct drm_device * dev,
1652 struct drm_file *file_priv,
1653 drm_radeon_texture_t * tex,
1654 drm_radeon_tex_image_t * image)
1655{
1656 drm_radeon_private_t *dev_priv = dev->dev_private;
1657 struct drm_buf *buf;
1658 u32 format;
1659 u32 *buffer;
1660 const u8 __user *data;
1661 int size, dwords, tex_width, blit_width, spitch;
1662 u32 height;
1663 int i;
1664 u32 texpitch, microtile;
1665 u32 offset;
1666 RING_LOCALS;
1667
1668 if (radeon_check_and_fixup_offset(dev_priv, file_priv, &tex->offset)) {
1669 DRM_ERROR("Invalid destination offset\n");
1670 return -EINVAL;
1671 }
1672
1673 dev_priv->stats.boxes |= RADEON_BOX_TEXTURE_LOAD;
1674
1675 /* Flush the pixel cache. This ensures no pixel data gets mixed
1676 * up with the texture data from the host data blit, otherwise
1677 * part of the texture image may be corrupted.
1678 */
1679 BEGIN_RING(4);
1680 RADEON_FLUSH_CACHE();
1681 RADEON_WAIT_UNTIL_IDLE();
1682 ADVANCE_RING();
1683
1684 /* The compiler won't optimize away a division by a variable,
1685 * even if the only legal values are powers of two. Thus, we'll
1686 * use a shift instead.
1687 */
1688 switch (tex->format) {
1689 case RADEON_TXFORMAT_ARGB8888:
1690 case RADEON_TXFORMAT_RGBA8888:
1691 format = RADEON_COLOR_FORMAT_ARGB8888;
1692 tex_width = tex->width * 4;
1693 blit_width = image->width * 4;
1694 break;
1695 case RADEON_TXFORMAT_AI88:
1696 case RADEON_TXFORMAT_ARGB1555:
1697 case RADEON_TXFORMAT_RGB565:
1698 case RADEON_TXFORMAT_ARGB4444:
1699 case RADEON_TXFORMAT_VYUY422:
1700 case RADEON_TXFORMAT_YVYU422:
1701 format = RADEON_COLOR_FORMAT_RGB565;
1702 tex_width = tex->width * 2;
1703 blit_width = image->width * 2;
1704 break;
1705 case RADEON_TXFORMAT_I8:
1706 case RADEON_TXFORMAT_RGB332:
1707 format = RADEON_COLOR_FORMAT_CI8;
1708 tex_width = tex->width * 1;
1709 blit_width = image->width * 1;
1710 break;
1711 default:
1712 DRM_ERROR("invalid texture format %d\n", tex->format);
1713 return -EINVAL;
1714 }
1715 spitch = blit_width >> 6;
1716 if (spitch == 0 && image->height > 1)
1717 return -EINVAL;
1718
1719 texpitch = tex->pitch;
1720 if ((texpitch << 22) & RADEON_DST_TILE_MICRO) {
1721 microtile = 1;
1722 if (tex_width < 64) {
1723 texpitch &= ~(RADEON_DST_TILE_MICRO >> 22);
1724 /* we got tiled coordinates, untile them */
1725 image->x *= 2;
1726 }
1727 } else
1728 microtile = 0;
1729
1730 DRM_DEBUG("tex=%dx%d blit=%d\n", tex_width, tex->height, blit_width);
1731
1732 do {
1733 DRM_DEBUG("tex: ofs=0x%x p=%d f=%d x=%hd y=%hd w=%hd h=%hd\n",
1734 tex->offset >> 10, tex->pitch, tex->format,
1735 image->x, image->y, image->width, image->height);
1736
1737 /* Make a copy of some parameters in case we have to
1738 * update them for a multi-pass texture blit.
1739 */
1740 height = image->height;
1741 data = (const u8 __user *)image->data;
1742
1743 size = height * blit_width;
1744
1745 if (size > RADEON_MAX_TEXTURE_SIZE) {
1746 height = RADEON_MAX_TEXTURE_SIZE / blit_width;
1747 size = height * blit_width;
1748 } else if (size < 4 && size > 0) {
1749 size = 4;
1750 } else if (size == 0) {
1751 return 0;
1752 }
1753
1754 buf = radeon_freelist_get(dev);
1755 if (0 && !buf) {
1756 radeon_do_cp_idle(dev_priv);
1757 buf = radeon_freelist_get(dev);
1758 }
1759 if (!buf) {
1760 DRM_DEBUG("EAGAIN\n");
1761 if (DRM_COPY_TO_USER(tex->image, image, sizeof(*image)))
1762 return -EFAULT;
1763 return -EAGAIN;
1764 }
1765
1766 /* Dispatch the indirect buffer.
1767 */
1768 buffer =
1769 (u32 *) ((char *)dev->agp_buffer_map->handle + buf->offset);
1770 dwords = size / 4;
1771
1772#define RADEON_COPY_MT(_buf, _data, _width) \
1773 do { \
1774 if (DRM_COPY_FROM_USER(_buf, _data, (_width))) {\
1775 DRM_ERROR("EFAULT on pad, %d bytes\n", (_width)); \
1776 return -EFAULT; \
1777 } \
1778 } while(0)
1779
1780 if (microtile) {
1781 /* texture micro tiling in use, minimum texture width is thus 16 bytes.
1782 however, we cannot use blitter directly for texture width < 64 bytes,
1783 since minimum tex pitch is 64 bytes and we need this to match
1784 the texture width, otherwise the blitter will tile it wrong.
1785 Thus, tiling manually in this case. Additionally, need to special
1786 case tex height = 1, since our actual image will have height 2
1787 and we need to ensure we don't read beyond the texture size
1788 from user space. */
1789 if (tex->height == 1) {
1790 if (tex_width >= 64 || tex_width <= 16) {
1791 RADEON_COPY_MT(buffer, data,
1792 (int)(tex_width * sizeof(u32)));
1793 } else if (tex_width == 32) {
1794 RADEON_COPY_MT(buffer, data, 16);
1795 RADEON_COPY_MT(buffer + 8,
1796 data + 16, 16);
1797 }
1798 } else if (tex_width >= 64 || tex_width == 16) {
1799 RADEON_COPY_MT(buffer, data,
1800 (int)(dwords * sizeof(u32)));
1801 } else if (tex_width < 16) {
1802 for (i = 0; i < tex->height; i++) {
1803 RADEON_COPY_MT(buffer, data, tex_width);
1804 buffer += 4;
1805 data += tex_width;
1806 }
1807 } else if (tex_width == 32) {
1808 /* TODO: make sure this works when not fitting in one buffer
1809 (i.e. 32bytes x 2048...) */
1810 for (i = 0; i < tex->height; i += 2) {
1811 RADEON_COPY_MT(buffer, data, 16);
1812 data += 16;
1813 RADEON_COPY_MT(buffer + 8, data, 16);
1814 data += 16;
1815 RADEON_COPY_MT(buffer + 4, data, 16);
1816 data += 16;
1817 RADEON_COPY_MT(buffer + 12, data, 16);
1818 data += 16;
1819 buffer += 16;
1820 }
1821 }
1822 } else {
1823 if (tex_width >= 32) {
1824 /* Texture image width is larger than the minimum, so we
1825 * can upload it directly.
1826 */
1827 RADEON_COPY_MT(buffer, data,
1828 (int)(dwords * sizeof(u32)));
1829 } else {
1830 /* Texture image width is less than the minimum, so we
1831 * need to pad out each image scanline to the minimum
1832 * width.
1833 */
1834 for (i = 0; i < tex->height; i++) {
1835 RADEON_COPY_MT(buffer, data, tex_width);
1836 buffer += 8;
1837 data += tex_width;
1838 }
1839 }
1840 }
1841
1842#undef RADEON_COPY_MT
1843 buf->file_priv = file_priv;
1844 buf->used = size;
1845 offset = dev_priv->gart_buffers_offset + buf->offset;
1846 BEGIN_RING(9);
1847 OUT_RING(CP_PACKET3(RADEON_CNTL_BITBLT_MULTI, 5));
1848 OUT_RING(RADEON_GMC_SRC_PITCH_OFFSET_CNTL |
1849 RADEON_GMC_DST_PITCH_OFFSET_CNTL |
1850 RADEON_GMC_BRUSH_NONE |
1851 (format << 8) |
1852 RADEON_GMC_SRC_DATATYPE_COLOR |
1853 RADEON_ROP3_S |
1854 RADEON_DP_SRC_SOURCE_MEMORY |
1855 RADEON_GMC_CLR_CMP_CNTL_DIS | RADEON_GMC_WR_MSK_DIS);
1856 OUT_RING((spitch << 22) | (offset >> 10));
1857 OUT_RING((texpitch << 22) | (tex->offset >> 10));
1858 OUT_RING(0);
1859 OUT_RING((image->x << 16) | image->y);
1860 OUT_RING((image->width << 16) | height);
1861 RADEON_WAIT_UNTIL_2D_IDLE();
1862 ADVANCE_RING();
1863 COMMIT_RING();
1864
1865 radeon_cp_discard_buffer(dev, buf);
1866
1867 /* Update the input parameters for next time */
1868 image->y += height;
1869 image->height -= height;
1870 image->data = (const u8 __user *)image->data + size;
1871 } while (image->height > 0);
1872
1873 /* Flush the pixel cache after the blit completes. This ensures
1874 * the texture data is written out to memory before rendering
1875 * continues.
1876 */
1877 BEGIN_RING(4);
1878 RADEON_FLUSH_CACHE();
1879 RADEON_WAIT_UNTIL_2D_IDLE();
1880 ADVANCE_RING();
1881 COMMIT_RING();
1882
1883 return 0;
1884}
1885
1886static void radeon_cp_dispatch_stipple(struct drm_device * dev, u32 * stipple)
1887{
1888 drm_radeon_private_t *dev_priv = dev->dev_private;
1889 int i;
1890 RING_LOCALS;
1891 DRM_DEBUG("\n");
1892
1893 BEGIN_RING(35);
1894
1895 OUT_RING(CP_PACKET0(RADEON_RE_STIPPLE_ADDR, 0));
1896 OUT_RING(0x00000000);
1897
1898 OUT_RING(CP_PACKET0_TABLE(RADEON_RE_STIPPLE_DATA, 31));
1899 for (i = 0; i < 32; i++) {
1900 OUT_RING(stipple[i]);
1901 }
1902
1903 ADVANCE_RING();
1904}
1905
1906static void radeon_apply_surface_regs(int surf_index,
1907 drm_radeon_private_t *dev_priv)
1908{
1909 if (!dev_priv->mmio)
1910 return;
1911
1912 radeon_do_cp_idle(dev_priv);
1913
1914 RADEON_WRITE(RADEON_SURFACE0_INFO + 16 * surf_index,
1915 dev_priv->surfaces[surf_index].flags);
1916 RADEON_WRITE(RADEON_SURFACE0_LOWER_BOUND + 16 * surf_index,
1917 dev_priv->surfaces[surf_index].lower);
1918 RADEON_WRITE(RADEON_SURFACE0_UPPER_BOUND + 16 * surf_index,
1919 dev_priv->surfaces[surf_index].upper);
1920}
1921
1922/* Allocates a virtual surface
1923 * doesn't always allocate a real surface, will stretch an existing
1924 * surface when possible.
1925 *
1926 * Note that refcount can be at most 2, since during a free refcount=3
1927 * might mean we have to allocate a new surface which might not always
1928 * be available.
1929 * For example : we allocate three contigous surfaces ABC. If B is
1930 * freed, we suddenly need two surfaces to store A and C, which might
1931 * not always be available.
1932 */
1933static int alloc_surface(drm_radeon_surface_alloc_t *new,
1934 drm_radeon_private_t *dev_priv,
1935 struct drm_file *file_priv)
1936{
1937 struct radeon_virt_surface *s;
1938 int i;
1939 int virt_surface_index;
1940 uint32_t new_upper, new_lower;
1941
1942 new_lower = new->address;
1943 new_upper = new_lower + new->size - 1;
1944
1945 /* sanity check */
1946 if ((new_lower >= new_upper) || (new->flags == 0) || (new->size == 0) ||
1947 ((new_upper & RADEON_SURF_ADDRESS_FIXED_MASK) !=
1948 RADEON_SURF_ADDRESS_FIXED_MASK)
1949 || ((new_lower & RADEON_SURF_ADDRESS_FIXED_MASK) != 0))
1950 return -1;
1951
1952 /* make sure there is no overlap with existing surfaces */
1953 for (i = 0; i < RADEON_MAX_SURFACES; i++) {
1954 if ((dev_priv->surfaces[i].refcount != 0) &&
1955 (((new_lower >= dev_priv->surfaces[i].lower) &&
1956 (new_lower < dev_priv->surfaces[i].upper)) ||
1957 ((new_lower < dev_priv->surfaces[i].lower) &&
1958 (new_upper > dev_priv->surfaces[i].lower)))) {
1959 return -1;
1960 }
1961 }
1962
1963 /* find a virtual surface */
1964 for (i = 0; i < 2 * RADEON_MAX_SURFACES; i++)
1965 if (dev_priv->virt_surfaces[i].file_priv == 0)
1966 break;
1967 if (i == 2 * RADEON_MAX_SURFACES) {
1968 return -1;
1969 }
1970 virt_surface_index = i;
1971
1972 /* try to reuse an existing surface */
1973 for (i = 0; i < RADEON_MAX_SURFACES; i++) {
1974 /* extend before */
1975 if ((dev_priv->surfaces[i].refcount == 1) &&
1976 (new->flags == dev_priv->surfaces[i].flags) &&
1977 (new_upper + 1 == dev_priv->surfaces[i].lower)) {
1978 s = &(dev_priv->virt_surfaces[virt_surface_index]);
1979 s->surface_index = i;
1980 s->lower = new_lower;
1981 s->upper = new_upper;
1982 s->flags = new->flags;
1983 s->file_priv = file_priv;
1984 dev_priv->surfaces[i].refcount++;
1985 dev_priv->surfaces[i].lower = s->lower;
1986 radeon_apply_surface_regs(s->surface_index, dev_priv);
1987 return virt_surface_index;
1988 }
1989
1990 /* extend after */
1991 if ((dev_priv->surfaces[i].refcount == 1) &&
1992 (new->flags == dev_priv->surfaces[i].flags) &&
1993 (new_lower == dev_priv->surfaces[i].upper + 1)) {
1994 s = &(dev_priv->virt_surfaces[virt_surface_index]);
1995 s->surface_index = i;
1996 s->lower = new_lower;
1997 s->upper = new_upper;
1998 s->flags = new->flags;
1999 s->file_priv = file_priv;
2000 dev_priv->surfaces[i].refcount++;
2001 dev_priv->surfaces[i].upper = s->upper;
2002 radeon_apply_surface_regs(s->surface_index, dev_priv);
2003 return virt_surface_index;
2004 }
2005 }
2006
2007 /* okay, we need a new one */
2008 for (i = 0; i < RADEON_MAX_SURFACES; i++) {
2009 if (dev_priv->surfaces[i].refcount == 0) {
2010 s = &(dev_priv->virt_surfaces[virt_surface_index]);
2011 s->surface_index = i;
2012 s->lower = new_lower;
2013 s->upper = new_upper;
2014 s->flags = new->flags;
2015 s->file_priv = file_priv;
2016 dev_priv->surfaces[i].refcount = 1;
2017 dev_priv->surfaces[i].lower = s->lower;
2018 dev_priv->surfaces[i].upper = s->upper;
2019 dev_priv->surfaces[i].flags = s->flags;
2020 radeon_apply_surface_regs(s->surface_index, dev_priv);
2021 return virt_surface_index;
2022 }
2023 }
2024
2025 /* we didn't find anything */
2026 return -1;
2027}
2028
2029static int free_surface(struct drm_file *file_priv,
2030 drm_radeon_private_t * dev_priv,
2031 int lower)
2032{
2033 struct radeon_virt_surface *s;
2034 int i;
2035 /* find the virtual surface */
2036 for (i = 0; i < 2 * RADEON_MAX_SURFACES; i++) {
2037 s = &(dev_priv->virt_surfaces[i]);
2038 if (s->file_priv) {
2039 if ((lower == s->lower) && (file_priv == s->file_priv))
2040 {
2041 if (dev_priv->surfaces[s->surface_index].
2042 lower == s->lower)
2043 dev_priv->surfaces[s->surface_index].
2044 lower = s->upper;
2045
2046 if (dev_priv->surfaces[s->surface_index].
2047 upper == s->upper)
2048 dev_priv->surfaces[s->surface_index].
2049 upper = s->lower;
2050
2051 dev_priv->surfaces[s->surface_index].refcount--;
2052 if (dev_priv->surfaces[s->surface_index].
2053 refcount == 0)
2054 dev_priv->surfaces[s->surface_index].
2055 flags = 0;
2056 s->file_priv = NULL;
2057 radeon_apply_surface_regs(s->surface_index,
2058 dev_priv);
2059 return 0;
2060 }
2061 }
2062 }
2063 return 1;
2064}
2065
2066static void radeon_surfaces_release(struct drm_file *file_priv,
2067 drm_radeon_private_t * dev_priv)
2068{
2069 int i;
2070 for (i = 0; i < 2 * RADEON_MAX_SURFACES; i++) {
2071 if (dev_priv->virt_surfaces[i].file_priv == file_priv)
2072 free_surface(file_priv, dev_priv,
2073 dev_priv->virt_surfaces[i].lower);
2074 }
2075}
2076
2077/* ================================================================
2078 * IOCTL functions
2079 */
2080static int radeon_surface_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv)
2081{
2082 drm_radeon_private_t *dev_priv = dev->dev_private;
2083 drm_radeon_surface_alloc_t *alloc = data;
2084
2085 if (alloc_surface(alloc, dev_priv, file_priv) == -1)
2086 return -EINVAL;
2087 else
2088 return 0;
2089}
2090
2091static int radeon_surface_free(struct drm_device *dev, void *data, struct drm_file *file_priv)
2092{
2093 drm_radeon_private_t *dev_priv = dev->dev_private;
2094 drm_radeon_surface_free_t *memfree = data;
2095
2096 if (free_surface(file_priv, dev_priv, memfree->address))
2097 return -EINVAL;
2098 else
2099 return 0;
2100}
2101
2102static int radeon_cp_clear(struct drm_device *dev, void *data, struct drm_file *file_priv)
2103{
2104 drm_radeon_private_t *dev_priv = dev->dev_private;
2105 drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
2106 drm_radeon_clear_t *clear = data;
2107 drm_radeon_clear_rect_t depth_boxes[RADEON_NR_SAREA_CLIPRECTS];
2108 DRM_DEBUG("\n");
2109
2110 LOCK_TEST_WITH_RETURN(dev, file_priv);
2111
2112 RING_SPACE_TEST_WITH_RETURN(dev_priv);
2113
2114 if (sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS)
2115 sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS;
2116
2117 if (DRM_COPY_FROM_USER(&depth_boxes, clear->depth_boxes,
2118 sarea_priv->nbox * sizeof(depth_boxes[0])))
2119 return -EFAULT;
2120
2121 radeon_cp_dispatch_clear(dev, clear, depth_boxes);
2122
2123 COMMIT_RING();
2124 return 0;
2125}
2126
2127/* Not sure why this isn't set all the time:
2128 */
2129static int radeon_do_init_pageflip(struct drm_device * dev)
2130{
2131 drm_radeon_private_t *dev_priv = dev->dev_private;
2132 RING_LOCALS;
2133
2134 DRM_DEBUG("\n");
2135
2136 BEGIN_RING(6);
2137 RADEON_WAIT_UNTIL_3D_IDLE();
2138 OUT_RING(CP_PACKET0(RADEON_CRTC_OFFSET_CNTL, 0));
2139 OUT_RING(RADEON_READ(RADEON_CRTC_OFFSET_CNTL) |
2140 RADEON_CRTC_OFFSET_FLIP_CNTL);
2141 OUT_RING(CP_PACKET0(RADEON_CRTC2_OFFSET_CNTL, 0));
2142 OUT_RING(RADEON_READ(RADEON_CRTC2_OFFSET_CNTL) |
2143 RADEON_CRTC_OFFSET_FLIP_CNTL);
2144 ADVANCE_RING();
2145
2146 dev_priv->page_flipping = 1;
2147
2148 if (dev_priv->sarea_priv->pfCurrentPage != 1)
2149 dev_priv->sarea_priv->pfCurrentPage = 0;
2150
2151 return 0;
2152}
2153
2154/* Swapping and flipping are different operations, need different ioctls.
2155 * They can & should be intermixed to support multiple 3d windows.
2156 */
2157static int radeon_cp_flip(struct drm_device *dev, void *data, struct drm_file *file_priv)
2158{
2159 drm_radeon_private_t *dev_priv = dev->dev_private;
2160 DRM_DEBUG("\n");
2161
2162 LOCK_TEST_WITH_RETURN(dev, file_priv);
2163
2164 RING_SPACE_TEST_WITH_RETURN(dev_priv);
2165
2166 if (!dev_priv->page_flipping)
2167 radeon_do_init_pageflip(dev);
2168
2169 radeon_cp_dispatch_flip(dev);
2170
2171 COMMIT_RING();
2172 return 0;
2173}
2174
2175static int radeon_cp_swap(struct drm_device *dev, void *data, struct drm_file *file_priv)
2176{
2177 drm_radeon_private_t *dev_priv = dev->dev_private;
2178 drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
2179 DRM_DEBUG("\n");
2180
2181 LOCK_TEST_WITH_RETURN(dev, file_priv);
2182
2183 RING_SPACE_TEST_WITH_RETURN(dev_priv);
2184
2185 if (sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS)
2186 sarea_priv->nbox = RADEON_NR_SAREA_CLIPRECTS;
2187
2188 radeon_cp_dispatch_swap(dev);
2189 dev_priv->sarea_priv->ctx_owner = 0;
2190
2191 COMMIT_RING();
2192 return 0;
2193}
2194
2195static int radeon_cp_vertex(struct drm_device *dev, void *data, struct drm_file *file_priv)
2196{
2197 drm_radeon_private_t *dev_priv = dev->dev_private;
2198 drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
2199 struct drm_device_dma *dma = dev->dma;
2200 struct drm_buf *buf;
2201 drm_radeon_vertex_t *vertex = data;
2202 drm_radeon_tcl_prim_t prim;
2203
2204 LOCK_TEST_WITH_RETURN(dev, file_priv);
2205
2206 DRM_DEBUG("pid=%d index=%d count=%d discard=%d\n",
2207 DRM_CURRENTPID, vertex->idx, vertex->count, vertex->discard);
2208
2209 if (vertex->idx < 0 || vertex->idx >= dma->buf_count) {
2210 DRM_ERROR("buffer index %d (of %d max)\n",
2211 vertex->idx, dma->buf_count - 1);
2212 return -EINVAL;
2213 }
2214 if (vertex->prim < 0 || vertex->prim > RADEON_PRIM_TYPE_3VRT_LINE_LIST) {
2215 DRM_ERROR("buffer prim %d\n", vertex->prim);
2216 return -EINVAL;
2217 }
2218
2219 RING_SPACE_TEST_WITH_RETURN(dev_priv);
2220 VB_AGE_TEST_WITH_RETURN(dev_priv);
2221
2222 buf = dma->buflist[vertex->idx];
2223
2224 if (buf->file_priv != file_priv) {
2225 DRM_ERROR("process %d using buffer owned by %p\n",
2226 DRM_CURRENTPID, buf->file_priv);
2227 return -EINVAL;
2228 }
2229 if (buf->pending) {
2230 DRM_ERROR("sending pending buffer %d\n", vertex->idx);
2231 return -EINVAL;
2232 }
2233
2234 /* Build up a prim_t record:
2235 */
2236 if (vertex->count) {
2237 buf->used = vertex->count; /* not used? */
2238
2239 if (sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS) {
2240 if (radeon_emit_state(dev_priv, file_priv,
2241 &sarea_priv->context_state,
2242 sarea_priv->tex_state,
2243 sarea_priv->dirty)) {
2244 DRM_ERROR("radeon_emit_state failed\n");
2245 return -EINVAL;
2246 }
2247
2248 sarea_priv->dirty &= ~(RADEON_UPLOAD_TEX0IMAGES |
2249 RADEON_UPLOAD_TEX1IMAGES |
2250 RADEON_UPLOAD_TEX2IMAGES |
2251 RADEON_REQUIRE_QUIESCENCE);
2252 }
2253
2254 prim.start = 0;
2255 prim.finish = vertex->count; /* unused */
2256 prim.prim = vertex->prim;
2257 prim.numverts = vertex->count;
2258 prim.vc_format = dev_priv->sarea_priv->vc_format;
2259
2260 radeon_cp_dispatch_vertex(dev, buf, &prim);
2261 }
2262
2263 if (vertex->discard) {
2264 radeon_cp_discard_buffer(dev, buf);
2265 }
2266
2267 COMMIT_RING();
2268 return 0;
2269}
2270
2271static int radeon_cp_indices(struct drm_device *dev, void *data, struct drm_file *file_priv)
2272{
2273 drm_radeon_private_t *dev_priv = dev->dev_private;
2274 drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
2275 struct drm_device_dma *dma = dev->dma;
2276 struct drm_buf *buf;
2277 drm_radeon_indices_t *elts = data;
2278 drm_radeon_tcl_prim_t prim;
2279 int count;
2280
2281 LOCK_TEST_WITH_RETURN(dev, file_priv);
2282
2283 DRM_DEBUG("pid=%d index=%d start=%d end=%d discard=%d\n",
2284 DRM_CURRENTPID, elts->idx, elts->start, elts->end,
2285 elts->discard);
2286
2287 if (elts->idx < 0 || elts->idx >= dma->buf_count) {
2288 DRM_ERROR("buffer index %d (of %d max)\n",
2289 elts->idx, dma->buf_count - 1);
2290 return -EINVAL;
2291 }
2292 if (elts->prim < 0 || elts->prim > RADEON_PRIM_TYPE_3VRT_LINE_LIST) {
2293 DRM_ERROR("buffer prim %d\n", elts->prim);
2294 return -EINVAL;
2295 }
2296
2297 RING_SPACE_TEST_WITH_RETURN(dev_priv);
2298 VB_AGE_TEST_WITH_RETURN(dev_priv);
2299
2300 buf = dma->buflist[elts->idx];
2301
2302 if (buf->file_priv != file_priv) {
2303 DRM_ERROR("process %d using buffer owned by %p\n",
2304 DRM_CURRENTPID, buf->file_priv);
2305 return -EINVAL;
2306 }
2307 if (buf->pending) {
2308 DRM_ERROR("sending pending buffer %d\n", elts->idx);
2309 return -EINVAL;
2310 }
2311
2312 count = (elts->end - elts->start) / sizeof(u16);
2313 elts->start -= RADEON_INDEX_PRIM_OFFSET;
2314
2315 if (elts->start & 0x7) {
2316 DRM_ERROR("misaligned buffer 0x%x\n", elts->start);
2317 return -EINVAL;
2318 }
2319 if (elts->start < buf->used) {
2320 DRM_ERROR("no header 0x%x - 0x%x\n", elts->start, buf->used);
2321 return -EINVAL;
2322 }
2323
2324 buf->used = elts->end;
2325
2326 if (sarea_priv->dirty & ~RADEON_UPLOAD_CLIPRECTS) {
2327 if (radeon_emit_state(dev_priv, file_priv,
2328 &sarea_priv->context_state,
2329 sarea_priv->tex_state,
2330 sarea_priv->dirty)) {
2331 DRM_ERROR("radeon_emit_state failed\n");
2332 return -EINVAL;
2333 }
2334
2335 sarea_priv->dirty &= ~(RADEON_UPLOAD_TEX0IMAGES |
2336 RADEON_UPLOAD_TEX1IMAGES |
2337 RADEON_UPLOAD_TEX2IMAGES |
2338 RADEON_REQUIRE_QUIESCENCE);
2339 }
2340
2341 /* Build up a prim_t record:
2342 */
2343 prim.start = elts->start;
2344 prim.finish = elts->end;
2345 prim.prim = elts->prim;
2346 prim.offset = 0; /* offset from start of dma buffers */
2347 prim.numverts = RADEON_MAX_VB_VERTS; /* duh */
2348 prim.vc_format = dev_priv->sarea_priv->vc_format;
2349
2350 radeon_cp_dispatch_indices(dev, buf, &prim);
2351 if (elts->discard) {
2352 radeon_cp_discard_buffer(dev, buf);
2353 }
2354
2355 COMMIT_RING();
2356 return 0;
2357}
2358
2359static int radeon_cp_texture(struct drm_device *dev, void *data, struct drm_file *file_priv)
2360{
2361 drm_radeon_private_t *dev_priv = dev->dev_private;
2362 drm_radeon_texture_t *tex = data;
2363 drm_radeon_tex_image_t image;
2364 int ret;
2365
2366 LOCK_TEST_WITH_RETURN(dev, file_priv);
2367
2368 if (tex->image == NULL) {
2369 DRM_ERROR("null texture image!\n");
2370 return -EINVAL;
2371 }
2372
2373 if (DRM_COPY_FROM_USER(&image,
2374 (drm_radeon_tex_image_t __user *) tex->image,
2375 sizeof(image)))
2376 return -EFAULT;
2377
2378 RING_SPACE_TEST_WITH_RETURN(dev_priv);
2379 VB_AGE_TEST_WITH_RETURN(dev_priv);
2380
2381 ret = radeon_cp_dispatch_texture(dev, file_priv, tex, &image);
2382
2383 return ret;
2384}
2385
2386static int radeon_cp_stipple(struct drm_device *dev, void *data, struct drm_file *file_priv)
2387{
2388 drm_radeon_private_t *dev_priv = dev->dev_private;
2389 drm_radeon_stipple_t *stipple = data;
2390 u32 mask[32];
2391
2392 LOCK_TEST_WITH_RETURN(dev, file_priv);
2393
2394 if (DRM_COPY_FROM_USER(&mask, stipple->mask, 32 * sizeof(u32)))
2395 return -EFAULT;
2396
2397 RING_SPACE_TEST_WITH_RETURN(dev_priv);
2398
2399 radeon_cp_dispatch_stipple(dev, mask);
2400
2401 COMMIT_RING();
2402 return 0;
2403}
2404
2405static int radeon_cp_indirect(struct drm_device *dev, void *data, struct drm_file *file_priv)
2406{
2407 drm_radeon_private_t *dev_priv = dev->dev_private;
2408 struct drm_device_dma *dma = dev->dma;
2409 struct drm_buf *buf;
2410 drm_radeon_indirect_t *indirect = data;
2411 RING_LOCALS;
2412
2413 LOCK_TEST_WITH_RETURN(dev, file_priv);
2414
2415 DRM_DEBUG("idx=%d s=%d e=%d d=%d\n",
2416 indirect->idx, indirect->start, indirect->end,
2417 indirect->discard);
2418
2419 if (indirect->idx < 0 || indirect->idx >= dma->buf_count) {
2420 DRM_ERROR("buffer index %d (of %d max)\n",
2421 indirect->idx, dma->buf_count - 1);
2422 return -EINVAL;
2423 }
2424
2425 buf = dma->buflist[indirect->idx];
2426
2427 if (buf->file_priv != file_priv) {
2428 DRM_ERROR("process %d using buffer owned by %p\n",
2429 DRM_CURRENTPID, buf->file_priv);
2430 return -EINVAL;
2431 }
2432 if (buf->pending) {
2433 DRM_ERROR("sending pending buffer %d\n", indirect->idx);
2434 return -EINVAL;
2435 }
2436
2437 if (indirect->start < buf->used) {
2438 DRM_ERROR("reusing indirect: start=0x%x actual=0x%x\n",
2439 indirect->start, buf->used);
2440 return -EINVAL;
2441 }
2442
2443 RING_SPACE_TEST_WITH_RETURN(dev_priv);
2444 VB_AGE_TEST_WITH_RETURN(dev_priv);
2445
2446 buf->used = indirect->end;
2447
2448 /* Wait for the 3D stream to idle before the indirect buffer
2449 * containing 2D acceleration commands is processed.
2450 */
2451 BEGIN_RING(2);
2452
2453 RADEON_WAIT_UNTIL_3D_IDLE();
2454
2455 ADVANCE_RING();
2456
2457 /* Dispatch the indirect buffer full of commands from the
2458 * X server. This is insecure and is thus only available to
2459 * privileged clients.
2460 */
2461 radeon_cp_dispatch_indirect(dev, buf, indirect->start, indirect->end);
2462 if (indirect->discard) {
2463 radeon_cp_discard_buffer(dev, buf);
2464 }
2465
2466 COMMIT_RING();
2467 return 0;
2468}
2469
2470static int radeon_cp_vertex2(struct drm_device *dev, void *data, struct drm_file *file_priv)
2471{
2472 drm_radeon_private_t *dev_priv = dev->dev_private;
2473 drm_radeon_sarea_t *sarea_priv = dev_priv->sarea_priv;
2474 struct drm_device_dma *dma = dev->dma;
2475 struct drm_buf *buf;
2476 drm_radeon_vertex2_t *vertex = data;
2477 int i;
2478 unsigned char laststate;
2479
2480 LOCK_TEST_WITH_RETURN(dev, file_priv);
2481
2482 DRM_DEBUG("pid=%d index=%d discard=%d\n",
2483 DRM_CURRENTPID, vertex->idx, vertex->discard);
2484
2485 if (vertex->idx < 0 || vertex->idx >= dma->buf_count) {
2486 DRM_ERROR("buffer index %d (of %d max)\n",
2487 vertex->idx, dma->buf_count - 1);
2488 return -EINVAL;
2489 }
2490
2491 RING_SPACE_TEST_WITH_RETURN(dev_priv);
2492 VB_AGE_TEST_WITH_RETURN(dev_priv);
2493
2494 buf = dma->buflist[vertex->idx];
2495
2496 if (buf->file_priv != file_priv) {
2497 DRM_ERROR("process %d using buffer owned by %p\n",
2498 DRM_CURRENTPID, buf->file_priv);
2499 return -EINVAL;
2500 }
2501
2502 if (buf->pending) {
2503 DRM_ERROR("sending pending buffer %d\n", vertex->idx);
2504 return -EINVAL;
2505 }
2506
2507 if (sarea_priv->nbox > RADEON_NR_SAREA_CLIPRECTS)
2508 return -EINVAL;
2509
2510 for (laststate = 0xff, i = 0; i < vertex->nr_prims; i++) {
2511 drm_radeon_prim_t prim;
2512 drm_radeon_tcl_prim_t tclprim;
2513
2514 if (DRM_COPY_FROM_USER(&prim, &vertex->prim[i], sizeof(prim)))
2515 return -EFAULT;
2516
2517 if (prim.stateidx != laststate) {
2518 drm_radeon_state_t state;
2519
2520 if (DRM_COPY_FROM_USER(&state,
2521 &vertex->state[prim.stateidx],
2522 sizeof(state)))
2523 return -EFAULT;
2524
2525 if (radeon_emit_state2(dev_priv, file_priv, &state)) {
2526 DRM_ERROR("radeon_emit_state2 failed\n");
2527 return -EINVAL;
2528 }
2529
2530 laststate = prim.stateidx;
2531 }
2532
2533 tclprim.start = prim.start;
2534 tclprim.finish = prim.finish;
2535 tclprim.prim = prim.prim;
2536 tclprim.vc_format = prim.vc_format;
2537
2538 if (prim.prim & RADEON_PRIM_WALK_IND) {
2539 tclprim.offset = prim.numverts * 64;
2540 tclprim.numverts = RADEON_MAX_VB_VERTS; /* duh */
2541
2542 radeon_cp_dispatch_indices(dev, buf, &tclprim);
2543 } else {
2544 tclprim.numverts = prim.numverts;
2545 tclprim.offset = 0; /* not used */
2546
2547 radeon_cp_dispatch_vertex(dev, buf, &tclprim);
2548 }
2549
2550 if (sarea_priv->nbox == 1)
2551 sarea_priv->nbox = 0;
2552 }
2553
2554 if (vertex->discard) {
2555 radeon_cp_discard_buffer(dev, buf);
2556 }
2557
2558 COMMIT_RING();
2559 return 0;
2560}
2561
2562static int radeon_emit_packets(drm_radeon_private_t * dev_priv,
2563 struct drm_file *file_priv,
2564 drm_radeon_cmd_header_t header,
2565 drm_radeon_kcmd_buffer_t *cmdbuf)
2566{
2567 int id = (int)header.packet.packet_id;
2568 int sz, reg;
2569 int *data = (int *)cmdbuf->buf;
2570 RING_LOCALS;
2571
2572 if (id >= RADEON_MAX_STATE_PACKETS)
2573 return -EINVAL;
2574
2575 sz = packet[id].len;
2576 reg = packet[id].start;
2577
2578 if (sz * sizeof(int) > cmdbuf->bufsz) {
2579 DRM_ERROR("Packet size provided larger than data provided\n");
2580 return -EINVAL;
2581 }
2582
2583 if (radeon_check_and_fixup_packets(dev_priv, file_priv, id, data)) {
2584 DRM_ERROR("Packet verification failed\n");
2585 return -EINVAL;
2586 }
2587
2588 BEGIN_RING(sz + 1);
2589 OUT_RING(CP_PACKET0(reg, (sz - 1)));
2590 OUT_RING_TABLE(data, sz);
2591 ADVANCE_RING();
2592
2593 cmdbuf->buf += sz * sizeof(int);
2594 cmdbuf->bufsz -= sz * sizeof(int);
2595 return 0;
2596}
2597
2598static __inline__ int radeon_emit_scalars(drm_radeon_private_t *dev_priv,
2599 drm_radeon_cmd_header_t header,
2600 drm_radeon_kcmd_buffer_t *cmdbuf)
2601{
2602 int sz = header.scalars.count;
2603 int start = header.scalars.offset;
2604 int stride = header.scalars.stride;
2605 RING_LOCALS;
2606
2607 BEGIN_RING(3 + sz);
2608 OUT_RING(CP_PACKET0(RADEON_SE_TCL_SCALAR_INDX_REG, 0));
2609 OUT_RING(start | (stride << RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT));
2610 OUT_RING(CP_PACKET0_TABLE(RADEON_SE_TCL_SCALAR_DATA_REG, sz - 1));
2611 OUT_RING_TABLE(cmdbuf->buf, sz);
2612 ADVANCE_RING();
2613 cmdbuf->buf += sz * sizeof(int);
2614 cmdbuf->bufsz -= sz * sizeof(int);
2615 return 0;
2616}
2617
2618/* God this is ugly
2619 */
2620static __inline__ int radeon_emit_scalars2(drm_radeon_private_t *dev_priv,
2621 drm_radeon_cmd_header_t header,
2622 drm_radeon_kcmd_buffer_t *cmdbuf)
2623{
2624 int sz = header.scalars.count;
2625 int start = ((unsigned int)header.scalars.offset) + 0x100;
2626 int stride = header.scalars.stride;
2627 RING_LOCALS;
2628
2629 BEGIN_RING(3 + sz);
2630 OUT_RING(CP_PACKET0(RADEON_SE_TCL_SCALAR_INDX_REG, 0));
2631 OUT_RING(start | (stride << RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT));
2632 OUT_RING(CP_PACKET0_TABLE(RADEON_SE_TCL_SCALAR_DATA_REG, sz - 1));
2633 OUT_RING_TABLE(cmdbuf->buf, sz);
2634 ADVANCE_RING();
2635 cmdbuf->buf += sz * sizeof(int);
2636 cmdbuf->bufsz -= sz * sizeof(int);
2637 return 0;
2638}
2639
2640static __inline__ int radeon_emit_vectors(drm_radeon_private_t *dev_priv,
2641 drm_radeon_cmd_header_t header,
2642 drm_radeon_kcmd_buffer_t *cmdbuf)
2643{
2644 int sz = header.vectors.count;
2645 int start = header.vectors.offset;
2646 int stride = header.vectors.stride;
2647 RING_LOCALS;
2648
2649 BEGIN_RING(5 + sz);
2650 OUT_RING_REG(RADEON_SE_TCL_STATE_FLUSH, 0);
2651 OUT_RING(CP_PACKET0(RADEON_SE_TCL_VECTOR_INDX_REG, 0));
2652 OUT_RING(start | (stride << RADEON_VEC_INDX_OCTWORD_STRIDE_SHIFT));
2653 OUT_RING(CP_PACKET0_TABLE(RADEON_SE_TCL_VECTOR_DATA_REG, (sz - 1)));
2654 OUT_RING_TABLE(cmdbuf->buf, sz);
2655 ADVANCE_RING();
2656
2657 cmdbuf->buf += sz * sizeof(int);
2658 cmdbuf->bufsz -= sz * sizeof(int);
2659 return 0;
2660}
2661
2662static __inline__ int radeon_emit_veclinear(drm_radeon_private_t *dev_priv,
2663 drm_radeon_cmd_header_t header,
2664 drm_radeon_kcmd_buffer_t *cmdbuf)
2665{
2666 int sz = header.veclinear.count * 4;
2667 int start = header.veclinear.addr_lo | (header.veclinear.addr_hi << 8);
2668 RING_LOCALS;
2669
2670 if (!sz)
2671 return 0;
2672 if (sz * 4 > cmdbuf->bufsz)
2673 return -EINVAL;
2674
2675 BEGIN_RING(5 + sz);
2676 OUT_RING_REG(RADEON_SE_TCL_STATE_FLUSH, 0);
2677 OUT_RING(CP_PACKET0(RADEON_SE_TCL_VECTOR_INDX_REG, 0));
2678 OUT_RING(start | (1 << RADEON_VEC_INDX_OCTWORD_STRIDE_SHIFT));
2679 OUT_RING(CP_PACKET0_TABLE(RADEON_SE_TCL_VECTOR_DATA_REG, (sz - 1)));
2680 OUT_RING_TABLE(cmdbuf->buf, sz);
2681 ADVANCE_RING();
2682
2683 cmdbuf->buf += sz * sizeof(int);
2684 cmdbuf->bufsz -= sz * sizeof(int);
2685 return 0;
2686}
2687
2688static int radeon_emit_packet3(struct drm_device * dev,
2689 struct drm_file *file_priv,
2690 drm_radeon_kcmd_buffer_t *cmdbuf)
2691{
2692 drm_radeon_private_t *dev_priv = dev->dev_private;
2693 unsigned int cmdsz;
2694 int ret;
2695 RING_LOCALS;
2696
2697 DRM_DEBUG("\n");
2698
2699 if ((ret = radeon_check_and_fixup_packet3(dev_priv, file_priv,
2700 cmdbuf, &cmdsz))) {
2701 DRM_ERROR("Packet verification failed\n");
2702 return ret;
2703 }
2704
2705 BEGIN_RING(cmdsz);
2706 OUT_RING_TABLE(cmdbuf->buf, cmdsz);
2707 ADVANCE_RING();
2708
2709 cmdbuf->buf += cmdsz * 4;
2710 cmdbuf->bufsz -= cmdsz * 4;
2711 return 0;
2712}
2713
2714static int radeon_emit_packet3_cliprect(struct drm_device *dev,
2715 struct drm_file *file_priv,
2716 drm_radeon_kcmd_buffer_t *cmdbuf,
2717 int orig_nbox)
2718{
2719 drm_radeon_private_t *dev_priv = dev->dev_private;
2720 struct drm_clip_rect box;
2721 unsigned int cmdsz;
2722 int ret;
2723 struct drm_clip_rect __user *boxes = cmdbuf->boxes;
2724 int i = 0;
2725 RING_LOCALS;
2726
2727 DRM_DEBUG("\n");
2728
2729 if ((ret = radeon_check_and_fixup_packet3(dev_priv, file_priv,
2730 cmdbuf, &cmdsz))) {
2731 DRM_ERROR("Packet verification failed\n");
2732 return ret;
2733 }
2734
2735 if (!orig_nbox)
2736 goto out;
2737
2738 do {
2739 if (i < cmdbuf->nbox) {
2740 if (DRM_COPY_FROM_USER(&box, &boxes[i], sizeof(box)))
2741 return -EFAULT;
2742 /* FIXME The second and subsequent times round
2743 * this loop, send a WAIT_UNTIL_3D_IDLE before
2744 * calling emit_clip_rect(). This fixes a
2745 * lockup on fast machines when sending
2746 * several cliprects with a cmdbuf, as when
2747 * waving a 2D window over a 3D
2748 * window. Something in the commands from user
2749 * space seems to hang the card when they're
2750 * sent several times in a row. That would be
2751 * the correct place to fix it but this works
2752 * around it until I can figure that out - Tim
2753 * Smith */
2754 if (i) {
2755 BEGIN_RING(2);
2756 RADEON_WAIT_UNTIL_3D_IDLE();
2757 ADVANCE_RING();
2758 }
2759 radeon_emit_clip_rect(dev_priv, &box);
2760 }
2761
2762 BEGIN_RING(cmdsz);
2763 OUT_RING_TABLE(cmdbuf->buf, cmdsz);
2764 ADVANCE_RING();
2765
2766 } while (++i < cmdbuf->nbox);
2767 if (cmdbuf->nbox == 1)
2768 cmdbuf->nbox = 0;
2769
2770 out:
2771 cmdbuf->buf += cmdsz * 4;
2772 cmdbuf->bufsz -= cmdsz * 4;
2773 return 0;
2774}
2775
2776static int radeon_emit_wait(struct drm_device * dev, int flags)
2777{
2778 drm_radeon_private_t *dev_priv = dev->dev_private;
2779 RING_LOCALS;
2780
2781 DRM_DEBUG("%x\n", flags);
2782 switch (flags) {
2783 case RADEON_WAIT_2D:
2784 BEGIN_RING(2);
2785 RADEON_WAIT_UNTIL_2D_IDLE();
2786 ADVANCE_RING();
2787 break;
2788 case RADEON_WAIT_3D:
2789 BEGIN_RING(2);
2790 RADEON_WAIT_UNTIL_3D_IDLE();
2791 ADVANCE_RING();
2792 break;
2793 case RADEON_WAIT_2D | RADEON_WAIT_3D:
2794 BEGIN_RING(2);
2795 RADEON_WAIT_UNTIL_IDLE();
2796 ADVANCE_RING();
2797 break;
2798 default:
2799 return -EINVAL;
2800 }
2801
2802 return 0;
2803}
2804
2805static int radeon_cp_cmdbuf(struct drm_device *dev, void *data, struct drm_file *file_priv)
2806{
2807 drm_radeon_private_t *dev_priv = dev->dev_private;
2808 struct drm_device_dma *dma = dev->dma;
2809 struct drm_buf *buf = NULL;
2810 int idx;
2811 drm_radeon_kcmd_buffer_t *cmdbuf = data;
2812 drm_radeon_cmd_header_t header;
2813 int orig_nbox, orig_bufsz;
2814 char *kbuf = NULL;
2815
2816 LOCK_TEST_WITH_RETURN(dev, file_priv);
2817
2818 RING_SPACE_TEST_WITH_RETURN(dev_priv);
2819 VB_AGE_TEST_WITH_RETURN(dev_priv);
2820
2821 if (cmdbuf->bufsz > 64 * 1024 || cmdbuf->bufsz < 0) {
2822 return -EINVAL;
2823 }
2824
2825 /* Allocate an in-kernel area and copy in the cmdbuf. Do this to avoid
2826 * races between checking values and using those values in other code,
2827 * and simply to avoid a lot of function calls to copy in data.
2828 */
2829 orig_bufsz = cmdbuf->bufsz;
2830 if (orig_bufsz != 0) {
2831 kbuf = drm_alloc(cmdbuf->bufsz, DRM_MEM_DRIVER);
2832 if (kbuf == NULL)
2833 return -ENOMEM;
2834 if (DRM_COPY_FROM_USER(kbuf, (void __user *)cmdbuf->buf,
2835 cmdbuf->bufsz)) {
2836 drm_free(kbuf, orig_bufsz, DRM_MEM_DRIVER);
2837 return -EFAULT;
2838 }
2839 cmdbuf->buf = kbuf;
2840 }
2841
2842 orig_nbox = cmdbuf->nbox;
2843
2844 if (dev_priv->microcode_version == UCODE_R300) {
2845 int temp;
2846 temp = r300_do_cp_cmdbuf(dev, file_priv, cmdbuf);
2847
2848 if (orig_bufsz != 0)
2849 drm_free(kbuf, orig_bufsz, DRM_MEM_DRIVER);
2850
2851 return temp;
2852 }
2853
2854 /* microcode_version != r300 */
2855 while (cmdbuf->bufsz >= sizeof(header)) {
2856
2857 header.i = *(int *)cmdbuf->buf;
2858 cmdbuf->buf += sizeof(header);
2859 cmdbuf->bufsz -= sizeof(header);
2860
2861 switch (header.header.cmd_type) {
2862 case RADEON_CMD_PACKET:
2863 DRM_DEBUG("RADEON_CMD_PACKET\n");
2864 if (radeon_emit_packets
2865 (dev_priv, file_priv, header, cmdbuf)) {
2866 DRM_ERROR("radeon_emit_packets failed\n");
2867 goto err;
2868 }
2869 break;
2870
2871 case RADEON_CMD_SCALARS:
2872 DRM_DEBUG("RADEON_CMD_SCALARS\n");
2873 if (radeon_emit_scalars(dev_priv, header, cmdbuf)) {
2874 DRM_ERROR("radeon_emit_scalars failed\n");
2875 goto err;
2876 }
2877 break;
2878
2879 case RADEON_CMD_VECTORS:
2880 DRM_DEBUG("RADEON_CMD_VECTORS\n");
2881 if (radeon_emit_vectors(dev_priv, header, cmdbuf)) {
2882 DRM_ERROR("radeon_emit_vectors failed\n");
2883 goto err;
2884 }
2885 break;
2886
2887 case RADEON_CMD_DMA_DISCARD:
2888 DRM_DEBUG("RADEON_CMD_DMA_DISCARD\n");
2889 idx = header.dma.buf_idx;
2890 if (idx < 0 || idx >= dma->buf_count) {
2891 DRM_ERROR("buffer index %d (of %d max)\n",
2892 idx, dma->buf_count - 1);
2893 goto err;
2894 }
2895
2896 buf = dma->buflist[idx];
2897 if (buf->file_priv != file_priv || buf->pending) {
2898 DRM_ERROR("bad buffer %p %p %d\n",
2899 buf->file_priv, file_priv,
2900 buf->pending);
2901 goto err;
2902 }
2903
2904 radeon_cp_discard_buffer(dev, buf);
2905 break;
2906
2907 case RADEON_CMD_PACKET3:
2908 DRM_DEBUG("RADEON_CMD_PACKET3\n");
2909 if (radeon_emit_packet3(dev, file_priv, cmdbuf)) {
2910 DRM_ERROR("radeon_emit_packet3 failed\n");
2911 goto err;
2912 }
2913 break;
2914
2915 case RADEON_CMD_PACKET3_CLIP:
2916 DRM_DEBUG("RADEON_CMD_PACKET3_CLIP\n");
2917 if (radeon_emit_packet3_cliprect
2918 (dev, file_priv, cmdbuf, orig_nbox)) {
2919 DRM_ERROR("radeon_emit_packet3_clip failed\n");
2920 goto err;
2921 }
2922 break;
2923
2924 case RADEON_CMD_SCALARS2:
2925 DRM_DEBUG("RADEON_CMD_SCALARS2\n");
2926 if (radeon_emit_scalars2(dev_priv, header, cmdbuf)) {
2927 DRM_ERROR("radeon_emit_scalars2 failed\n");
2928 goto err;
2929 }
2930 break;
2931
2932 case RADEON_CMD_WAIT:
2933 DRM_DEBUG("RADEON_CMD_WAIT\n");
2934 if (radeon_emit_wait(dev, header.wait.flags)) {
2935 DRM_ERROR("radeon_emit_wait failed\n");
2936 goto err;
2937 }
2938 break;
2939 case RADEON_CMD_VECLINEAR:
2940 DRM_DEBUG("RADEON_CMD_VECLINEAR\n");
2941 if (radeon_emit_veclinear(dev_priv, header, cmdbuf)) {
2942 DRM_ERROR("radeon_emit_veclinear failed\n");
2943 goto err;
2944 }
2945 break;
2946
2947 default:
2948 DRM_ERROR("bad cmd_type %d at %p\n",
2949 header.header.cmd_type,
2950 cmdbuf->buf - sizeof(header));
2951 goto err;
2952 }
2953 }
2954
2955 if (orig_bufsz != 0)
2956 drm_free(kbuf, orig_bufsz, DRM_MEM_DRIVER);
2957
2958 DRM_DEBUG("DONE\n");
2959 COMMIT_RING();
2960 return 0;
2961
2962 err:
2963 if (orig_bufsz != 0)
2964 drm_free(kbuf, orig_bufsz, DRM_MEM_DRIVER);
2965 return -EINVAL;
2966}
2967
2968static int radeon_cp_getparam(struct drm_device *dev, void *data, struct drm_file *file_priv)
2969{
2970 drm_radeon_private_t *dev_priv = dev->dev_private;
2971 drm_radeon_getparam_t *param = data;
2972 int value;
2973
2974 DRM_DEBUG("pid=%d\n", DRM_CURRENTPID);
2975
2976 switch (param->param) {
2977 case RADEON_PARAM_GART_BUFFER_OFFSET:
2978 value = dev_priv->gart_buffers_offset;
2979 break;
2980 case RADEON_PARAM_LAST_FRAME:
2981 dev_priv->stats.last_frame_reads++;
2982 value = GET_SCRATCH(0);
2983 break;
2984 case RADEON_PARAM_LAST_DISPATCH:
2985 value = GET_SCRATCH(1);
2986 break;
2987 case RADEON_PARAM_LAST_CLEAR:
2988 dev_priv->stats.last_clear_reads++;
2989 value = GET_SCRATCH(2);
2990 break;
2991 case RADEON_PARAM_IRQ_NR:
2992 value = dev->irq;
2993 break;
2994 case RADEON_PARAM_GART_BASE:
2995 value = dev_priv->gart_vm_start;
2996 break;
2997 case RADEON_PARAM_REGISTER_HANDLE:
2998 value = dev_priv->mmio->offset;
2999 break;
3000 case RADEON_PARAM_STATUS_HANDLE:
3001 value = dev_priv->ring_rptr_offset;
3002 break;
3003#if BITS_PER_LONG == 32
3004 /*
3005 * This ioctl() doesn't work on 64-bit platforms because hw_lock is a
3006 * pointer which can't fit into an int-sized variable. According to
3007 * Michel Dänzer, the ioctl() is only used on embedded platforms, so
3008 * not supporting it shouldn't be a problem. If the same functionality
3009 * is needed on 64-bit platforms, a new ioctl() would have to be added,
3010 * so backwards-compatibility for the embedded platforms can be
3011 * maintained. --davidm 4-Feb-2004.
3012 */
3013 case RADEON_PARAM_SAREA_HANDLE:
3014 /* The lock is the first dword in the sarea. */
3015 value = (long)dev->lock.hw_lock;
3016 break;
3017#endif
3018 case RADEON_PARAM_GART_TEX_HANDLE:
3019 value = dev_priv->gart_textures_offset;
3020 break;
3021 case RADEON_PARAM_SCRATCH_OFFSET:
3022 if (!dev_priv->writeback_works)
3023 return -EINVAL;
3024 value = RADEON_SCRATCH_REG_OFFSET;
3025 break;
3026 case RADEON_PARAM_CARD_TYPE:
3027 if (dev_priv->flags & RADEON_IS_PCIE)
3028 value = RADEON_CARD_PCIE;
3029 else if (dev_priv->flags & RADEON_IS_AGP)
3030 value = RADEON_CARD_AGP;
3031 else
3032 value = RADEON_CARD_PCI;
3033 break;
3034 case RADEON_PARAM_VBLANK_CRTC:
3035 value = radeon_vblank_crtc_get(dev);
3036 break;
3037 case RADEON_PARAM_FB_LOCATION:
3038 value = radeon_read_fb_location(dev_priv);
3039 break;
3040 default:
3041 DRM_DEBUG("Invalid parameter %d\n", param->param);
3042 return -EINVAL;
3043 }
3044
3045 if (DRM_COPY_TO_USER(param->value, &value, sizeof(int))) {
3046 DRM_ERROR("copy_to_user\n");
3047 return -EFAULT;
3048 }
3049
3050 return 0;
3051}
3052
3053static int radeon_cp_setparam(struct drm_device *dev, void *data, struct drm_file *file_priv)
3054{
3055 drm_radeon_private_t *dev_priv = dev->dev_private;
3056 drm_radeon_setparam_t *sp = data;
3057 struct drm_radeon_driver_file_fields *radeon_priv;
3058
3059 switch (sp->param) {
3060 case RADEON_SETPARAM_FB_LOCATION:
3061 radeon_priv = file_priv->driver_priv;
3062 radeon_priv->radeon_fb_delta = dev_priv->fb_location -
3063 sp->value;
3064 break;
3065 case RADEON_SETPARAM_SWITCH_TILING:
3066 if (sp->value == 0) {
3067 DRM_DEBUG("color tiling disabled\n");
3068 dev_priv->front_pitch_offset &= ~RADEON_DST_TILE_MACRO;
3069 dev_priv->back_pitch_offset &= ~RADEON_DST_TILE_MACRO;
3070 dev_priv->sarea_priv->tiling_enabled = 0;
3071 } else if (sp->value == 1) {
3072 DRM_DEBUG("color tiling enabled\n");
3073 dev_priv->front_pitch_offset |= RADEON_DST_TILE_MACRO;
3074 dev_priv->back_pitch_offset |= RADEON_DST_TILE_MACRO;
3075 dev_priv->sarea_priv->tiling_enabled = 1;
3076 }
3077 break;
3078 case RADEON_SETPARAM_PCIGART_LOCATION:
3079 dev_priv->pcigart_offset = sp->value;
3080 dev_priv->pcigart_offset_set = 1;
3081 break;
3082 case RADEON_SETPARAM_NEW_MEMMAP:
3083 dev_priv->new_memmap = sp->value;
3084 break;
3085 case RADEON_SETPARAM_PCIGART_TABLE_SIZE:
3086 dev_priv->gart_info.table_size = sp->value;
3087 if (dev_priv->gart_info.table_size < RADEON_PCIGART_TABLE_SIZE)
3088 dev_priv->gart_info.table_size = RADEON_PCIGART_TABLE_SIZE;
3089 break;
3090 case RADEON_SETPARAM_VBLANK_CRTC:
3091 return radeon_vblank_crtc_set(dev, sp->value);
3092 break;
3093 default:
3094 DRM_DEBUG("Invalid parameter %d\n", sp->param);
3095 return -EINVAL;
3096 }
3097
3098 return 0;
3099}
3100
3101/* When a client dies:
3102 * - Check for and clean up flipped page state
3103 * - Free any alloced GART memory.
3104 * - Free any alloced radeon surfaces.
3105 *
3106 * DRM infrastructure takes care of reclaiming dma buffers.
3107 */
3108void radeon_driver_preclose(struct drm_device *dev, struct drm_file *file_priv)
3109{
3110 if (dev->dev_private) {
3111 drm_radeon_private_t *dev_priv = dev->dev_private;
3112 dev_priv->page_flipping = 0;
3113 radeon_mem_release(file_priv, dev_priv->gart_heap);
3114 radeon_mem_release(file_priv, dev_priv->fb_heap);
3115 radeon_surfaces_release(file_priv, dev_priv);
3116 }
3117}
3118
3119void radeon_driver_lastclose(struct drm_device *dev)
3120{
3121 if (dev->dev_private) {
3122 drm_radeon_private_t *dev_priv = dev->dev_private;
3123
3124 if (dev_priv->sarea_priv &&
3125 dev_priv->sarea_priv->pfCurrentPage != 0)
3126 radeon_cp_dispatch_flip(dev);
3127 }
3128
3129 radeon_do_release(dev);
3130}
3131
3132int radeon_driver_open(struct drm_device *dev, struct drm_file *file_priv)
3133{
3134 drm_radeon_private_t *dev_priv = dev->dev_private;
3135 struct drm_radeon_driver_file_fields *radeon_priv;
3136
3137 DRM_DEBUG("\n");
3138 radeon_priv =
3139 (struct drm_radeon_driver_file_fields *)
3140 drm_alloc(sizeof(*radeon_priv), DRM_MEM_FILES);
3141
3142 if (!radeon_priv)
3143 return -ENOMEM;
3144
3145 file_priv->driver_priv = radeon_priv;
3146
3147 if (dev_priv)
3148 radeon_priv->radeon_fb_delta = dev_priv->fb_location;
3149 else
3150 radeon_priv->radeon_fb_delta = 0;
3151 return 0;
3152}
3153
3154void radeon_driver_postclose(struct drm_device *dev, struct drm_file *file_priv)
3155{
3156 struct drm_radeon_driver_file_fields *radeon_priv =
3157 file_priv->driver_priv;
3158
3159 drm_free(radeon_priv, sizeof(*radeon_priv), DRM_MEM_FILES);
3160}
3161
3162struct drm_ioctl_desc radeon_ioctls[] = {
3163 DRM_IOCTL_DEF(DRM_RADEON_CP_INIT, radeon_cp_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
3164 DRM_IOCTL_DEF(DRM_RADEON_CP_START, radeon_cp_start, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
3165 DRM_IOCTL_DEF(DRM_RADEON_CP_STOP, radeon_cp_stop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
3166 DRM_IOCTL_DEF(DRM_RADEON_CP_RESET, radeon_cp_reset, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
3167 DRM_IOCTL_DEF(DRM_RADEON_CP_IDLE, radeon_cp_idle, DRM_AUTH),
3168 DRM_IOCTL_DEF(DRM_RADEON_CP_RESUME, radeon_cp_resume, DRM_AUTH),
3169 DRM_IOCTL_DEF(DRM_RADEON_RESET, radeon_engine_reset, DRM_AUTH),
3170 DRM_IOCTL_DEF(DRM_RADEON_FULLSCREEN, radeon_fullscreen, DRM_AUTH),
3171 DRM_IOCTL_DEF(DRM_RADEON_SWAP, radeon_cp_swap, DRM_AUTH),
3172 DRM_IOCTL_DEF(DRM_RADEON_CLEAR, radeon_cp_clear, DRM_AUTH),
3173 DRM_IOCTL_DEF(DRM_RADEON_VERTEX, radeon_cp_vertex, DRM_AUTH),
3174 DRM_IOCTL_DEF(DRM_RADEON_INDICES, radeon_cp_indices, DRM_AUTH),
3175 DRM_IOCTL_DEF(DRM_RADEON_TEXTURE, radeon_cp_texture, DRM_AUTH),
3176 DRM_IOCTL_DEF(DRM_RADEON_STIPPLE, radeon_cp_stipple, DRM_AUTH),
3177 DRM_IOCTL_DEF(DRM_RADEON_INDIRECT, radeon_cp_indirect, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
3178 DRM_IOCTL_DEF(DRM_RADEON_VERTEX2, radeon_cp_vertex2, DRM_AUTH),
3179 DRM_IOCTL_DEF(DRM_RADEON_CMDBUF, radeon_cp_cmdbuf, DRM_AUTH),
3180 DRM_IOCTL_DEF(DRM_RADEON_GETPARAM, radeon_cp_getparam, DRM_AUTH),
3181 DRM_IOCTL_DEF(DRM_RADEON_FLIP, radeon_cp_flip, DRM_AUTH),
3182 DRM_IOCTL_DEF(DRM_RADEON_ALLOC, radeon_mem_alloc, DRM_AUTH),
3183 DRM_IOCTL_DEF(DRM_RADEON_FREE, radeon_mem_free, DRM_AUTH),
3184 DRM_IOCTL_DEF(DRM_RADEON_INIT_HEAP, radeon_mem_init_heap, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
3185 DRM_IOCTL_DEF(DRM_RADEON_IRQ_EMIT, radeon_irq_emit, DRM_AUTH),
3186 DRM_IOCTL_DEF(DRM_RADEON_IRQ_WAIT, radeon_irq_wait, DRM_AUTH),
3187 DRM_IOCTL_DEF(DRM_RADEON_SETPARAM, radeon_cp_setparam, DRM_AUTH),
3188 DRM_IOCTL_DEF(DRM_RADEON_SURF_ALLOC, radeon_surface_alloc, DRM_AUTH),
3189 DRM_IOCTL_DEF(DRM_RADEON_SURF_FREE, radeon_surface_free, DRM_AUTH)
3190};
3191
3192int radeon_max_ioctl = DRM_ARRAY_SIZE(radeon_ioctls);
diff --git a/drivers/char/drm/savage_bci.c b/drivers/char/drm/savage_bci.c
deleted file mode 100644
index d465b2f9c1cd..000000000000
--- a/drivers/char/drm/savage_bci.c
+++ /dev/null
@@ -1,1095 +0,0 @@
1/* savage_bci.c -- BCI support for Savage
2 *
3 * Copyright 2004 Felix Kuehling
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sub license,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial portions
15 * of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 * NON-INFRINGEMENT. IN NO EVENT SHALL FELIX KUEHLING BE LIABLE FOR
21 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
22 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 */
25#include "drmP.h"
26#include "savage_drm.h"
27#include "savage_drv.h"
28
29/* Need a long timeout for shadow status updates can take a while
30 * and so can waiting for events when the queue is full. */
31#define SAVAGE_DEFAULT_USEC_TIMEOUT 1000000 /* 1s */
32#define SAVAGE_EVENT_USEC_TIMEOUT 5000000 /* 5s */
33#define SAVAGE_FREELIST_DEBUG 0
34
35static int savage_do_cleanup_bci(struct drm_device *dev);
36
37static int
38savage_bci_wait_fifo_shadow(drm_savage_private_t * dev_priv, unsigned int n)
39{
40 uint32_t mask = dev_priv->status_used_mask;
41 uint32_t threshold = dev_priv->bci_threshold_hi;
42 uint32_t status;
43 int i;
44
45#if SAVAGE_BCI_DEBUG
46 if (n > dev_priv->cob_size + SAVAGE_BCI_FIFO_SIZE - threshold)
47 DRM_ERROR("Trying to emit %d words "
48 "(more than guaranteed space in COB)\n", n);
49#endif
50
51 for (i = 0; i < SAVAGE_DEFAULT_USEC_TIMEOUT; i++) {
52 DRM_MEMORYBARRIER();
53 status = dev_priv->status_ptr[0];
54 if ((status & mask) < threshold)
55 return 0;
56 DRM_UDELAY(1);
57 }
58
59#if SAVAGE_BCI_DEBUG
60 DRM_ERROR("failed!\n");
61 DRM_INFO(" status=0x%08x, threshold=0x%08x\n", status, threshold);
62#endif
63 return -EBUSY;
64}
65
66static int
67savage_bci_wait_fifo_s3d(drm_savage_private_t * dev_priv, unsigned int n)
68{
69 uint32_t maxUsed = dev_priv->cob_size + SAVAGE_BCI_FIFO_SIZE - n;
70 uint32_t status;
71 int i;
72
73 for (i = 0; i < SAVAGE_DEFAULT_USEC_TIMEOUT; i++) {
74 status = SAVAGE_READ(SAVAGE_STATUS_WORD0);
75 if ((status & SAVAGE_FIFO_USED_MASK_S3D) <= maxUsed)
76 return 0;
77 DRM_UDELAY(1);
78 }
79
80#if SAVAGE_BCI_DEBUG
81 DRM_ERROR("failed!\n");
82 DRM_INFO(" status=0x%08x\n", status);
83#endif
84 return -EBUSY;
85}
86
87static int
88savage_bci_wait_fifo_s4(drm_savage_private_t * dev_priv, unsigned int n)
89{
90 uint32_t maxUsed = dev_priv->cob_size + SAVAGE_BCI_FIFO_SIZE - n;
91 uint32_t status;
92 int i;
93
94 for (i = 0; i < SAVAGE_DEFAULT_USEC_TIMEOUT; i++) {
95 status = SAVAGE_READ(SAVAGE_ALT_STATUS_WORD0);
96 if ((status & SAVAGE_FIFO_USED_MASK_S4) <= maxUsed)
97 return 0;
98 DRM_UDELAY(1);
99 }
100
101#if SAVAGE_BCI_DEBUG
102 DRM_ERROR("failed!\n");
103 DRM_INFO(" status=0x%08x\n", status);
104#endif
105 return -EBUSY;
106}
107
108/*
109 * Waiting for events.
110 *
111 * The BIOSresets the event tag to 0 on mode changes. Therefore we
112 * never emit 0 to the event tag. If we find a 0 event tag we know the
113 * BIOS stomped on it and return success assuming that the BIOS waited
114 * for engine idle.
115 *
116 * Note: if the Xserver uses the event tag it has to follow the same
117 * rule. Otherwise there may be glitches every 2^16 events.
118 */
119static int
120savage_bci_wait_event_shadow(drm_savage_private_t * dev_priv, uint16_t e)
121{
122 uint32_t status;
123 int i;
124
125 for (i = 0; i < SAVAGE_EVENT_USEC_TIMEOUT; i++) {
126 DRM_MEMORYBARRIER();
127 status = dev_priv->status_ptr[1];
128 if ((((status & 0xffff) - e) & 0xffff) <= 0x7fff ||
129 (status & 0xffff) == 0)
130 return 0;
131 DRM_UDELAY(1);
132 }
133
134#if SAVAGE_BCI_DEBUG
135 DRM_ERROR("failed!\n");
136 DRM_INFO(" status=0x%08x, e=0x%04x\n", status, e);
137#endif
138
139 return -EBUSY;
140}
141
142static int
143savage_bci_wait_event_reg(drm_savage_private_t * dev_priv, uint16_t e)
144{
145 uint32_t status;
146 int i;
147
148 for (i = 0; i < SAVAGE_EVENT_USEC_TIMEOUT; i++) {
149 status = SAVAGE_READ(SAVAGE_STATUS_WORD1);
150 if ((((status & 0xffff) - e) & 0xffff) <= 0x7fff ||
151 (status & 0xffff) == 0)
152 return 0;
153 DRM_UDELAY(1);
154 }
155
156#if SAVAGE_BCI_DEBUG
157 DRM_ERROR("failed!\n");
158 DRM_INFO(" status=0x%08x, e=0x%04x\n", status, e);
159#endif
160
161 return -EBUSY;
162}
163
164uint16_t savage_bci_emit_event(drm_savage_private_t * dev_priv,
165 unsigned int flags)
166{
167 uint16_t count;
168 BCI_LOCALS;
169
170 if (dev_priv->status_ptr) {
171 /* coordinate with Xserver */
172 count = dev_priv->status_ptr[1023];
173 if (count < dev_priv->event_counter)
174 dev_priv->event_wrap++;
175 } else {
176 count = dev_priv->event_counter;
177 }
178 count = (count + 1) & 0xffff;
179 if (count == 0) {
180 count++; /* See the comment above savage_wait_event_*. */
181 dev_priv->event_wrap++;
182 }
183 dev_priv->event_counter = count;
184 if (dev_priv->status_ptr)
185 dev_priv->status_ptr[1023] = (uint32_t) count;
186
187 if ((flags & (SAVAGE_WAIT_2D | SAVAGE_WAIT_3D))) {
188 unsigned int wait_cmd = BCI_CMD_WAIT;
189 if ((flags & SAVAGE_WAIT_2D))
190 wait_cmd |= BCI_CMD_WAIT_2D;
191 if ((flags & SAVAGE_WAIT_3D))
192 wait_cmd |= BCI_CMD_WAIT_3D;
193 BEGIN_BCI(2);
194 BCI_WRITE(wait_cmd);
195 } else {
196 BEGIN_BCI(1);
197 }
198 BCI_WRITE(BCI_CMD_UPDATE_EVENT_TAG | (uint32_t) count);
199
200 return count;
201}
202
203/*
204 * Freelist management
205 */
206static int savage_freelist_init(struct drm_device * dev)
207{
208 drm_savage_private_t *dev_priv = dev->dev_private;
209 struct drm_device_dma *dma = dev->dma;
210 struct drm_buf *buf;
211 drm_savage_buf_priv_t *entry;
212 int i;
213 DRM_DEBUG("count=%d\n", dma->buf_count);
214
215 dev_priv->head.next = &dev_priv->tail;
216 dev_priv->head.prev = NULL;
217 dev_priv->head.buf = NULL;
218
219 dev_priv->tail.next = NULL;
220 dev_priv->tail.prev = &dev_priv->head;
221 dev_priv->tail.buf = NULL;
222
223 for (i = 0; i < dma->buf_count; i++) {
224 buf = dma->buflist[i];
225 entry = buf->dev_private;
226
227 SET_AGE(&entry->age, 0, 0);
228 entry->buf = buf;
229
230 entry->next = dev_priv->head.next;
231 entry->prev = &dev_priv->head;
232 dev_priv->head.next->prev = entry;
233 dev_priv->head.next = entry;
234 }
235
236 return 0;
237}
238
239static struct drm_buf *savage_freelist_get(struct drm_device * dev)
240{
241 drm_savage_private_t *dev_priv = dev->dev_private;
242 drm_savage_buf_priv_t *tail = dev_priv->tail.prev;
243 uint16_t event;
244 unsigned int wrap;
245 DRM_DEBUG("\n");
246
247 UPDATE_EVENT_COUNTER();
248 if (dev_priv->status_ptr)
249 event = dev_priv->status_ptr[1] & 0xffff;
250 else
251 event = SAVAGE_READ(SAVAGE_STATUS_WORD1) & 0xffff;
252 wrap = dev_priv->event_wrap;
253 if (event > dev_priv->event_counter)
254 wrap--; /* hardware hasn't passed the last wrap yet */
255
256 DRM_DEBUG(" tail=0x%04x %d\n", tail->age.event, tail->age.wrap);
257 DRM_DEBUG(" head=0x%04x %d\n", event, wrap);
258
259 if (tail->buf && (TEST_AGE(&tail->age, event, wrap) || event == 0)) {
260 drm_savage_buf_priv_t *next = tail->next;
261 drm_savage_buf_priv_t *prev = tail->prev;
262 prev->next = next;
263 next->prev = prev;
264 tail->next = tail->prev = NULL;
265 return tail->buf;
266 }
267
268 DRM_DEBUG("returning NULL, tail->buf=%p!\n", tail->buf);
269 return NULL;
270}
271
272void savage_freelist_put(struct drm_device * dev, struct drm_buf * buf)
273{
274 drm_savage_private_t *dev_priv = dev->dev_private;
275 drm_savage_buf_priv_t *entry = buf->dev_private, *prev, *next;
276
277 DRM_DEBUG("age=0x%04x wrap=%d\n", entry->age.event, entry->age.wrap);
278
279 if (entry->next != NULL || entry->prev != NULL) {
280 DRM_ERROR("entry already on freelist.\n");
281 return;
282 }
283
284 prev = &dev_priv->head;
285 next = prev->next;
286 prev->next = entry;
287 next->prev = entry;
288 entry->prev = prev;
289 entry->next = next;
290}
291
292/*
293 * Command DMA
294 */
295static int savage_dma_init(drm_savage_private_t * dev_priv)
296{
297 unsigned int i;
298
299 dev_priv->nr_dma_pages = dev_priv->cmd_dma->size /
300 (SAVAGE_DMA_PAGE_SIZE * 4);
301 dev_priv->dma_pages = drm_alloc(sizeof(drm_savage_dma_page_t) *
302 dev_priv->nr_dma_pages, DRM_MEM_DRIVER);
303 if (dev_priv->dma_pages == NULL)
304 return -ENOMEM;
305
306 for (i = 0; i < dev_priv->nr_dma_pages; ++i) {
307 SET_AGE(&dev_priv->dma_pages[i].age, 0, 0);
308 dev_priv->dma_pages[i].used = 0;
309 dev_priv->dma_pages[i].flushed = 0;
310 }
311 SET_AGE(&dev_priv->last_dma_age, 0, 0);
312
313 dev_priv->first_dma_page = 0;
314 dev_priv->current_dma_page = 0;
315
316 return 0;
317}
318
319void savage_dma_reset(drm_savage_private_t * dev_priv)
320{
321 uint16_t event;
322 unsigned int wrap, i;
323 event = savage_bci_emit_event(dev_priv, 0);
324 wrap = dev_priv->event_wrap;
325 for (i = 0; i < dev_priv->nr_dma_pages; ++i) {
326 SET_AGE(&dev_priv->dma_pages[i].age, event, wrap);
327 dev_priv->dma_pages[i].used = 0;
328 dev_priv->dma_pages[i].flushed = 0;
329 }
330 SET_AGE(&dev_priv->last_dma_age, event, wrap);
331 dev_priv->first_dma_page = dev_priv->current_dma_page = 0;
332}
333
334void savage_dma_wait(drm_savage_private_t * dev_priv, unsigned int page)
335{
336 uint16_t event;
337 unsigned int wrap;
338
339 /* Faked DMA buffer pages don't age. */
340 if (dev_priv->cmd_dma == &dev_priv->fake_dma)
341 return;
342
343 UPDATE_EVENT_COUNTER();
344 if (dev_priv->status_ptr)
345 event = dev_priv->status_ptr[1] & 0xffff;
346 else
347 event = SAVAGE_READ(SAVAGE_STATUS_WORD1) & 0xffff;
348 wrap = dev_priv->event_wrap;
349 if (event > dev_priv->event_counter)
350 wrap--; /* hardware hasn't passed the last wrap yet */
351
352 if (dev_priv->dma_pages[page].age.wrap > wrap ||
353 (dev_priv->dma_pages[page].age.wrap == wrap &&
354 dev_priv->dma_pages[page].age.event > event)) {
355 if (dev_priv->wait_evnt(dev_priv,
356 dev_priv->dma_pages[page].age.event)
357 < 0)
358 DRM_ERROR("wait_evnt failed!\n");
359 }
360}
361
362uint32_t *savage_dma_alloc(drm_savage_private_t * dev_priv, unsigned int n)
363{
364 unsigned int cur = dev_priv->current_dma_page;
365 unsigned int rest = SAVAGE_DMA_PAGE_SIZE -
366 dev_priv->dma_pages[cur].used;
367 unsigned int nr_pages = (n - rest + SAVAGE_DMA_PAGE_SIZE - 1) /
368 SAVAGE_DMA_PAGE_SIZE;
369 uint32_t *dma_ptr;
370 unsigned int i;
371
372 DRM_DEBUG("cur=%u, cur->used=%u, n=%u, rest=%u, nr_pages=%u\n",
373 cur, dev_priv->dma_pages[cur].used, n, rest, nr_pages);
374
375 if (cur + nr_pages < dev_priv->nr_dma_pages) {
376 dma_ptr = (uint32_t *) dev_priv->cmd_dma->handle +
377 cur * SAVAGE_DMA_PAGE_SIZE + dev_priv->dma_pages[cur].used;
378 if (n < rest)
379 rest = n;
380 dev_priv->dma_pages[cur].used += rest;
381 n -= rest;
382 cur++;
383 } else {
384 dev_priv->dma_flush(dev_priv);
385 nr_pages =
386 (n + SAVAGE_DMA_PAGE_SIZE - 1) / SAVAGE_DMA_PAGE_SIZE;
387 for (i = cur; i < dev_priv->nr_dma_pages; ++i) {
388 dev_priv->dma_pages[i].age = dev_priv->last_dma_age;
389 dev_priv->dma_pages[i].used = 0;
390 dev_priv->dma_pages[i].flushed = 0;
391 }
392 dma_ptr = (uint32_t *) dev_priv->cmd_dma->handle;
393 dev_priv->first_dma_page = cur = 0;
394 }
395 for (i = cur; nr_pages > 0; ++i, --nr_pages) {
396#if SAVAGE_DMA_DEBUG
397 if (dev_priv->dma_pages[i].used) {
398 DRM_ERROR("unflushed page %u: used=%u\n",
399 i, dev_priv->dma_pages[i].used);
400 }
401#endif
402 if (n > SAVAGE_DMA_PAGE_SIZE)
403 dev_priv->dma_pages[i].used = SAVAGE_DMA_PAGE_SIZE;
404 else
405 dev_priv->dma_pages[i].used = n;
406 n -= SAVAGE_DMA_PAGE_SIZE;
407 }
408 dev_priv->current_dma_page = --i;
409
410 DRM_DEBUG("cur=%u, cur->used=%u, n=%u\n",
411 i, dev_priv->dma_pages[i].used, n);
412
413 savage_dma_wait(dev_priv, dev_priv->current_dma_page);
414
415 return dma_ptr;
416}
417
418static void savage_dma_flush(drm_savage_private_t * dev_priv)
419{
420 unsigned int first = dev_priv->first_dma_page;
421 unsigned int cur = dev_priv->current_dma_page;
422 uint16_t event;
423 unsigned int wrap, pad, align, len, i;
424 unsigned long phys_addr;
425 BCI_LOCALS;
426
427 if (first == cur &&
428 dev_priv->dma_pages[cur].used == dev_priv->dma_pages[cur].flushed)
429 return;
430
431 /* pad length to multiples of 2 entries
432 * align start of next DMA block to multiles of 8 entries */
433 pad = -dev_priv->dma_pages[cur].used & 1;
434 align = -(dev_priv->dma_pages[cur].used + pad) & 7;
435
436 DRM_DEBUG("first=%u, cur=%u, first->flushed=%u, cur->used=%u, "
437 "pad=%u, align=%u\n",
438 first, cur, dev_priv->dma_pages[first].flushed,
439 dev_priv->dma_pages[cur].used, pad, align);
440
441 /* pad with noops */
442 if (pad) {
443 uint32_t *dma_ptr = (uint32_t *) dev_priv->cmd_dma->handle +
444 cur * SAVAGE_DMA_PAGE_SIZE + dev_priv->dma_pages[cur].used;
445 dev_priv->dma_pages[cur].used += pad;
446 while (pad != 0) {
447 *dma_ptr++ = BCI_CMD_WAIT;
448 pad--;
449 }
450 }
451
452 DRM_MEMORYBARRIER();
453
454 /* do flush ... */
455 phys_addr = dev_priv->cmd_dma->offset +
456 (first * SAVAGE_DMA_PAGE_SIZE +
457 dev_priv->dma_pages[first].flushed) * 4;
458 len = (cur - first) * SAVAGE_DMA_PAGE_SIZE +
459 dev_priv->dma_pages[cur].used - dev_priv->dma_pages[first].flushed;
460
461 DRM_DEBUG("phys_addr=%lx, len=%u\n",
462 phys_addr | dev_priv->dma_type, len);
463
464 BEGIN_BCI(3);
465 BCI_SET_REGISTERS(SAVAGE_DMABUFADDR, 1);
466 BCI_WRITE(phys_addr | dev_priv->dma_type);
467 BCI_DMA(len);
468
469 /* fix alignment of the start of the next block */
470 dev_priv->dma_pages[cur].used += align;
471
472 /* age DMA pages */
473 event = savage_bci_emit_event(dev_priv, 0);
474 wrap = dev_priv->event_wrap;
475 for (i = first; i < cur; ++i) {
476 SET_AGE(&dev_priv->dma_pages[i].age, event, wrap);
477 dev_priv->dma_pages[i].used = 0;
478 dev_priv->dma_pages[i].flushed = 0;
479 }
480 /* age the current page only when it's full */
481 if (dev_priv->dma_pages[cur].used == SAVAGE_DMA_PAGE_SIZE) {
482 SET_AGE(&dev_priv->dma_pages[cur].age, event, wrap);
483 dev_priv->dma_pages[cur].used = 0;
484 dev_priv->dma_pages[cur].flushed = 0;
485 /* advance to next page */
486 cur++;
487 if (cur == dev_priv->nr_dma_pages)
488 cur = 0;
489 dev_priv->first_dma_page = dev_priv->current_dma_page = cur;
490 } else {
491 dev_priv->first_dma_page = cur;
492 dev_priv->dma_pages[cur].flushed = dev_priv->dma_pages[i].used;
493 }
494 SET_AGE(&dev_priv->last_dma_age, event, wrap);
495
496 DRM_DEBUG("first=cur=%u, cur->used=%u, cur->flushed=%u\n", cur,
497 dev_priv->dma_pages[cur].used,
498 dev_priv->dma_pages[cur].flushed);
499}
500
501static void savage_fake_dma_flush(drm_savage_private_t * dev_priv)
502{
503 unsigned int i, j;
504 BCI_LOCALS;
505
506 if (dev_priv->first_dma_page == dev_priv->current_dma_page &&
507 dev_priv->dma_pages[dev_priv->current_dma_page].used == 0)
508 return;
509
510 DRM_DEBUG("first=%u, cur=%u, cur->used=%u\n",
511 dev_priv->first_dma_page, dev_priv->current_dma_page,
512 dev_priv->dma_pages[dev_priv->current_dma_page].used);
513
514 for (i = dev_priv->first_dma_page;
515 i <= dev_priv->current_dma_page && dev_priv->dma_pages[i].used;
516 ++i) {
517 uint32_t *dma_ptr = (uint32_t *) dev_priv->cmd_dma->handle +
518 i * SAVAGE_DMA_PAGE_SIZE;
519#if SAVAGE_DMA_DEBUG
520 /* Sanity check: all pages except the last one must be full. */
521 if (i < dev_priv->current_dma_page &&
522 dev_priv->dma_pages[i].used != SAVAGE_DMA_PAGE_SIZE) {
523 DRM_ERROR("partial DMA page %u: used=%u",
524 i, dev_priv->dma_pages[i].used);
525 }
526#endif
527 BEGIN_BCI(dev_priv->dma_pages[i].used);
528 for (j = 0; j < dev_priv->dma_pages[i].used; ++j) {
529 BCI_WRITE(dma_ptr[j]);
530 }
531 dev_priv->dma_pages[i].used = 0;
532 }
533
534 /* reset to first page */
535 dev_priv->first_dma_page = dev_priv->current_dma_page = 0;
536}
537
538int savage_driver_load(struct drm_device *dev, unsigned long chipset)
539{
540 drm_savage_private_t *dev_priv;
541
542 dev_priv = drm_alloc(sizeof(drm_savage_private_t), DRM_MEM_DRIVER);
543 if (dev_priv == NULL)
544 return -ENOMEM;
545
546 memset(dev_priv, 0, sizeof(drm_savage_private_t));
547 dev->dev_private = (void *)dev_priv;
548
549 dev_priv->chipset = (enum savage_family)chipset;
550
551 return 0;
552}
553
554
555/*
556 * Initalize mappings. On Savage4 and SavageIX the alignment
557 * and size of the aperture is not suitable for automatic MTRR setup
558 * in drm_addmap. Therefore we add them manually before the maps are
559 * initialized, and tear them down on last close.
560 */
561int savage_driver_firstopen(struct drm_device *dev)
562{
563 drm_savage_private_t *dev_priv = dev->dev_private;
564 unsigned long mmio_base, fb_base, fb_size, aperture_base;
565 /* fb_rsrc and aper_rsrc aren't really used currently, but still exist
566 * in case we decide we need information on the BAR for BSD in the
567 * future.
568 */
569 unsigned int fb_rsrc, aper_rsrc;
570 int ret = 0;
571
572 dev_priv->mtrr[0].handle = -1;
573 dev_priv->mtrr[1].handle = -1;
574 dev_priv->mtrr[2].handle = -1;
575 if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) {
576 fb_rsrc = 0;
577 fb_base = drm_get_resource_start(dev, 0);
578 fb_size = SAVAGE_FB_SIZE_S3;
579 mmio_base = fb_base + SAVAGE_FB_SIZE_S3;
580 aper_rsrc = 0;
581 aperture_base = fb_base + SAVAGE_APERTURE_OFFSET;
582 /* this should always be true */
583 if (drm_get_resource_len(dev, 0) == 0x08000000) {
584 /* Don't make MMIO write-cobining! We need 3
585 * MTRRs. */
586 dev_priv->mtrr[0].base = fb_base;
587 dev_priv->mtrr[0].size = 0x01000000;
588 dev_priv->mtrr[0].handle =
589 drm_mtrr_add(dev_priv->mtrr[0].base,
590 dev_priv->mtrr[0].size, DRM_MTRR_WC);
591 dev_priv->mtrr[1].base = fb_base + 0x02000000;
592 dev_priv->mtrr[1].size = 0x02000000;
593 dev_priv->mtrr[1].handle =
594 drm_mtrr_add(dev_priv->mtrr[1].base,
595 dev_priv->mtrr[1].size, DRM_MTRR_WC);
596 dev_priv->mtrr[2].base = fb_base + 0x04000000;
597 dev_priv->mtrr[2].size = 0x04000000;
598 dev_priv->mtrr[2].handle =
599 drm_mtrr_add(dev_priv->mtrr[2].base,
600 dev_priv->mtrr[2].size, DRM_MTRR_WC);
601 } else {
602 DRM_ERROR("strange pci_resource_len %08lx\n",
603 drm_get_resource_len(dev, 0));
604 }
605 } else if (dev_priv->chipset != S3_SUPERSAVAGE &&
606 dev_priv->chipset != S3_SAVAGE2000) {
607 mmio_base = drm_get_resource_start(dev, 0);
608 fb_rsrc = 1;
609 fb_base = drm_get_resource_start(dev, 1);
610 fb_size = SAVAGE_FB_SIZE_S4;
611 aper_rsrc = 1;
612 aperture_base = fb_base + SAVAGE_APERTURE_OFFSET;
613 /* this should always be true */
614 if (drm_get_resource_len(dev, 1) == 0x08000000) {
615 /* Can use one MTRR to cover both fb and
616 * aperture. */
617 dev_priv->mtrr[0].base = fb_base;
618 dev_priv->mtrr[0].size = 0x08000000;
619 dev_priv->mtrr[0].handle =
620 drm_mtrr_add(dev_priv->mtrr[0].base,
621 dev_priv->mtrr[0].size, DRM_MTRR_WC);
622 } else {
623 DRM_ERROR("strange pci_resource_len %08lx\n",
624 drm_get_resource_len(dev, 1));
625 }
626 } else {
627 mmio_base = drm_get_resource_start(dev, 0);
628 fb_rsrc = 1;
629 fb_base = drm_get_resource_start(dev, 1);
630 fb_size = drm_get_resource_len(dev, 1);
631 aper_rsrc = 2;
632 aperture_base = drm_get_resource_start(dev, 2);
633 /* Automatic MTRR setup will do the right thing. */
634 }
635
636 ret = drm_addmap(dev, mmio_base, SAVAGE_MMIO_SIZE, _DRM_REGISTERS,
637 _DRM_READ_ONLY, &dev_priv->mmio);
638 if (ret)
639 return ret;
640
641 ret = drm_addmap(dev, fb_base, fb_size, _DRM_FRAME_BUFFER,
642 _DRM_WRITE_COMBINING, &dev_priv->fb);
643 if (ret)
644 return ret;
645
646 ret = drm_addmap(dev, aperture_base, SAVAGE_APERTURE_SIZE,
647 _DRM_FRAME_BUFFER, _DRM_WRITE_COMBINING,
648 &dev_priv->aperture);
649 if (ret)
650 return ret;
651
652 return ret;
653}
654
655/*
656 * Delete MTRRs and free device-private data.
657 */
658void savage_driver_lastclose(struct drm_device *dev)
659{
660 drm_savage_private_t *dev_priv = dev->dev_private;
661 int i;
662
663 for (i = 0; i < 3; ++i)
664 if (dev_priv->mtrr[i].handle >= 0)
665 drm_mtrr_del(dev_priv->mtrr[i].handle,
666 dev_priv->mtrr[i].base,
667 dev_priv->mtrr[i].size, DRM_MTRR_WC);
668}
669
670int savage_driver_unload(struct drm_device *dev)
671{
672 drm_savage_private_t *dev_priv = dev->dev_private;
673
674 drm_free(dev_priv, sizeof(drm_savage_private_t), DRM_MEM_DRIVER);
675
676 return 0;
677}
678
679static int savage_do_init_bci(struct drm_device * dev, drm_savage_init_t * init)
680{
681 drm_savage_private_t *dev_priv = dev->dev_private;
682
683 if (init->fb_bpp != 16 && init->fb_bpp != 32) {
684 DRM_ERROR("invalid frame buffer bpp %d!\n", init->fb_bpp);
685 return -EINVAL;
686 }
687 if (init->depth_bpp != 16 && init->depth_bpp != 32) {
688 DRM_ERROR("invalid depth buffer bpp %d!\n", init->fb_bpp);
689 return -EINVAL;
690 }
691 if (init->dma_type != SAVAGE_DMA_AGP &&
692 init->dma_type != SAVAGE_DMA_PCI) {
693 DRM_ERROR("invalid dma memory type %d!\n", init->dma_type);
694 return -EINVAL;
695 }
696
697 dev_priv->cob_size = init->cob_size;
698 dev_priv->bci_threshold_lo = init->bci_threshold_lo;
699 dev_priv->bci_threshold_hi = init->bci_threshold_hi;
700 dev_priv->dma_type = init->dma_type;
701
702 dev_priv->fb_bpp = init->fb_bpp;
703 dev_priv->front_offset = init->front_offset;
704 dev_priv->front_pitch = init->front_pitch;
705 dev_priv->back_offset = init->back_offset;
706 dev_priv->back_pitch = init->back_pitch;
707 dev_priv->depth_bpp = init->depth_bpp;
708 dev_priv->depth_offset = init->depth_offset;
709 dev_priv->depth_pitch = init->depth_pitch;
710
711 dev_priv->texture_offset = init->texture_offset;
712 dev_priv->texture_size = init->texture_size;
713
714 dev_priv->sarea = drm_getsarea(dev);
715 if (!dev_priv->sarea) {
716 DRM_ERROR("could not find sarea!\n");
717 savage_do_cleanup_bci(dev);
718 return -EINVAL;
719 }
720 if (init->status_offset != 0) {
721 dev_priv->status = drm_core_findmap(dev, init->status_offset);
722 if (!dev_priv->status) {
723 DRM_ERROR("could not find shadow status region!\n");
724 savage_do_cleanup_bci(dev);
725 return -EINVAL;
726 }
727 } else {
728 dev_priv->status = NULL;
729 }
730 if (dev_priv->dma_type == SAVAGE_DMA_AGP && init->buffers_offset) {
731 dev->agp_buffer_token = init->buffers_offset;
732 dev->agp_buffer_map = drm_core_findmap(dev,
733 init->buffers_offset);
734 if (!dev->agp_buffer_map) {
735 DRM_ERROR("could not find DMA buffer region!\n");
736 savage_do_cleanup_bci(dev);
737 return -EINVAL;
738 }
739 drm_core_ioremap(dev->agp_buffer_map, dev);
740 if (!dev->agp_buffer_map) {
741 DRM_ERROR("failed to ioremap DMA buffer region!\n");
742 savage_do_cleanup_bci(dev);
743 return -ENOMEM;
744 }
745 }
746 if (init->agp_textures_offset) {
747 dev_priv->agp_textures =
748 drm_core_findmap(dev, init->agp_textures_offset);
749 if (!dev_priv->agp_textures) {
750 DRM_ERROR("could not find agp texture region!\n");
751 savage_do_cleanup_bci(dev);
752 return -EINVAL;
753 }
754 } else {
755 dev_priv->agp_textures = NULL;
756 }
757
758 if (init->cmd_dma_offset) {
759 if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) {
760 DRM_ERROR("command DMA not supported on "
761 "Savage3D/MX/IX.\n");
762 savage_do_cleanup_bci(dev);
763 return -EINVAL;
764 }
765 if (dev->dma && dev->dma->buflist) {
766 DRM_ERROR("command and vertex DMA not supported "
767 "at the same time.\n");
768 savage_do_cleanup_bci(dev);
769 return -EINVAL;
770 }
771 dev_priv->cmd_dma = drm_core_findmap(dev, init->cmd_dma_offset);
772 if (!dev_priv->cmd_dma) {
773 DRM_ERROR("could not find command DMA region!\n");
774 savage_do_cleanup_bci(dev);
775 return -EINVAL;
776 }
777 if (dev_priv->dma_type == SAVAGE_DMA_AGP) {
778 if (dev_priv->cmd_dma->type != _DRM_AGP) {
779 DRM_ERROR("AGP command DMA region is not a "
780 "_DRM_AGP map!\n");
781 savage_do_cleanup_bci(dev);
782 return -EINVAL;
783 }
784 drm_core_ioremap(dev_priv->cmd_dma, dev);
785 if (!dev_priv->cmd_dma->handle) {
786 DRM_ERROR("failed to ioremap command "
787 "DMA region!\n");
788 savage_do_cleanup_bci(dev);
789 return -ENOMEM;
790 }
791 } else if (dev_priv->cmd_dma->type != _DRM_CONSISTENT) {
792 DRM_ERROR("PCI command DMA region is not a "
793 "_DRM_CONSISTENT map!\n");
794 savage_do_cleanup_bci(dev);
795 return -EINVAL;
796 }
797 } else {
798 dev_priv->cmd_dma = NULL;
799 }
800
801 dev_priv->dma_flush = savage_dma_flush;
802 if (!dev_priv->cmd_dma) {
803 DRM_DEBUG("falling back to faked command DMA.\n");
804 dev_priv->fake_dma.offset = 0;
805 dev_priv->fake_dma.size = SAVAGE_FAKE_DMA_SIZE;
806 dev_priv->fake_dma.type = _DRM_SHM;
807 dev_priv->fake_dma.handle = drm_alloc(SAVAGE_FAKE_DMA_SIZE,
808 DRM_MEM_DRIVER);
809 if (!dev_priv->fake_dma.handle) {
810 DRM_ERROR("could not allocate faked DMA buffer!\n");
811 savage_do_cleanup_bci(dev);
812 return -ENOMEM;
813 }
814 dev_priv->cmd_dma = &dev_priv->fake_dma;
815 dev_priv->dma_flush = savage_fake_dma_flush;
816 }
817
818 dev_priv->sarea_priv =
819 (drm_savage_sarea_t *) ((uint8_t *) dev_priv->sarea->handle +
820 init->sarea_priv_offset);
821
822 /* setup bitmap descriptors */
823 {
824 unsigned int color_tile_format;
825 unsigned int depth_tile_format;
826 unsigned int front_stride, back_stride, depth_stride;
827 if (dev_priv->chipset <= S3_SAVAGE4) {
828 color_tile_format = dev_priv->fb_bpp == 16 ?
829 SAVAGE_BD_TILE_16BPP : SAVAGE_BD_TILE_32BPP;
830 depth_tile_format = dev_priv->depth_bpp == 16 ?
831 SAVAGE_BD_TILE_16BPP : SAVAGE_BD_TILE_32BPP;
832 } else {
833 color_tile_format = SAVAGE_BD_TILE_DEST;
834 depth_tile_format = SAVAGE_BD_TILE_DEST;
835 }
836 front_stride = dev_priv->front_pitch / (dev_priv->fb_bpp / 8);
837 back_stride = dev_priv->back_pitch / (dev_priv->fb_bpp / 8);
838 depth_stride =
839 dev_priv->depth_pitch / (dev_priv->depth_bpp / 8);
840
841 dev_priv->front_bd = front_stride | SAVAGE_BD_BW_DISABLE |
842 (dev_priv->fb_bpp << SAVAGE_BD_BPP_SHIFT) |
843 (color_tile_format << SAVAGE_BD_TILE_SHIFT);
844
845 dev_priv->back_bd = back_stride | SAVAGE_BD_BW_DISABLE |
846 (dev_priv->fb_bpp << SAVAGE_BD_BPP_SHIFT) |
847 (color_tile_format << SAVAGE_BD_TILE_SHIFT);
848
849 dev_priv->depth_bd = depth_stride | SAVAGE_BD_BW_DISABLE |
850 (dev_priv->depth_bpp << SAVAGE_BD_BPP_SHIFT) |
851 (depth_tile_format << SAVAGE_BD_TILE_SHIFT);
852 }
853
854 /* setup status and bci ptr */
855 dev_priv->event_counter = 0;
856 dev_priv->event_wrap = 0;
857 dev_priv->bci_ptr = (volatile uint32_t *)
858 ((uint8_t *) dev_priv->mmio->handle + SAVAGE_BCI_OFFSET);
859 if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) {
860 dev_priv->status_used_mask = SAVAGE_FIFO_USED_MASK_S3D;
861 } else {
862 dev_priv->status_used_mask = SAVAGE_FIFO_USED_MASK_S4;
863 }
864 if (dev_priv->status != NULL) {
865 dev_priv->status_ptr =
866 (volatile uint32_t *)dev_priv->status->handle;
867 dev_priv->wait_fifo = savage_bci_wait_fifo_shadow;
868 dev_priv->wait_evnt = savage_bci_wait_event_shadow;
869 dev_priv->status_ptr[1023] = dev_priv->event_counter;
870 } else {
871 dev_priv->status_ptr = NULL;
872 if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) {
873 dev_priv->wait_fifo = savage_bci_wait_fifo_s3d;
874 } else {
875 dev_priv->wait_fifo = savage_bci_wait_fifo_s4;
876 }
877 dev_priv->wait_evnt = savage_bci_wait_event_reg;
878 }
879
880 /* cliprect functions */
881 if (S3_SAVAGE3D_SERIES(dev_priv->chipset))
882 dev_priv->emit_clip_rect = savage_emit_clip_rect_s3d;
883 else
884 dev_priv->emit_clip_rect = savage_emit_clip_rect_s4;
885
886 if (savage_freelist_init(dev) < 0) {
887 DRM_ERROR("could not initialize freelist\n");
888 savage_do_cleanup_bci(dev);
889 return -ENOMEM;
890 }
891
892 if (savage_dma_init(dev_priv) < 0) {
893 DRM_ERROR("could not initialize command DMA\n");
894 savage_do_cleanup_bci(dev);
895 return -ENOMEM;
896 }
897
898 return 0;
899}
900
901static int savage_do_cleanup_bci(struct drm_device * dev)
902{
903 drm_savage_private_t *dev_priv = dev->dev_private;
904
905 if (dev_priv->cmd_dma == &dev_priv->fake_dma) {
906 if (dev_priv->fake_dma.handle)
907 drm_free(dev_priv->fake_dma.handle,
908 SAVAGE_FAKE_DMA_SIZE, DRM_MEM_DRIVER);
909 } else if (dev_priv->cmd_dma && dev_priv->cmd_dma->handle &&
910 dev_priv->cmd_dma->type == _DRM_AGP &&
911 dev_priv->dma_type == SAVAGE_DMA_AGP)
912 drm_core_ioremapfree(dev_priv->cmd_dma, dev);
913
914 if (dev_priv->dma_type == SAVAGE_DMA_AGP &&
915 dev->agp_buffer_map && dev->agp_buffer_map->handle) {
916 drm_core_ioremapfree(dev->agp_buffer_map, dev);
917 /* make sure the next instance (which may be running
918 * in PCI mode) doesn't try to use an old
919 * agp_buffer_map. */
920 dev->agp_buffer_map = NULL;
921 }
922
923 if (dev_priv->dma_pages)
924 drm_free(dev_priv->dma_pages,
925 sizeof(drm_savage_dma_page_t) * dev_priv->nr_dma_pages,
926 DRM_MEM_DRIVER);
927
928 return 0;
929}
930
931static int savage_bci_init(struct drm_device *dev, void *data, struct drm_file *file_priv)
932{
933 drm_savage_init_t *init = data;
934
935 LOCK_TEST_WITH_RETURN(dev, file_priv);
936
937 switch (init->func) {
938 case SAVAGE_INIT_BCI:
939 return savage_do_init_bci(dev, init);
940 case SAVAGE_CLEANUP_BCI:
941 return savage_do_cleanup_bci(dev);
942 }
943
944 return -EINVAL;
945}
946
947static int savage_bci_event_emit(struct drm_device *dev, void *data, struct drm_file *file_priv)
948{
949 drm_savage_private_t *dev_priv = dev->dev_private;
950 drm_savage_event_emit_t *event = data;
951
952 DRM_DEBUG("\n");
953
954 LOCK_TEST_WITH_RETURN(dev, file_priv);
955
956 event->count = savage_bci_emit_event(dev_priv, event->flags);
957 event->count |= dev_priv->event_wrap << 16;
958
959 return 0;
960}
961
962static int savage_bci_event_wait(struct drm_device *dev, void *data, struct drm_file *file_priv)
963{
964 drm_savage_private_t *dev_priv = dev->dev_private;
965 drm_savage_event_wait_t *event = data;
966 unsigned int event_e, hw_e;
967 unsigned int event_w, hw_w;
968
969 DRM_DEBUG("\n");
970
971 UPDATE_EVENT_COUNTER();
972 if (dev_priv->status_ptr)
973 hw_e = dev_priv->status_ptr[1] & 0xffff;
974 else
975 hw_e = SAVAGE_READ(SAVAGE_STATUS_WORD1) & 0xffff;
976 hw_w = dev_priv->event_wrap;
977 if (hw_e > dev_priv->event_counter)
978 hw_w--; /* hardware hasn't passed the last wrap yet */
979
980 event_e = event->count & 0xffff;
981 event_w = event->count >> 16;
982
983 /* Don't need to wait if
984 * - event counter wrapped since the event was emitted or
985 * - the hardware has advanced up to or over the event to wait for.
986 */
987 if (event_w < hw_w || (event_w == hw_w && event_e <= hw_e))
988 return 0;
989 else
990 return dev_priv->wait_evnt(dev_priv, event_e);
991}
992
993/*
994 * DMA buffer management
995 */
996
997static int savage_bci_get_buffers(struct drm_device *dev,
998 struct drm_file *file_priv,
999 struct drm_dma *d)
1000{
1001 struct drm_buf *buf;
1002 int i;
1003
1004 for (i = d->granted_count; i < d->request_count; i++) {
1005 buf = savage_freelist_get(dev);
1006 if (!buf)
1007 return -EAGAIN;
1008
1009 buf->file_priv = file_priv;
1010
1011 if (DRM_COPY_TO_USER(&d->request_indices[i],
1012 &buf->idx, sizeof(buf->idx)))
1013 return -EFAULT;
1014 if (DRM_COPY_TO_USER(&d->request_sizes[i],
1015 &buf->total, sizeof(buf->total)))
1016 return -EFAULT;
1017
1018 d->granted_count++;
1019 }
1020 return 0;
1021}
1022
1023int savage_bci_buffers(struct drm_device *dev, void *data, struct drm_file *file_priv)
1024{
1025 struct drm_device_dma *dma = dev->dma;
1026 struct drm_dma *d = data;
1027 int ret = 0;
1028
1029 LOCK_TEST_WITH_RETURN(dev, file_priv);
1030
1031 /* Please don't send us buffers.
1032 */
1033 if (d->send_count != 0) {
1034 DRM_ERROR("Process %d trying to send %d buffers via drmDMA\n",
1035 DRM_CURRENTPID, d->send_count);
1036 return -EINVAL;
1037 }
1038
1039 /* We'll send you buffers.
1040 */
1041 if (d->request_count < 0 || d->request_count > dma->buf_count) {
1042 DRM_ERROR("Process %d trying to get %d buffers (of %d max)\n",
1043 DRM_CURRENTPID, d->request_count, dma->buf_count);
1044 return -EINVAL;
1045 }
1046
1047 d->granted_count = 0;
1048
1049 if (d->request_count) {
1050 ret = savage_bci_get_buffers(dev, file_priv, d);
1051 }
1052
1053 return ret;
1054}
1055
1056void savage_reclaim_buffers(struct drm_device *dev, struct drm_file *file_priv)
1057{
1058 struct drm_device_dma *dma = dev->dma;
1059 drm_savage_private_t *dev_priv = dev->dev_private;
1060 int i;
1061
1062 if (!dma)
1063 return;
1064 if (!dev_priv)
1065 return;
1066 if (!dma->buflist)
1067 return;
1068
1069 /*i830_flush_queue(dev); */
1070
1071 for (i = 0; i < dma->buf_count; i++) {
1072 struct drm_buf *buf = dma->buflist[i];
1073 drm_savage_buf_priv_t *buf_priv = buf->dev_private;
1074
1075 if (buf->file_priv == file_priv && buf_priv &&
1076 buf_priv->next == NULL && buf_priv->prev == NULL) {
1077 uint16_t event;
1078 DRM_DEBUG("reclaimed from client\n");
1079 event = savage_bci_emit_event(dev_priv, SAVAGE_WAIT_3D);
1080 SET_AGE(&buf_priv->age, event, dev_priv->event_wrap);
1081 savage_freelist_put(dev, buf);
1082 }
1083 }
1084
1085 drm_core_reclaim_buffers(dev, file_priv);
1086}
1087
1088struct drm_ioctl_desc savage_ioctls[] = {
1089 DRM_IOCTL_DEF(DRM_SAVAGE_BCI_INIT, savage_bci_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
1090 DRM_IOCTL_DEF(DRM_SAVAGE_BCI_CMDBUF, savage_bci_cmdbuf, DRM_AUTH),
1091 DRM_IOCTL_DEF(DRM_SAVAGE_BCI_EVENT_EMIT, savage_bci_event_emit, DRM_AUTH),
1092 DRM_IOCTL_DEF(DRM_SAVAGE_BCI_EVENT_WAIT, savage_bci_event_wait, DRM_AUTH),
1093};
1094
1095int savage_max_ioctl = DRM_ARRAY_SIZE(savage_ioctls);
diff --git a/drivers/char/drm/savage_drm.h b/drivers/char/drm/savage_drm.h
deleted file mode 100644
index 8a576ef01821..000000000000
--- a/drivers/char/drm/savage_drm.h
+++ /dev/null
@@ -1,210 +0,0 @@
1/* savage_drm.h -- Public header for the savage driver
2 *
3 * Copyright 2004 Felix Kuehling
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sub license,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial portions
15 * of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 * NON-INFRINGEMENT. IN NO EVENT SHALL FELIX KUEHLING BE LIABLE FOR
21 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
22 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26#ifndef __SAVAGE_DRM_H__
27#define __SAVAGE_DRM_H__
28
29#ifndef __SAVAGE_SAREA_DEFINES__
30#define __SAVAGE_SAREA_DEFINES__
31
32/* 2 heaps (1 for card, 1 for agp), each divided into upto 128
33 * regions, subject to a minimum region size of (1<<16) == 64k.
34 *
35 * Clients may subdivide regions internally, but when sharing between
36 * clients, the region size is the minimum granularity.
37 */
38
39#define SAVAGE_CARD_HEAP 0
40#define SAVAGE_AGP_HEAP 1
41#define SAVAGE_NR_TEX_HEAPS 2
42#define SAVAGE_NR_TEX_REGIONS 16
43#define SAVAGE_LOG_MIN_TEX_REGION_SIZE 16
44
45#endif /* __SAVAGE_SAREA_DEFINES__ */
46
47typedef struct _drm_savage_sarea {
48 /* LRU lists for texture memory in agp space and on the card.
49 */
50 struct drm_tex_region texList[SAVAGE_NR_TEX_HEAPS][SAVAGE_NR_TEX_REGIONS +
51 1];
52 unsigned int texAge[SAVAGE_NR_TEX_HEAPS];
53
54 /* Mechanism to validate card state.
55 */
56 int ctxOwner;
57} drm_savage_sarea_t, *drm_savage_sarea_ptr;
58
59/* Savage-specific ioctls
60 */
61#define DRM_SAVAGE_BCI_INIT 0x00
62#define DRM_SAVAGE_BCI_CMDBUF 0x01
63#define DRM_SAVAGE_BCI_EVENT_EMIT 0x02
64#define DRM_SAVAGE_BCI_EVENT_WAIT 0x03
65
66#define DRM_IOCTL_SAVAGE_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_SAVAGE_BCI_INIT, drm_savage_init_t)
67#define DRM_IOCTL_SAVAGE_CMDBUF DRM_IOW( DRM_COMMAND_BASE + DRM_SAVAGE_BCI_CMDBUF, drm_savage_cmdbuf_t)
68#define DRM_IOCTL_SAVAGE_EVENT_EMIT DRM_IOWR(DRM_COMMAND_BASE + DRM_SAVAGE_BCI_EVENT_EMIT, drm_savage_event_emit_t)
69#define DRM_IOCTL_SAVAGE_EVENT_WAIT DRM_IOW( DRM_COMMAND_BASE + DRM_SAVAGE_BCI_EVENT_WAIT, drm_savage_event_wait_t)
70
71#define SAVAGE_DMA_PCI 1
72#define SAVAGE_DMA_AGP 3
73typedef struct drm_savage_init {
74 enum {
75 SAVAGE_INIT_BCI = 1,
76 SAVAGE_CLEANUP_BCI = 2
77 } func;
78 unsigned int sarea_priv_offset;
79
80 /* some parameters */
81 unsigned int cob_size;
82 unsigned int bci_threshold_lo, bci_threshold_hi;
83 unsigned int dma_type;
84
85 /* frame buffer layout */
86 unsigned int fb_bpp;
87 unsigned int front_offset, front_pitch;
88 unsigned int back_offset, back_pitch;
89 unsigned int depth_bpp;
90 unsigned int depth_offset, depth_pitch;
91
92 /* local textures */
93 unsigned int texture_offset;
94 unsigned int texture_size;
95
96 /* physical locations of non-permanent maps */
97 unsigned long status_offset;
98 unsigned long buffers_offset;
99 unsigned long agp_textures_offset;
100 unsigned long cmd_dma_offset;
101} drm_savage_init_t;
102
103typedef union drm_savage_cmd_header drm_savage_cmd_header_t;
104typedef struct drm_savage_cmdbuf {
105 /* command buffer in client's address space */
106 drm_savage_cmd_header_t __user *cmd_addr;
107 unsigned int size; /* size of the command buffer in 64bit units */
108
109 unsigned int dma_idx; /* DMA buffer index to use */
110 int discard; /* discard DMA buffer when done */
111 /* vertex buffer in client's address space */
112 unsigned int __user *vb_addr;
113 unsigned int vb_size; /* size of client vertex buffer in bytes */
114 unsigned int vb_stride; /* stride of vertices in 32bit words */
115 /* boxes in client's address space */
116 struct drm_clip_rect __user *box_addr;
117 unsigned int nbox; /* number of clipping boxes */
118} drm_savage_cmdbuf_t;
119
120#define SAVAGE_WAIT_2D 0x1 /* wait for 2D idle before updating event tag */
121#define SAVAGE_WAIT_3D 0x2 /* wait for 3D idle before updating event tag */
122#define SAVAGE_WAIT_IRQ 0x4 /* emit or wait for IRQ, not implemented yet */
123typedef struct drm_savage_event {
124 unsigned int count;
125 unsigned int flags;
126} drm_savage_event_emit_t, drm_savage_event_wait_t;
127
128/* Commands for the cmdbuf ioctl
129 */
130#define SAVAGE_CMD_STATE 0 /* a range of state registers */
131#define SAVAGE_CMD_DMA_PRIM 1 /* vertices from DMA buffer */
132#define SAVAGE_CMD_VB_PRIM 2 /* vertices from client vertex buffer */
133#define SAVAGE_CMD_DMA_IDX 3 /* indexed vertices from DMA buffer */
134#define SAVAGE_CMD_VB_IDX 4 /* indexed vertices client vertex buffer */
135#define SAVAGE_CMD_CLEAR 5 /* clear buffers */
136#define SAVAGE_CMD_SWAP 6 /* swap buffers */
137
138/* Primitive types
139*/
140#define SAVAGE_PRIM_TRILIST 0 /* triangle list */
141#define SAVAGE_PRIM_TRISTRIP 1 /* triangle strip */
142#define SAVAGE_PRIM_TRIFAN 2 /* triangle fan */
143#define SAVAGE_PRIM_TRILIST_201 3 /* reorder verts for correct flat
144 * shading on s3d */
145
146/* Skip flags (vertex format)
147 */
148#define SAVAGE_SKIP_Z 0x01
149#define SAVAGE_SKIP_W 0x02
150#define SAVAGE_SKIP_C0 0x04
151#define SAVAGE_SKIP_C1 0x08
152#define SAVAGE_SKIP_S0 0x10
153#define SAVAGE_SKIP_T0 0x20
154#define SAVAGE_SKIP_ST0 0x30
155#define SAVAGE_SKIP_S1 0x40
156#define SAVAGE_SKIP_T1 0x80
157#define SAVAGE_SKIP_ST1 0xc0
158#define SAVAGE_SKIP_ALL_S3D 0x3f
159#define SAVAGE_SKIP_ALL_S4 0xff
160
161/* Buffer names for clear command
162 */
163#define SAVAGE_FRONT 0x1
164#define SAVAGE_BACK 0x2
165#define SAVAGE_DEPTH 0x4
166
167/* 64-bit command header
168 */
169union drm_savage_cmd_header {
170 struct {
171 unsigned char cmd; /* command */
172 unsigned char pad0;
173 unsigned short pad1;
174 unsigned short pad2;
175 unsigned short pad3;
176 } cmd; /* generic */
177 struct {
178 unsigned char cmd;
179 unsigned char global; /* need idle engine? */
180 unsigned short count; /* number of consecutive registers */
181 unsigned short start; /* first register */
182 unsigned short pad3;
183 } state; /* SAVAGE_CMD_STATE */
184 struct {
185 unsigned char cmd;
186 unsigned char prim; /* primitive type */
187 unsigned short skip; /* vertex format (skip flags) */
188 unsigned short count; /* number of vertices */
189 unsigned short start; /* first vertex in DMA/vertex buffer */
190 } prim; /* SAVAGE_CMD_DMA_PRIM, SAVAGE_CMD_VB_PRIM */
191 struct {
192 unsigned char cmd;
193 unsigned char prim;
194 unsigned short skip;
195 unsigned short count; /* number of indices that follow */
196 unsigned short pad3;
197 } idx; /* SAVAGE_CMD_DMA_IDX, SAVAGE_CMD_VB_IDX */
198 struct {
199 unsigned char cmd;
200 unsigned char pad0;
201 unsigned short pad1;
202 unsigned int flags;
203 } clear0; /* SAVAGE_CMD_CLEAR */
204 struct {
205 unsigned int mask;
206 unsigned int value;
207 } clear1; /* SAVAGE_CMD_CLEAR data */
208};
209
210#endif
diff --git a/drivers/char/drm/savage_drv.c b/drivers/char/drm/savage_drv.c
deleted file mode 100644
index eee52aa92a7c..000000000000
--- a/drivers/char/drm/savage_drv.c
+++ /dev/null
@@ -1,88 +0,0 @@
1/* savage_drv.c -- Savage driver for Linux
2 *
3 * Copyright 2004 Felix Kuehling
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sub license,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial portions
15 * of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 * NON-INFRINGEMENT. IN NO EVENT SHALL FELIX KUEHLING BE LIABLE FOR
21 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
22 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26#include "drmP.h"
27#include "savage_drm.h"
28#include "savage_drv.h"
29
30#include "drm_pciids.h"
31
32static struct pci_device_id pciidlist[] = {
33 savage_PCI_IDS
34};
35
36static struct drm_driver driver = {
37 .driver_features =
38 DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_DMA | DRIVER_PCI_DMA,
39 .dev_priv_size = sizeof(drm_savage_buf_priv_t),
40 .load = savage_driver_load,
41 .firstopen = savage_driver_firstopen,
42 .lastclose = savage_driver_lastclose,
43 .unload = savage_driver_unload,
44 .reclaim_buffers = savage_reclaim_buffers,
45 .get_map_ofs = drm_core_get_map_ofs,
46 .get_reg_ofs = drm_core_get_reg_ofs,
47 .ioctls = savage_ioctls,
48 .dma_ioctl = savage_bci_buffers,
49 .fops = {
50 .owner = THIS_MODULE,
51 .open = drm_open,
52 .release = drm_release,
53 .ioctl = drm_ioctl,
54 .mmap = drm_mmap,
55 .poll = drm_poll,
56 .fasync = drm_fasync,
57 },
58
59 .pci_driver = {
60 .name = DRIVER_NAME,
61 .id_table = pciidlist,
62 },
63
64 .name = DRIVER_NAME,
65 .desc = DRIVER_DESC,
66 .date = DRIVER_DATE,
67 .major = DRIVER_MAJOR,
68 .minor = DRIVER_MINOR,
69 .patchlevel = DRIVER_PATCHLEVEL,
70};
71
72static int __init savage_init(void)
73{
74 driver.num_ioctls = savage_max_ioctl;
75 return drm_init(&driver);
76}
77
78static void __exit savage_exit(void)
79{
80 drm_exit(&driver);
81}
82
83module_init(savage_init);
84module_exit(savage_exit);
85
86MODULE_AUTHOR(DRIVER_AUTHOR);
87MODULE_DESCRIPTION(DRIVER_DESC);
88MODULE_LICENSE("GPL and additional rights");
diff --git a/drivers/char/drm/savage_drv.h b/drivers/char/drm/savage_drv.h
deleted file mode 100644
index df2aac6636f7..000000000000
--- a/drivers/char/drm/savage_drv.h
+++ /dev/null
@@ -1,575 +0,0 @@
1/* savage_drv.h -- Private header for the savage driver */
2/*
3 * Copyright 2004 Felix Kuehling
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sub license,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial portions
15 * of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 * NON-INFRINGEMENT. IN NO EVENT SHALL FELIX KUEHLING BE LIABLE FOR
21 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
22 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 */
25
26#ifndef __SAVAGE_DRV_H__
27#define __SAVAGE_DRV_H__
28
29#define DRIVER_AUTHOR "Felix Kuehling"
30
31#define DRIVER_NAME "savage"
32#define DRIVER_DESC "Savage3D/MX/IX, Savage4, SuperSavage, Twister, ProSavage[DDR]"
33#define DRIVER_DATE "20050313"
34
35#define DRIVER_MAJOR 2
36#define DRIVER_MINOR 4
37#define DRIVER_PATCHLEVEL 1
38/* Interface history:
39 *
40 * 1.x The DRM driver from the VIA/S3 code drop, basically a dummy
41 * 2.0 The first real DRM
42 * 2.1 Scissors registers managed by the DRM, 3D operations clipped by
43 * cliprects of the cmdbuf ioctl
44 * 2.2 Implemented SAVAGE_CMD_DMA_IDX and SAVAGE_CMD_VB_IDX
45 * 2.3 Event counters used by BCI_EVENT_EMIT/WAIT ioctls are now 32 bits
46 * wide and thus very long lived (unlikely to ever wrap). The size
47 * in the struct was 32 bits before, but only 16 bits were used
48 * 2.4 Implemented command DMA. Now drm_savage_init_t.cmd_dma_offset is
49 * actually used
50 */
51
52typedef struct drm_savage_age {
53 uint16_t event;
54 unsigned int wrap;
55} drm_savage_age_t;
56
57typedef struct drm_savage_buf_priv {
58 struct drm_savage_buf_priv *next;
59 struct drm_savage_buf_priv *prev;
60 drm_savage_age_t age;
61 struct drm_buf *buf;
62} drm_savage_buf_priv_t;
63
64typedef struct drm_savage_dma_page {
65 drm_savage_age_t age;
66 unsigned int used, flushed;
67} drm_savage_dma_page_t;
68#define SAVAGE_DMA_PAGE_SIZE 1024 /* in dwords */
69/* Fake DMA buffer size in bytes. 4 pages. Allows a maximum command
70 * size of 16kbytes or 4k entries. Minimum requirement would be
71 * 10kbytes for 255 40-byte vertices in one drawing command. */
72#define SAVAGE_FAKE_DMA_SIZE (SAVAGE_DMA_PAGE_SIZE*4*4)
73
74/* interesting bits of hardware state that are saved in dev_priv */
75typedef union {
76 struct drm_savage_common_state {
77 uint32_t vbaddr;
78 } common;
79 struct {
80 unsigned char pad[sizeof(struct drm_savage_common_state)];
81 uint32_t texctrl, texaddr;
82 uint32_t scstart, new_scstart;
83 uint32_t scend, new_scend;
84 } s3d;
85 struct {
86 unsigned char pad[sizeof(struct drm_savage_common_state)];
87 uint32_t texdescr, texaddr0, texaddr1;
88 uint32_t drawctrl0, new_drawctrl0;
89 uint32_t drawctrl1, new_drawctrl1;
90 } s4;
91} drm_savage_state_t;
92
93/* these chip tags should match the ones in the 2D driver in savage_regs.h. */
94enum savage_family {
95 S3_UNKNOWN = 0,
96 S3_SAVAGE3D,
97 S3_SAVAGE_MX,
98 S3_SAVAGE4,
99 S3_PROSAVAGE,
100 S3_TWISTER,
101 S3_PROSAVAGEDDR,
102 S3_SUPERSAVAGE,
103 S3_SAVAGE2000,
104 S3_LAST
105};
106
107extern struct drm_ioctl_desc savage_ioctls[];
108extern int savage_max_ioctl;
109
110#define S3_SAVAGE3D_SERIES(chip) ((chip>=S3_SAVAGE3D) && (chip<=S3_SAVAGE_MX))
111
112#define S3_SAVAGE4_SERIES(chip) ((chip==S3_SAVAGE4) \
113 || (chip==S3_PROSAVAGE) \
114 || (chip==S3_TWISTER) \
115 || (chip==S3_PROSAVAGEDDR))
116
117#define S3_SAVAGE_MOBILE_SERIES(chip) ((chip==S3_SAVAGE_MX) || (chip==S3_SUPERSAVAGE))
118
119#define S3_SAVAGE_SERIES(chip) ((chip>=S3_SAVAGE3D) && (chip<=S3_SAVAGE2000))
120
121#define S3_MOBILE_TWISTER_SERIES(chip) ((chip==S3_TWISTER) \
122 ||(chip==S3_PROSAVAGEDDR))
123
124/* flags */
125#define SAVAGE_IS_AGP 1
126
127typedef struct drm_savage_private {
128 drm_savage_sarea_t *sarea_priv;
129
130 drm_savage_buf_priv_t head, tail;
131
132 /* who am I? */
133 enum savage_family chipset;
134
135 unsigned int cob_size;
136 unsigned int bci_threshold_lo, bci_threshold_hi;
137 unsigned int dma_type;
138
139 /* frame buffer layout */
140 unsigned int fb_bpp;
141 unsigned int front_offset, front_pitch;
142 unsigned int back_offset, back_pitch;
143 unsigned int depth_bpp;
144 unsigned int depth_offset, depth_pitch;
145
146 /* bitmap descriptors for swap and clear */
147 unsigned int front_bd, back_bd, depth_bd;
148
149 /* local textures */
150 unsigned int texture_offset;
151 unsigned int texture_size;
152
153 /* memory regions in physical memory */
154 drm_local_map_t *sarea;
155 drm_local_map_t *mmio;
156 drm_local_map_t *fb;
157 drm_local_map_t *aperture;
158 drm_local_map_t *status;
159 drm_local_map_t *agp_textures;
160 drm_local_map_t *cmd_dma;
161 drm_local_map_t fake_dma;
162
163 struct {
164 int handle;
165 unsigned long base, size;
166 } mtrr[3];
167
168 /* BCI and status-related stuff */
169 volatile uint32_t *status_ptr, *bci_ptr;
170 uint32_t status_used_mask;
171 uint16_t event_counter;
172 unsigned int event_wrap;
173
174 /* Savage4 command DMA */
175 drm_savage_dma_page_t *dma_pages;
176 unsigned int nr_dma_pages, first_dma_page, current_dma_page;
177 drm_savage_age_t last_dma_age;
178
179 /* saved hw state for global/local check on S3D */
180 uint32_t hw_draw_ctrl, hw_zbuf_ctrl;
181 /* and for scissors (global, so don't emit if not changed) */
182 uint32_t hw_scissors_start, hw_scissors_end;
183
184 drm_savage_state_t state;
185
186 /* after emitting a wait cmd Savage3D needs 63 nops before next DMA */
187 unsigned int waiting;
188
189 /* config/hardware-dependent function pointers */
190 int (*wait_fifo) (struct drm_savage_private * dev_priv, unsigned int n);
191 int (*wait_evnt) (struct drm_savage_private * dev_priv, uint16_t e);
192 /* Err, there is a macro wait_event in include/linux/wait.h.
193 * Avoid unwanted macro expansion. */
194 void (*emit_clip_rect) (struct drm_savage_private * dev_priv,
195 const struct drm_clip_rect * pbox);
196 void (*dma_flush) (struct drm_savage_private * dev_priv);
197} drm_savage_private_t;
198
199/* ioctls */
200extern int savage_bci_cmdbuf(struct drm_device *dev, void *data, struct drm_file *file_priv);
201extern int savage_bci_buffers(struct drm_device *dev, void *data, struct drm_file *file_priv);
202
203/* BCI functions */
204extern uint16_t savage_bci_emit_event(drm_savage_private_t * dev_priv,
205 unsigned int flags);
206extern void savage_freelist_put(struct drm_device * dev, struct drm_buf * buf);
207extern void savage_dma_reset(drm_savage_private_t * dev_priv);
208extern void savage_dma_wait(drm_savage_private_t * dev_priv, unsigned int page);
209extern uint32_t *savage_dma_alloc(drm_savage_private_t * dev_priv,
210 unsigned int n);
211extern int savage_driver_load(struct drm_device *dev, unsigned long chipset);
212extern int savage_driver_firstopen(struct drm_device *dev);
213extern void savage_driver_lastclose(struct drm_device *dev);
214extern int savage_driver_unload(struct drm_device *dev);
215extern void savage_reclaim_buffers(struct drm_device *dev,
216 struct drm_file *file_priv);
217
218/* state functions */
219extern void savage_emit_clip_rect_s3d(drm_savage_private_t * dev_priv,
220 const struct drm_clip_rect * pbox);
221extern void savage_emit_clip_rect_s4(drm_savage_private_t * dev_priv,
222 const struct drm_clip_rect * pbox);
223
224#define SAVAGE_FB_SIZE_S3 0x01000000 /* 16MB */
225#define SAVAGE_FB_SIZE_S4 0x02000000 /* 32MB */
226#define SAVAGE_MMIO_SIZE 0x00080000 /* 512kB */
227#define SAVAGE_APERTURE_OFFSET 0x02000000 /* 32MB */
228#define SAVAGE_APERTURE_SIZE 0x05000000 /* 5 tiled surfaces, 16MB each */
229
230#define SAVAGE_BCI_OFFSET 0x00010000 /* offset of the BCI region
231 * inside the MMIO region */
232#define SAVAGE_BCI_FIFO_SIZE 32 /* number of entries in on-chip
233 * BCI FIFO */
234
235/*
236 * MMIO registers
237 */
238#define SAVAGE_STATUS_WORD0 0x48C00
239#define SAVAGE_STATUS_WORD1 0x48C04
240#define SAVAGE_ALT_STATUS_WORD0 0x48C60
241
242#define SAVAGE_FIFO_USED_MASK_S3D 0x0001ffff
243#define SAVAGE_FIFO_USED_MASK_S4 0x001fffff
244
245/* Copied from savage_bci.h in the 2D driver with some renaming. */
246
247/* Bitmap descriptors */
248#define SAVAGE_BD_STRIDE_SHIFT 0
249#define SAVAGE_BD_BPP_SHIFT 16
250#define SAVAGE_BD_TILE_SHIFT 24
251#define SAVAGE_BD_BW_DISABLE (1<<28)
252/* common: */
253#define SAVAGE_BD_TILE_LINEAR 0
254/* savage4, MX, IX, 3D */
255#define SAVAGE_BD_TILE_16BPP 2
256#define SAVAGE_BD_TILE_32BPP 3
257/* twister, prosavage, DDR, supersavage, 2000 */
258#define SAVAGE_BD_TILE_DEST 1
259#define SAVAGE_BD_TILE_TEXTURE 2
260/* GBD - BCI enable */
261/* savage4, MX, IX, 3D */
262#define SAVAGE_GBD_BCI_ENABLE 8
263/* twister, prosavage, DDR, supersavage, 2000 */
264#define SAVAGE_GBD_BCI_ENABLE_TWISTER 0
265
266#define SAVAGE_GBD_BIG_ENDIAN 4
267#define SAVAGE_GBD_LITTLE_ENDIAN 0
268#define SAVAGE_GBD_64 1
269
270/* Global Bitmap Descriptor */
271#define SAVAGE_BCI_GLB_BD_LOW 0x8168
272#define SAVAGE_BCI_GLB_BD_HIGH 0x816C
273
274/*
275 * BCI registers
276 */
277/* Savage4/Twister/ProSavage 3D registers */
278#define SAVAGE_DRAWLOCALCTRL_S4 0x1e
279#define SAVAGE_TEXPALADDR_S4 0x1f
280#define SAVAGE_TEXCTRL0_S4 0x20
281#define SAVAGE_TEXCTRL1_S4 0x21
282#define SAVAGE_TEXADDR0_S4 0x22
283#define SAVAGE_TEXADDR1_S4 0x23
284#define SAVAGE_TEXBLEND0_S4 0x24
285#define SAVAGE_TEXBLEND1_S4 0x25
286#define SAVAGE_TEXXPRCLR_S4 0x26 /* never used */
287#define SAVAGE_TEXDESCR_S4 0x27
288#define SAVAGE_FOGTABLE_S4 0x28
289#define SAVAGE_FOGCTRL_S4 0x30
290#define SAVAGE_STENCILCTRL_S4 0x31
291#define SAVAGE_ZBUFCTRL_S4 0x32
292#define SAVAGE_ZBUFOFF_S4 0x33
293#define SAVAGE_DESTCTRL_S4 0x34
294#define SAVAGE_DRAWCTRL0_S4 0x35
295#define SAVAGE_DRAWCTRL1_S4 0x36
296#define SAVAGE_ZWATERMARK_S4 0x37
297#define SAVAGE_DESTTEXRWWATERMARK_S4 0x38
298#define SAVAGE_TEXBLENDCOLOR_S4 0x39
299/* Savage3D/MX/IX 3D registers */
300#define SAVAGE_TEXPALADDR_S3D 0x18
301#define SAVAGE_TEXXPRCLR_S3D 0x19 /* never used */
302#define SAVAGE_TEXADDR_S3D 0x1A
303#define SAVAGE_TEXDESCR_S3D 0x1B
304#define SAVAGE_TEXCTRL_S3D 0x1C
305#define SAVAGE_FOGTABLE_S3D 0x20
306#define SAVAGE_FOGCTRL_S3D 0x30
307#define SAVAGE_DRAWCTRL_S3D 0x31
308#define SAVAGE_ZBUFCTRL_S3D 0x32
309#define SAVAGE_ZBUFOFF_S3D 0x33
310#define SAVAGE_DESTCTRL_S3D 0x34
311#define SAVAGE_SCSTART_S3D 0x35
312#define SAVAGE_SCEND_S3D 0x36
313#define SAVAGE_ZWATERMARK_S3D 0x37
314#define SAVAGE_DESTTEXRWWATERMARK_S3D 0x38
315/* common stuff */
316#define SAVAGE_VERTBUFADDR 0x3e
317#define SAVAGE_BITPLANEWTMASK 0xd7
318#define SAVAGE_DMABUFADDR 0x51
319
320/* texture enable bits (needed for tex addr checking) */
321#define SAVAGE_TEXCTRL_TEXEN_MASK 0x00010000 /* S3D */
322#define SAVAGE_TEXDESCR_TEX0EN_MASK 0x02000000 /* S4 */
323#define SAVAGE_TEXDESCR_TEX1EN_MASK 0x04000000 /* S4 */
324
325/* Global fields in Savage4/Twister/ProSavage 3D registers:
326 *
327 * All texture registers and DrawLocalCtrl are local. All other
328 * registers are global. */
329
330/* Global fields in Savage3D/MX/IX 3D registers:
331 *
332 * All texture registers are local. DrawCtrl and ZBufCtrl are
333 * partially local. All other registers are global.
334 *
335 * DrawCtrl global fields: cullMode, alphaTestCmpFunc, alphaTestEn, alphaRefVal
336 * ZBufCtrl global fields: zCmpFunc, zBufEn
337 */
338#define SAVAGE_DRAWCTRL_S3D_GLOBAL 0x03f3c00c
339#define SAVAGE_ZBUFCTRL_S3D_GLOBAL 0x00000027
340
341/* Masks for scissor bits (drawCtrl[01] on s4, scissorStart/End on s3d)
342 */
343#define SAVAGE_SCISSOR_MASK_S4 0x00fff7ff
344#define SAVAGE_SCISSOR_MASK_S3D 0x07ff07ff
345
346/*
347 * BCI commands
348 */
349#define BCI_CMD_NOP 0x40000000
350#define BCI_CMD_RECT 0x48000000
351#define BCI_CMD_RECT_XP 0x01000000
352#define BCI_CMD_RECT_YP 0x02000000
353#define BCI_CMD_SCANLINE 0x50000000
354#define BCI_CMD_LINE 0x5C000000
355#define BCI_CMD_LINE_LAST_PIXEL 0x58000000
356#define BCI_CMD_BYTE_TEXT 0x63000000
357#define BCI_CMD_NT_BYTE_TEXT 0x67000000
358#define BCI_CMD_BIT_TEXT 0x6C000000
359#define BCI_CMD_GET_ROP(cmd) (((cmd) >> 16) & 0xFF)
360#define BCI_CMD_SET_ROP(cmd, rop) ((cmd) |= ((rop & 0xFF) << 16))
361#define BCI_CMD_SEND_COLOR 0x00008000
362
363#define BCI_CMD_CLIP_NONE 0x00000000
364#define BCI_CMD_CLIP_CURRENT 0x00002000
365#define BCI_CMD_CLIP_LR 0x00004000
366#define BCI_CMD_CLIP_NEW 0x00006000
367
368#define BCI_CMD_DEST_GBD 0x00000000
369#define BCI_CMD_DEST_PBD 0x00000800
370#define BCI_CMD_DEST_PBD_NEW 0x00000C00
371#define BCI_CMD_DEST_SBD 0x00001000
372#define BCI_CMD_DEST_SBD_NEW 0x00001400
373
374#define BCI_CMD_SRC_TRANSPARENT 0x00000200
375#define BCI_CMD_SRC_SOLID 0x00000000
376#define BCI_CMD_SRC_GBD 0x00000020
377#define BCI_CMD_SRC_COLOR 0x00000040
378#define BCI_CMD_SRC_MONO 0x00000060
379#define BCI_CMD_SRC_PBD_COLOR 0x00000080
380#define BCI_CMD_SRC_PBD_MONO 0x000000A0
381#define BCI_CMD_SRC_PBD_COLOR_NEW 0x000000C0
382#define BCI_CMD_SRC_PBD_MONO_NEW 0x000000E0
383#define BCI_CMD_SRC_SBD_COLOR 0x00000100
384#define BCI_CMD_SRC_SBD_MONO 0x00000120
385#define BCI_CMD_SRC_SBD_COLOR_NEW 0x00000140
386#define BCI_CMD_SRC_SBD_MONO_NEW 0x00000160
387
388#define BCI_CMD_PAT_TRANSPARENT 0x00000010
389#define BCI_CMD_PAT_NONE 0x00000000
390#define BCI_CMD_PAT_COLOR 0x00000002
391#define BCI_CMD_PAT_MONO 0x00000003
392#define BCI_CMD_PAT_PBD_COLOR 0x00000004
393#define BCI_CMD_PAT_PBD_MONO 0x00000005
394#define BCI_CMD_PAT_PBD_COLOR_NEW 0x00000006
395#define BCI_CMD_PAT_PBD_MONO_NEW 0x00000007
396#define BCI_CMD_PAT_SBD_COLOR 0x00000008
397#define BCI_CMD_PAT_SBD_MONO 0x00000009
398#define BCI_CMD_PAT_SBD_COLOR_NEW 0x0000000A
399#define BCI_CMD_PAT_SBD_MONO_NEW 0x0000000B
400
401#define BCI_BD_BW_DISABLE 0x10000000
402#define BCI_BD_TILE_MASK 0x03000000
403#define BCI_BD_TILE_NONE 0x00000000
404#define BCI_BD_TILE_16 0x02000000
405#define BCI_BD_TILE_32 0x03000000
406#define BCI_BD_GET_BPP(bd) (((bd) >> 16) & 0xFF)
407#define BCI_BD_SET_BPP(bd, bpp) ((bd) |= (((bpp) & 0xFF) << 16))
408#define BCI_BD_GET_STRIDE(bd) ((bd) & 0xFFFF)
409#define BCI_BD_SET_STRIDE(bd, st) ((bd) |= ((st) & 0xFFFF))
410
411#define BCI_CMD_SET_REGISTER 0x96000000
412
413#define BCI_CMD_WAIT 0xC0000000
414#define BCI_CMD_WAIT_3D 0x00010000
415#define BCI_CMD_WAIT_2D 0x00020000
416
417#define BCI_CMD_UPDATE_EVENT_TAG 0x98000000
418
419#define BCI_CMD_DRAW_PRIM 0x80000000
420#define BCI_CMD_DRAW_INDEXED_PRIM 0x88000000
421#define BCI_CMD_DRAW_CONT 0x01000000
422#define BCI_CMD_DRAW_TRILIST 0x00000000
423#define BCI_CMD_DRAW_TRISTRIP 0x02000000
424#define BCI_CMD_DRAW_TRIFAN 0x04000000
425#define BCI_CMD_DRAW_SKIPFLAGS 0x000000ff
426#define BCI_CMD_DRAW_NO_Z 0x00000001
427#define BCI_CMD_DRAW_NO_W 0x00000002
428#define BCI_CMD_DRAW_NO_CD 0x00000004
429#define BCI_CMD_DRAW_NO_CS 0x00000008
430#define BCI_CMD_DRAW_NO_U0 0x00000010
431#define BCI_CMD_DRAW_NO_V0 0x00000020
432#define BCI_CMD_DRAW_NO_UV0 0x00000030
433#define BCI_CMD_DRAW_NO_U1 0x00000040
434#define BCI_CMD_DRAW_NO_V1 0x00000080
435#define BCI_CMD_DRAW_NO_UV1 0x000000c0
436
437#define BCI_CMD_DMA 0xa8000000
438
439#define BCI_W_H(w, h) ((((h) << 16) | (w)) & 0x0FFF0FFF)
440#define BCI_X_Y(x, y) ((((y) << 16) | (x)) & 0x0FFF0FFF)
441#define BCI_X_W(x, y) ((((w) << 16) | (x)) & 0x0FFF0FFF)
442#define BCI_CLIP_LR(l, r) ((((r) << 16) | (l)) & 0x0FFF0FFF)
443#define BCI_CLIP_TL(t, l) ((((t) << 16) | (l)) & 0x0FFF0FFF)
444#define BCI_CLIP_BR(b, r) ((((b) << 16) | (r)) & 0x0FFF0FFF)
445
446#define BCI_LINE_X_Y(x, y) (((y) << 16) | ((x) & 0xFFFF))
447#define BCI_LINE_STEPS(diag, axi) (((axi) << 16) | ((diag) & 0xFFFF))
448#define BCI_LINE_MISC(maj, ym, xp, yp, err) \
449 (((maj) & 0x1FFF) | \
450 ((ym) ? 1<<13 : 0) | \
451 ((xp) ? 1<<14 : 0) | \
452 ((yp) ? 1<<15 : 0) | \
453 ((err) << 16))
454
455/*
456 * common commands
457 */
458#define BCI_SET_REGISTERS( first, n ) \
459 BCI_WRITE(BCI_CMD_SET_REGISTER | \
460 ((uint32_t)(n) & 0xff) << 16 | \
461 ((uint32_t)(first) & 0xffff))
462#define DMA_SET_REGISTERS( first, n ) \
463 DMA_WRITE(BCI_CMD_SET_REGISTER | \
464 ((uint32_t)(n) & 0xff) << 16 | \
465 ((uint32_t)(first) & 0xffff))
466
467#define BCI_DRAW_PRIMITIVE(n, type, skip) \
468 BCI_WRITE(BCI_CMD_DRAW_PRIM | (type) | (skip) | \
469 ((n) << 16))
470#define DMA_DRAW_PRIMITIVE(n, type, skip) \
471 DMA_WRITE(BCI_CMD_DRAW_PRIM | (type) | (skip) | \
472 ((n) << 16))
473
474#define BCI_DRAW_INDICES_S3D(n, type, i0) \
475 BCI_WRITE(BCI_CMD_DRAW_INDEXED_PRIM | (type) | \
476 ((n) << 16) | (i0))
477
478#define BCI_DRAW_INDICES_S4(n, type, skip) \
479 BCI_WRITE(BCI_CMD_DRAW_INDEXED_PRIM | (type) | \
480 (skip) | ((n) << 16))
481
482#define BCI_DMA(n) \
483 BCI_WRITE(BCI_CMD_DMA | (((n) >> 1) - 1))
484
485/*
486 * access to MMIO
487 */
488#define SAVAGE_READ(reg) DRM_READ32( dev_priv->mmio, (reg) )
489#define SAVAGE_WRITE(reg) DRM_WRITE32( dev_priv->mmio, (reg) )
490
491/*
492 * access to the burst command interface (BCI)
493 */
494#define SAVAGE_BCI_DEBUG 1
495
496#define BCI_LOCALS volatile uint32_t *bci_ptr;
497
498#define BEGIN_BCI( n ) do { \
499 dev_priv->wait_fifo(dev_priv, (n)); \
500 bci_ptr = dev_priv->bci_ptr; \
501} while(0)
502
503#define BCI_WRITE( val ) *bci_ptr++ = (uint32_t)(val)
504
505/*
506 * command DMA support
507 */
508#define SAVAGE_DMA_DEBUG 1
509
510#define DMA_LOCALS uint32_t *dma_ptr;
511
512#define BEGIN_DMA( n ) do { \
513 unsigned int cur = dev_priv->current_dma_page; \
514 unsigned int rest = SAVAGE_DMA_PAGE_SIZE - \
515 dev_priv->dma_pages[cur].used; \
516 if ((n) > rest) { \
517 dma_ptr = savage_dma_alloc(dev_priv, (n)); \
518 } else { /* fast path for small allocations */ \
519 dma_ptr = (uint32_t *)dev_priv->cmd_dma->handle + \
520 cur * SAVAGE_DMA_PAGE_SIZE + \
521 dev_priv->dma_pages[cur].used; \
522 if (dev_priv->dma_pages[cur].used == 0) \
523 savage_dma_wait(dev_priv, cur); \
524 dev_priv->dma_pages[cur].used += (n); \
525 } \
526} while(0)
527
528#define DMA_WRITE( val ) *dma_ptr++ = (uint32_t)(val)
529
530#define DMA_COPY(src, n) do { \
531 memcpy(dma_ptr, (src), (n)*4); \
532 dma_ptr += n; \
533} while(0)
534
535#if SAVAGE_DMA_DEBUG
536#define DMA_COMMIT() do { \
537 unsigned int cur = dev_priv->current_dma_page; \
538 uint32_t *expected = (uint32_t *)dev_priv->cmd_dma->handle + \
539 cur * SAVAGE_DMA_PAGE_SIZE + \
540 dev_priv->dma_pages[cur].used; \
541 if (dma_ptr != expected) { \
542 DRM_ERROR("DMA allocation and use don't match: " \
543 "%p != %p\n", expected, dma_ptr); \
544 savage_dma_reset(dev_priv); \
545 } \
546} while(0)
547#else
548#define DMA_COMMIT() do {/* nothing */} while(0)
549#endif
550
551#define DMA_FLUSH() dev_priv->dma_flush(dev_priv)
552
553/* Buffer aging via event tag
554 */
555
556#define UPDATE_EVENT_COUNTER( ) do { \
557 if (dev_priv->status_ptr) { \
558 uint16_t count; \
559 /* coordinate with Xserver */ \
560 count = dev_priv->status_ptr[1023]; \
561 if (count < dev_priv->event_counter) \
562 dev_priv->event_wrap++; \
563 dev_priv->event_counter = count; \
564 } \
565} while(0)
566
567#define SET_AGE( age, e, w ) do { \
568 (age)->event = e; \
569 (age)->wrap = w; \
570} while(0)
571
572#define TEST_AGE( age, e, w ) \
573 ( (age)->wrap < (w) || ( (age)->wrap == (w) && (age)->event <= (e) ) )
574
575#endif /* __SAVAGE_DRV_H__ */
diff --git a/drivers/char/drm/savage_state.c b/drivers/char/drm/savage_state.c
deleted file mode 100644
index 5f6238fdf1fa..000000000000
--- a/drivers/char/drm/savage_state.c
+++ /dev/null
@@ -1,1163 +0,0 @@
1/* savage_state.c -- State and drawing support for Savage
2 *
3 * Copyright 2004 Felix Kuehling
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sub license,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial portions
15 * of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
19 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 * NON-INFRINGEMENT. IN NO EVENT SHALL FELIX KUEHLING BE LIABLE FOR
21 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
22 * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
23 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
24 */
25#include "drmP.h"
26#include "savage_drm.h"
27#include "savage_drv.h"
28
29void savage_emit_clip_rect_s3d(drm_savage_private_t * dev_priv,
30 const struct drm_clip_rect * pbox)
31{
32 uint32_t scstart = dev_priv->state.s3d.new_scstart;
33 uint32_t scend = dev_priv->state.s3d.new_scend;
34 scstart = (scstart & ~SAVAGE_SCISSOR_MASK_S3D) |
35 ((uint32_t) pbox->x1 & 0x000007ff) |
36 (((uint32_t) pbox->y1 << 16) & 0x07ff0000);
37 scend = (scend & ~SAVAGE_SCISSOR_MASK_S3D) |
38 (((uint32_t) pbox->x2 - 1) & 0x000007ff) |
39 ((((uint32_t) pbox->y2 - 1) << 16) & 0x07ff0000);
40 if (scstart != dev_priv->state.s3d.scstart ||
41 scend != dev_priv->state.s3d.scend) {
42 DMA_LOCALS;
43 BEGIN_DMA(4);
44 DMA_WRITE(BCI_CMD_WAIT | BCI_CMD_WAIT_3D);
45 DMA_SET_REGISTERS(SAVAGE_SCSTART_S3D, 2);
46 DMA_WRITE(scstart);
47 DMA_WRITE(scend);
48 dev_priv->state.s3d.scstart = scstart;
49 dev_priv->state.s3d.scend = scend;
50 dev_priv->waiting = 1;
51 DMA_COMMIT();
52 }
53}
54
55void savage_emit_clip_rect_s4(drm_savage_private_t * dev_priv,
56 const struct drm_clip_rect * pbox)
57{
58 uint32_t drawctrl0 = dev_priv->state.s4.new_drawctrl0;
59 uint32_t drawctrl1 = dev_priv->state.s4.new_drawctrl1;
60 drawctrl0 = (drawctrl0 & ~SAVAGE_SCISSOR_MASK_S4) |
61 ((uint32_t) pbox->x1 & 0x000007ff) |
62 (((uint32_t) pbox->y1 << 12) & 0x00fff000);
63 drawctrl1 = (drawctrl1 & ~SAVAGE_SCISSOR_MASK_S4) |
64 (((uint32_t) pbox->x2 - 1) & 0x000007ff) |
65 ((((uint32_t) pbox->y2 - 1) << 12) & 0x00fff000);
66 if (drawctrl0 != dev_priv->state.s4.drawctrl0 ||
67 drawctrl1 != dev_priv->state.s4.drawctrl1) {
68 DMA_LOCALS;
69 BEGIN_DMA(4);
70 DMA_WRITE(BCI_CMD_WAIT | BCI_CMD_WAIT_3D);
71 DMA_SET_REGISTERS(SAVAGE_DRAWCTRL0_S4, 2);
72 DMA_WRITE(drawctrl0);
73 DMA_WRITE(drawctrl1);
74 dev_priv->state.s4.drawctrl0 = drawctrl0;
75 dev_priv->state.s4.drawctrl1 = drawctrl1;
76 dev_priv->waiting = 1;
77 DMA_COMMIT();
78 }
79}
80
81static int savage_verify_texaddr(drm_savage_private_t * dev_priv, int unit,
82 uint32_t addr)
83{
84 if ((addr & 6) != 2) { /* reserved bits */
85 DRM_ERROR("bad texAddr%d %08x (reserved bits)\n", unit, addr);
86 return -EINVAL;
87 }
88 if (!(addr & 1)) { /* local */
89 addr &= ~7;
90 if (addr < dev_priv->texture_offset ||
91 addr >= dev_priv->texture_offset + dev_priv->texture_size) {
92 DRM_ERROR
93 ("bad texAddr%d %08x (local addr out of range)\n",
94 unit, addr);
95 return -EINVAL;
96 }
97 } else { /* AGP */
98 if (!dev_priv->agp_textures) {
99 DRM_ERROR("bad texAddr%d %08x (AGP not available)\n",
100 unit, addr);
101 return -EINVAL;
102 }
103 addr &= ~7;
104 if (addr < dev_priv->agp_textures->offset ||
105 addr >= (dev_priv->agp_textures->offset +
106 dev_priv->agp_textures->size)) {
107 DRM_ERROR
108 ("bad texAddr%d %08x (AGP addr out of range)\n",
109 unit, addr);
110 return -EINVAL;
111 }
112 }
113 return 0;
114}
115
116#define SAVE_STATE(reg,where) \
117 if(start <= reg && start+count > reg) \
118 dev_priv->state.where = regs[reg - start]
119#define SAVE_STATE_MASK(reg,where,mask) do { \
120 if(start <= reg && start+count > reg) { \
121 uint32_t tmp; \
122 tmp = regs[reg - start]; \
123 dev_priv->state.where = (tmp & (mask)) | \
124 (dev_priv->state.where & ~(mask)); \
125 } \
126} while (0)
127
128static int savage_verify_state_s3d(drm_savage_private_t * dev_priv,
129 unsigned int start, unsigned int count,
130 const uint32_t *regs)
131{
132 if (start < SAVAGE_TEXPALADDR_S3D ||
133 start + count - 1 > SAVAGE_DESTTEXRWWATERMARK_S3D) {
134 DRM_ERROR("invalid register range (0x%04x-0x%04x)\n",
135 start, start + count - 1);
136 return -EINVAL;
137 }
138
139 SAVE_STATE_MASK(SAVAGE_SCSTART_S3D, s3d.new_scstart,
140 ~SAVAGE_SCISSOR_MASK_S3D);
141 SAVE_STATE_MASK(SAVAGE_SCEND_S3D, s3d.new_scend,
142 ~SAVAGE_SCISSOR_MASK_S3D);
143
144 /* if any texture regs were changed ... */
145 if (start <= SAVAGE_TEXCTRL_S3D &&
146 start + count > SAVAGE_TEXPALADDR_S3D) {
147 /* ... check texture state */
148 SAVE_STATE(SAVAGE_TEXCTRL_S3D, s3d.texctrl);
149 SAVE_STATE(SAVAGE_TEXADDR_S3D, s3d.texaddr);
150 if (dev_priv->state.s3d.texctrl & SAVAGE_TEXCTRL_TEXEN_MASK)
151 return savage_verify_texaddr(dev_priv, 0,
152 dev_priv->state.s3d.texaddr);
153 }
154
155 return 0;
156}
157
158static int savage_verify_state_s4(drm_savage_private_t * dev_priv,
159 unsigned int start, unsigned int count,
160 const uint32_t *regs)
161{
162 int ret = 0;
163
164 if (start < SAVAGE_DRAWLOCALCTRL_S4 ||
165 start + count - 1 > SAVAGE_TEXBLENDCOLOR_S4) {
166 DRM_ERROR("invalid register range (0x%04x-0x%04x)\n",
167 start, start + count - 1);
168 return -EINVAL;
169 }
170
171 SAVE_STATE_MASK(SAVAGE_DRAWCTRL0_S4, s4.new_drawctrl0,
172 ~SAVAGE_SCISSOR_MASK_S4);
173 SAVE_STATE_MASK(SAVAGE_DRAWCTRL1_S4, s4.new_drawctrl1,
174 ~SAVAGE_SCISSOR_MASK_S4);
175
176 /* if any texture regs were changed ... */
177 if (start <= SAVAGE_TEXDESCR_S4 &&
178 start + count > SAVAGE_TEXPALADDR_S4) {
179 /* ... check texture state */
180 SAVE_STATE(SAVAGE_TEXDESCR_S4, s4.texdescr);
181 SAVE_STATE(SAVAGE_TEXADDR0_S4, s4.texaddr0);
182 SAVE_STATE(SAVAGE_TEXADDR1_S4, s4.texaddr1);
183 if (dev_priv->state.s4.texdescr & SAVAGE_TEXDESCR_TEX0EN_MASK)
184 ret |= savage_verify_texaddr(dev_priv, 0,
185 dev_priv->state.s4.texaddr0);
186 if (dev_priv->state.s4.texdescr & SAVAGE_TEXDESCR_TEX1EN_MASK)
187 ret |= savage_verify_texaddr(dev_priv, 1,
188 dev_priv->state.s4.texaddr1);
189 }
190
191 return ret;
192}
193
194#undef SAVE_STATE
195#undef SAVE_STATE_MASK
196
197static int savage_dispatch_state(drm_savage_private_t * dev_priv,
198 const drm_savage_cmd_header_t * cmd_header,
199 const uint32_t *regs)
200{
201 unsigned int count = cmd_header->state.count;
202 unsigned int start = cmd_header->state.start;
203 unsigned int count2 = 0;
204 unsigned int bci_size;
205 int ret;
206 DMA_LOCALS;
207
208 if (!count)
209 return 0;
210
211 if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) {
212 ret = savage_verify_state_s3d(dev_priv, start, count, regs);
213 if (ret != 0)
214 return ret;
215 /* scissor regs are emitted in savage_dispatch_draw */
216 if (start < SAVAGE_SCSTART_S3D) {
217 if (start + count > SAVAGE_SCEND_S3D + 1)
218 count2 = count - (SAVAGE_SCEND_S3D + 1 - start);
219 if (start + count > SAVAGE_SCSTART_S3D)
220 count = SAVAGE_SCSTART_S3D - start;
221 } else if (start <= SAVAGE_SCEND_S3D) {
222 if (start + count > SAVAGE_SCEND_S3D + 1) {
223 count -= SAVAGE_SCEND_S3D + 1 - start;
224 start = SAVAGE_SCEND_S3D + 1;
225 } else
226 return 0;
227 }
228 } else {
229 ret = savage_verify_state_s4(dev_priv, start, count, regs);
230 if (ret != 0)
231 return ret;
232 /* scissor regs are emitted in savage_dispatch_draw */
233 if (start < SAVAGE_DRAWCTRL0_S4) {
234 if (start + count > SAVAGE_DRAWCTRL1_S4 + 1)
235 count2 = count -
236 (SAVAGE_DRAWCTRL1_S4 + 1 - start);
237 if (start + count > SAVAGE_DRAWCTRL0_S4)
238 count = SAVAGE_DRAWCTRL0_S4 - start;
239 } else if (start <= SAVAGE_DRAWCTRL1_S4) {
240 if (start + count > SAVAGE_DRAWCTRL1_S4 + 1) {
241 count -= SAVAGE_DRAWCTRL1_S4 + 1 - start;
242 start = SAVAGE_DRAWCTRL1_S4 + 1;
243 } else
244 return 0;
245 }
246 }
247
248 bci_size = count + (count + 254) / 255 + count2 + (count2 + 254) / 255;
249
250 if (cmd_header->state.global) {
251 BEGIN_DMA(bci_size + 1);
252 DMA_WRITE(BCI_CMD_WAIT | BCI_CMD_WAIT_3D);
253 dev_priv->waiting = 1;
254 } else {
255 BEGIN_DMA(bci_size);
256 }
257
258 do {
259 while (count > 0) {
260 unsigned int n = count < 255 ? count : 255;
261 DMA_SET_REGISTERS(start, n);
262 DMA_COPY(regs, n);
263 count -= n;
264 start += n;
265 regs += n;
266 }
267 start += 2;
268 regs += 2;
269 count = count2;
270 count2 = 0;
271 } while (count);
272
273 DMA_COMMIT();
274
275 return 0;
276}
277
278static int savage_dispatch_dma_prim(drm_savage_private_t * dev_priv,
279 const drm_savage_cmd_header_t * cmd_header,
280 const struct drm_buf * dmabuf)
281{
282 unsigned char reorder = 0;
283 unsigned int prim = cmd_header->prim.prim;
284 unsigned int skip = cmd_header->prim.skip;
285 unsigned int n = cmd_header->prim.count;
286 unsigned int start = cmd_header->prim.start;
287 unsigned int i;
288 BCI_LOCALS;
289
290 if (!dmabuf) {
291 DRM_ERROR("called without dma buffers!\n");
292 return -EINVAL;
293 }
294
295 if (!n)
296 return 0;
297
298 switch (prim) {
299 case SAVAGE_PRIM_TRILIST_201:
300 reorder = 1;
301 prim = SAVAGE_PRIM_TRILIST;
302 case SAVAGE_PRIM_TRILIST:
303 if (n % 3 != 0) {
304 DRM_ERROR("wrong number of vertices %u in TRILIST\n",
305 n);
306 return -EINVAL;
307 }
308 break;
309 case SAVAGE_PRIM_TRISTRIP:
310 case SAVAGE_PRIM_TRIFAN:
311 if (n < 3) {
312 DRM_ERROR
313 ("wrong number of vertices %u in TRIFAN/STRIP\n",
314 n);
315 return -EINVAL;
316 }
317 break;
318 default:
319 DRM_ERROR("invalid primitive type %u\n", prim);
320 return -EINVAL;
321 }
322
323 if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) {
324 if (skip != 0) {
325 DRM_ERROR("invalid skip flags 0x%04x for DMA\n", skip);
326 return -EINVAL;
327 }
328 } else {
329 unsigned int size = 10 - (skip & 1) - (skip >> 1 & 1) -
330 (skip >> 2 & 1) - (skip >> 3 & 1) - (skip >> 4 & 1) -
331 (skip >> 5 & 1) - (skip >> 6 & 1) - (skip >> 7 & 1);
332 if (skip > SAVAGE_SKIP_ALL_S4 || size != 8) {
333 DRM_ERROR("invalid skip flags 0x%04x for DMA\n", skip);
334 return -EINVAL;
335 }
336 if (reorder) {
337 DRM_ERROR("TRILIST_201 used on Savage4 hardware\n");
338 return -EINVAL;
339 }
340 }
341
342 if (start + n > dmabuf->total / 32) {
343 DRM_ERROR("vertex indices (%u-%u) out of range (0-%u)\n",
344 start, start + n - 1, dmabuf->total / 32);
345 return -EINVAL;
346 }
347
348 /* Vertex DMA doesn't work with command DMA at the same time,
349 * so we use BCI_... to submit commands here. Flush buffered
350 * faked DMA first. */
351 DMA_FLUSH();
352
353 if (dmabuf->bus_address != dev_priv->state.common.vbaddr) {
354 BEGIN_BCI(2);
355 BCI_SET_REGISTERS(SAVAGE_VERTBUFADDR, 1);
356 BCI_WRITE(dmabuf->bus_address | dev_priv->dma_type);
357 dev_priv->state.common.vbaddr = dmabuf->bus_address;
358 }
359 if (S3_SAVAGE3D_SERIES(dev_priv->chipset) && dev_priv->waiting) {
360 /* Workaround for what looks like a hardware bug. If a
361 * WAIT_3D_IDLE was emitted some time before the
362 * indexed drawing command then the engine will lock
363 * up. There are two known workarounds:
364 * WAIT_IDLE_EMPTY or emit at least 63 NOPs. */
365 BEGIN_BCI(63);
366 for (i = 0; i < 63; ++i)
367 BCI_WRITE(BCI_CMD_WAIT);
368 dev_priv->waiting = 0;
369 }
370
371 prim <<= 25;
372 while (n != 0) {
373 /* Can emit up to 255 indices (85 triangles) at once. */
374 unsigned int count = n > 255 ? 255 : n;
375 if (reorder) {
376 /* Need to reorder indices for correct flat
377 * shading while preserving the clock sense
378 * for correct culling. Only on Savage3D. */
379 int reorder[3] = { -1, -1, -1 };
380 reorder[start % 3] = 2;
381
382 BEGIN_BCI((count + 1 + 1) / 2);
383 BCI_DRAW_INDICES_S3D(count, prim, start + 2);
384
385 for (i = start + 1; i + 1 < start + count; i += 2)
386 BCI_WRITE((i + reorder[i % 3]) |
387 ((i + 1 +
388 reorder[(i + 1) % 3]) << 16));
389 if (i < start + count)
390 BCI_WRITE(i + reorder[i % 3]);
391 } else if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) {
392 BEGIN_BCI((count + 1 + 1) / 2);
393 BCI_DRAW_INDICES_S3D(count, prim, start);
394
395 for (i = start + 1; i + 1 < start + count; i += 2)
396 BCI_WRITE(i | ((i + 1) << 16));
397 if (i < start + count)
398 BCI_WRITE(i);
399 } else {
400 BEGIN_BCI((count + 2 + 1) / 2);
401 BCI_DRAW_INDICES_S4(count, prim, skip);
402
403 for (i = start; i + 1 < start + count; i += 2)
404 BCI_WRITE(i | ((i + 1) << 16));
405 if (i < start + count)
406 BCI_WRITE(i);
407 }
408
409 start += count;
410 n -= count;
411
412 prim |= BCI_CMD_DRAW_CONT;
413 }
414
415 return 0;
416}
417
418static int savage_dispatch_vb_prim(drm_savage_private_t * dev_priv,
419 const drm_savage_cmd_header_t * cmd_header,
420 const uint32_t *vtxbuf, unsigned int vb_size,
421 unsigned int vb_stride)
422{
423 unsigned char reorder = 0;
424 unsigned int prim = cmd_header->prim.prim;
425 unsigned int skip = cmd_header->prim.skip;
426 unsigned int n = cmd_header->prim.count;
427 unsigned int start = cmd_header->prim.start;
428 unsigned int vtx_size;
429 unsigned int i;
430 DMA_LOCALS;
431
432 if (!n)
433 return 0;
434
435 switch (prim) {
436 case SAVAGE_PRIM_TRILIST_201:
437 reorder = 1;
438 prim = SAVAGE_PRIM_TRILIST;
439 case SAVAGE_PRIM_TRILIST:
440 if (n % 3 != 0) {
441 DRM_ERROR("wrong number of vertices %u in TRILIST\n",
442 n);
443 return -EINVAL;
444 }
445 break;
446 case SAVAGE_PRIM_TRISTRIP:
447 case SAVAGE_PRIM_TRIFAN:
448 if (n < 3) {
449 DRM_ERROR
450 ("wrong number of vertices %u in TRIFAN/STRIP\n",
451 n);
452 return -EINVAL;
453 }
454 break;
455 default:
456 DRM_ERROR("invalid primitive type %u\n", prim);
457 return -EINVAL;
458 }
459
460 if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) {
461 if (skip > SAVAGE_SKIP_ALL_S3D) {
462 DRM_ERROR("invalid skip flags 0x%04x\n", skip);
463 return -EINVAL;
464 }
465 vtx_size = 8; /* full vertex */
466 } else {
467 if (skip > SAVAGE_SKIP_ALL_S4) {
468 DRM_ERROR("invalid skip flags 0x%04x\n", skip);
469 return -EINVAL;
470 }
471 vtx_size = 10; /* full vertex */
472 }
473
474 vtx_size -= (skip & 1) + (skip >> 1 & 1) +
475 (skip >> 2 & 1) + (skip >> 3 & 1) + (skip >> 4 & 1) +
476 (skip >> 5 & 1) + (skip >> 6 & 1) + (skip >> 7 & 1);
477
478 if (vtx_size > vb_stride) {
479 DRM_ERROR("vertex size greater than vb stride (%u > %u)\n",
480 vtx_size, vb_stride);
481 return -EINVAL;
482 }
483
484 if (start + n > vb_size / (vb_stride * 4)) {
485 DRM_ERROR("vertex indices (%u-%u) out of range (0-%u)\n",
486 start, start + n - 1, vb_size / (vb_stride * 4));
487 return -EINVAL;
488 }
489
490 prim <<= 25;
491 while (n != 0) {
492 /* Can emit up to 255 vertices (85 triangles) at once. */
493 unsigned int count = n > 255 ? 255 : n;
494 if (reorder) {
495 /* Need to reorder vertices for correct flat
496 * shading while preserving the clock sense
497 * for correct culling. Only on Savage3D. */
498 int reorder[3] = { -1, -1, -1 };
499 reorder[start % 3] = 2;
500
501 BEGIN_DMA(count * vtx_size + 1);
502 DMA_DRAW_PRIMITIVE(count, prim, skip);
503
504 for (i = start; i < start + count; ++i) {
505 unsigned int j = i + reorder[i % 3];
506 DMA_COPY(&vtxbuf[vb_stride * j], vtx_size);
507 }
508
509 DMA_COMMIT();
510 } else {
511 BEGIN_DMA(count * vtx_size + 1);
512 DMA_DRAW_PRIMITIVE(count, prim, skip);
513
514 if (vb_stride == vtx_size) {
515 DMA_COPY(&vtxbuf[vb_stride * start],
516 vtx_size * count);
517 } else {
518 for (i = start; i < start + count; ++i) {
519 DMA_COPY(&vtxbuf [vb_stride * i],
520 vtx_size);
521 }
522 }
523
524 DMA_COMMIT();
525 }
526
527 start += count;
528 n -= count;
529
530 prim |= BCI_CMD_DRAW_CONT;
531 }
532
533 return 0;
534}
535
536static int savage_dispatch_dma_idx(drm_savage_private_t * dev_priv,
537 const drm_savage_cmd_header_t * cmd_header,
538 const uint16_t *idx,
539 const struct drm_buf * dmabuf)
540{
541 unsigned char reorder = 0;
542 unsigned int prim = cmd_header->idx.prim;
543 unsigned int skip = cmd_header->idx.skip;
544 unsigned int n = cmd_header->idx.count;
545 unsigned int i;
546 BCI_LOCALS;
547
548 if (!dmabuf) {
549 DRM_ERROR("called without dma buffers!\n");
550 return -EINVAL;
551 }
552
553 if (!n)
554 return 0;
555
556 switch (prim) {
557 case SAVAGE_PRIM_TRILIST_201:
558 reorder = 1;
559 prim = SAVAGE_PRIM_TRILIST;
560 case SAVAGE_PRIM_TRILIST:
561 if (n % 3 != 0) {
562 DRM_ERROR("wrong number of indices %u in TRILIST\n", n);
563 return -EINVAL;
564 }
565 break;
566 case SAVAGE_PRIM_TRISTRIP:
567 case SAVAGE_PRIM_TRIFAN:
568 if (n < 3) {
569 DRM_ERROR
570 ("wrong number of indices %u in TRIFAN/STRIP\n", n);
571 return -EINVAL;
572 }
573 break;
574 default:
575 DRM_ERROR("invalid primitive type %u\n", prim);
576 return -EINVAL;
577 }
578
579 if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) {
580 if (skip != 0) {
581 DRM_ERROR("invalid skip flags 0x%04x for DMA\n", skip);
582 return -EINVAL;
583 }
584 } else {
585 unsigned int size = 10 - (skip & 1) - (skip >> 1 & 1) -
586 (skip >> 2 & 1) - (skip >> 3 & 1) - (skip >> 4 & 1) -
587 (skip >> 5 & 1) - (skip >> 6 & 1) - (skip >> 7 & 1);
588 if (skip > SAVAGE_SKIP_ALL_S4 || size != 8) {
589 DRM_ERROR("invalid skip flags 0x%04x for DMA\n", skip);
590 return -EINVAL;
591 }
592 if (reorder) {
593 DRM_ERROR("TRILIST_201 used on Savage4 hardware\n");
594 return -EINVAL;
595 }
596 }
597
598 /* Vertex DMA doesn't work with command DMA at the same time,
599 * so we use BCI_... to submit commands here. Flush buffered
600 * faked DMA first. */
601 DMA_FLUSH();
602
603 if (dmabuf->bus_address != dev_priv->state.common.vbaddr) {
604 BEGIN_BCI(2);
605 BCI_SET_REGISTERS(SAVAGE_VERTBUFADDR, 1);
606 BCI_WRITE(dmabuf->bus_address | dev_priv->dma_type);
607 dev_priv->state.common.vbaddr = dmabuf->bus_address;
608 }
609 if (S3_SAVAGE3D_SERIES(dev_priv->chipset) && dev_priv->waiting) {
610 /* Workaround for what looks like a hardware bug. If a
611 * WAIT_3D_IDLE was emitted some time before the
612 * indexed drawing command then the engine will lock
613 * up. There are two known workarounds:
614 * WAIT_IDLE_EMPTY or emit at least 63 NOPs. */
615 BEGIN_BCI(63);
616 for (i = 0; i < 63; ++i)
617 BCI_WRITE(BCI_CMD_WAIT);
618 dev_priv->waiting = 0;
619 }
620
621 prim <<= 25;
622 while (n != 0) {
623 /* Can emit up to 255 indices (85 triangles) at once. */
624 unsigned int count = n > 255 ? 255 : n;
625
626 /* check indices */
627 for (i = 0; i < count; ++i) {
628 if (idx[i] > dmabuf->total / 32) {
629 DRM_ERROR("idx[%u]=%u out of range (0-%u)\n",
630 i, idx[i], dmabuf->total / 32);
631 return -EINVAL;
632 }
633 }
634
635 if (reorder) {
636 /* Need to reorder indices for correct flat
637 * shading while preserving the clock sense
638 * for correct culling. Only on Savage3D. */
639 int reorder[3] = { 2, -1, -1 };
640
641 BEGIN_BCI((count + 1 + 1) / 2);
642 BCI_DRAW_INDICES_S3D(count, prim, idx[2]);
643
644 for (i = 1; i + 1 < count; i += 2)
645 BCI_WRITE(idx[i + reorder[i % 3]] |
646 (idx[i + 1 +
647 reorder[(i + 1) % 3]] << 16));
648 if (i < count)
649 BCI_WRITE(idx[i + reorder[i % 3]]);
650 } else if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) {
651 BEGIN_BCI((count + 1 + 1) / 2);
652 BCI_DRAW_INDICES_S3D(count, prim, idx[0]);
653
654 for (i = 1; i + 1 < count; i += 2)
655 BCI_WRITE(idx[i] | (idx[i + 1] << 16));
656 if (i < count)
657 BCI_WRITE(idx[i]);
658 } else {
659 BEGIN_BCI((count + 2 + 1) / 2);
660 BCI_DRAW_INDICES_S4(count, prim, skip);
661
662 for (i = 0; i + 1 < count; i += 2)
663 BCI_WRITE(idx[i] | (idx[i + 1] << 16));
664 if (i < count)
665 BCI_WRITE(idx[i]);
666 }
667
668 idx += count;
669 n -= count;
670
671 prim |= BCI_CMD_DRAW_CONT;
672 }
673
674 return 0;
675}
676
677static int savage_dispatch_vb_idx(drm_savage_private_t * dev_priv,
678 const drm_savage_cmd_header_t * cmd_header,
679 const uint16_t *idx,
680 const uint32_t *vtxbuf,
681 unsigned int vb_size, unsigned int vb_stride)
682{
683 unsigned char reorder = 0;
684 unsigned int prim = cmd_header->idx.prim;
685 unsigned int skip = cmd_header->idx.skip;
686 unsigned int n = cmd_header->idx.count;
687 unsigned int vtx_size;
688 unsigned int i;
689 DMA_LOCALS;
690
691 if (!n)
692 return 0;
693
694 switch (prim) {
695 case SAVAGE_PRIM_TRILIST_201:
696 reorder = 1;
697 prim = SAVAGE_PRIM_TRILIST;
698 case SAVAGE_PRIM_TRILIST:
699 if (n % 3 != 0) {
700 DRM_ERROR("wrong number of indices %u in TRILIST\n", n);
701 return -EINVAL;
702 }
703 break;
704 case SAVAGE_PRIM_TRISTRIP:
705 case SAVAGE_PRIM_TRIFAN:
706 if (n < 3) {
707 DRM_ERROR
708 ("wrong number of indices %u in TRIFAN/STRIP\n", n);
709 return -EINVAL;
710 }
711 break;
712 default:
713 DRM_ERROR("invalid primitive type %u\n", prim);
714 return -EINVAL;
715 }
716
717 if (S3_SAVAGE3D_SERIES(dev_priv->chipset)) {
718 if (skip > SAVAGE_SKIP_ALL_S3D) {
719 DRM_ERROR("invalid skip flags 0x%04x\n", skip);
720 return -EINVAL;
721 }
722 vtx_size = 8; /* full vertex */
723 } else {
724 if (skip > SAVAGE_SKIP_ALL_S4) {
725 DRM_ERROR("invalid skip flags 0x%04x\n", skip);
726 return -EINVAL;
727 }
728 vtx_size = 10; /* full vertex */
729 }
730
731 vtx_size -= (skip & 1) + (skip >> 1 & 1) +
732 (skip >> 2 & 1) + (skip >> 3 & 1) + (skip >> 4 & 1) +
733 (skip >> 5 & 1) + (skip >> 6 & 1) + (skip >> 7 & 1);
734
735 if (vtx_size > vb_stride) {
736 DRM_ERROR("vertex size greater than vb stride (%u > %u)\n",
737 vtx_size, vb_stride);
738 return -EINVAL;
739 }
740
741 prim <<= 25;
742 while (n != 0) {
743 /* Can emit up to 255 vertices (85 triangles) at once. */
744 unsigned int count = n > 255 ? 255 : n;
745
746 /* Check indices */
747 for (i = 0; i < count; ++i) {
748 if (idx[i] > vb_size / (vb_stride * 4)) {
749 DRM_ERROR("idx[%u]=%u out of range (0-%u)\n",
750 i, idx[i], vb_size / (vb_stride * 4));
751 return -EINVAL;
752 }
753 }
754
755 if (reorder) {
756 /* Need to reorder vertices for correct flat
757 * shading while preserving the clock sense
758 * for correct culling. Only on Savage3D. */
759 int reorder[3] = { 2, -1, -1 };
760
761 BEGIN_DMA(count * vtx_size + 1);
762 DMA_DRAW_PRIMITIVE(count, prim, skip);
763
764 for (i = 0; i < count; ++i) {
765 unsigned int j = idx[i + reorder[i % 3]];
766 DMA_COPY(&vtxbuf[vb_stride * j], vtx_size);
767 }
768
769 DMA_COMMIT();
770 } else {
771 BEGIN_DMA(count * vtx_size + 1);
772 DMA_DRAW_PRIMITIVE(count, prim, skip);
773
774 for (i = 0; i < count; ++i) {
775 unsigned int j = idx[i];
776 DMA_COPY(&vtxbuf[vb_stride * j], vtx_size);
777 }
778
779 DMA_COMMIT();
780 }
781
782 idx += count;
783 n -= count;
784
785 prim |= BCI_CMD_DRAW_CONT;
786 }
787
788 return 0;
789}
790
791static int savage_dispatch_clear(drm_savage_private_t * dev_priv,
792 const drm_savage_cmd_header_t * cmd_header,
793 const drm_savage_cmd_header_t *data,
794 unsigned int nbox,
795 const struct drm_clip_rect *boxes)
796{
797 unsigned int flags = cmd_header->clear0.flags;
798 unsigned int clear_cmd;
799 unsigned int i, nbufs;
800 DMA_LOCALS;
801
802 if (nbox == 0)
803 return 0;
804
805 clear_cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP |
806 BCI_CMD_SEND_COLOR | BCI_CMD_DEST_PBD_NEW;
807 BCI_CMD_SET_ROP(clear_cmd, 0xCC);
808
809 nbufs = ((flags & SAVAGE_FRONT) ? 1 : 0) +
810 ((flags & SAVAGE_BACK) ? 1 : 0) + ((flags & SAVAGE_DEPTH) ? 1 : 0);
811 if (nbufs == 0)
812 return 0;
813
814 if (data->clear1.mask != 0xffffffff) {
815 /* set mask */
816 BEGIN_DMA(2);
817 DMA_SET_REGISTERS(SAVAGE_BITPLANEWTMASK, 1);
818 DMA_WRITE(data->clear1.mask);
819 DMA_COMMIT();
820 }
821 for (i = 0; i < nbox; ++i) {
822 unsigned int x, y, w, h;
823 unsigned int buf;
824 x = boxes[i].x1, y = boxes[i].y1;
825 w = boxes[i].x2 - boxes[i].x1;
826 h = boxes[i].y2 - boxes[i].y1;
827 BEGIN_DMA(nbufs * 6);
828 for (buf = SAVAGE_FRONT; buf <= SAVAGE_DEPTH; buf <<= 1) {
829 if (!(flags & buf))
830 continue;
831 DMA_WRITE(clear_cmd);
832 switch (buf) {
833 case SAVAGE_FRONT:
834 DMA_WRITE(dev_priv->front_offset);
835 DMA_WRITE(dev_priv->front_bd);
836 break;
837 case SAVAGE_BACK:
838 DMA_WRITE(dev_priv->back_offset);
839 DMA_WRITE(dev_priv->back_bd);
840 break;
841 case SAVAGE_DEPTH:
842 DMA_WRITE(dev_priv->depth_offset);
843 DMA_WRITE(dev_priv->depth_bd);
844 break;
845 }
846 DMA_WRITE(data->clear1.value);
847 DMA_WRITE(BCI_X_Y(x, y));
848 DMA_WRITE(BCI_W_H(w, h));
849 }
850 DMA_COMMIT();
851 }
852 if (data->clear1.mask != 0xffffffff) {
853 /* reset mask */
854 BEGIN_DMA(2);
855 DMA_SET_REGISTERS(SAVAGE_BITPLANEWTMASK, 1);
856 DMA_WRITE(0xffffffff);
857 DMA_COMMIT();
858 }
859
860 return 0;
861}
862
863static int savage_dispatch_swap(drm_savage_private_t * dev_priv,
864 unsigned int nbox, const struct drm_clip_rect *boxes)
865{
866 unsigned int swap_cmd;
867 unsigned int i;
868 DMA_LOCALS;
869
870 if (nbox == 0)
871 return 0;
872
873 swap_cmd = BCI_CMD_RECT | BCI_CMD_RECT_XP | BCI_CMD_RECT_YP |
874 BCI_CMD_SRC_PBD_COLOR_NEW | BCI_CMD_DEST_GBD;
875 BCI_CMD_SET_ROP(swap_cmd, 0xCC);
876
877 for (i = 0; i < nbox; ++i) {
878 BEGIN_DMA(6);
879 DMA_WRITE(swap_cmd);
880 DMA_WRITE(dev_priv->back_offset);
881 DMA_WRITE(dev_priv->back_bd);
882 DMA_WRITE(BCI_X_Y(boxes[i].x1, boxes[i].y1));
883 DMA_WRITE(BCI_X_Y(boxes[i].x1, boxes[i].y1));
884 DMA_WRITE(BCI_W_H(boxes[i].x2 - boxes[i].x1,
885 boxes[i].y2 - boxes[i].y1));
886 DMA_COMMIT();
887 }
888
889 return 0;
890}
891
892static int savage_dispatch_draw(drm_savage_private_t * dev_priv,
893 const drm_savage_cmd_header_t *start,
894 const drm_savage_cmd_header_t *end,
895 const struct drm_buf * dmabuf,
896 const unsigned int *vtxbuf,
897 unsigned int vb_size, unsigned int vb_stride,
898 unsigned int nbox,
899 const struct drm_clip_rect *boxes)
900{
901 unsigned int i, j;
902 int ret;
903
904 for (i = 0; i < nbox; ++i) {
905 const drm_savage_cmd_header_t *cmdbuf;
906 dev_priv->emit_clip_rect(dev_priv, &boxes[i]);
907
908 cmdbuf = start;
909 while (cmdbuf < end) {
910 drm_savage_cmd_header_t cmd_header;
911 cmd_header = *cmdbuf;
912 cmdbuf++;
913 switch (cmd_header.cmd.cmd) {
914 case SAVAGE_CMD_DMA_PRIM:
915 ret = savage_dispatch_dma_prim(
916 dev_priv, &cmd_header, dmabuf);
917 break;
918 case SAVAGE_CMD_VB_PRIM:
919 ret = savage_dispatch_vb_prim(
920 dev_priv, &cmd_header,
921 vtxbuf, vb_size, vb_stride);
922 break;
923 case SAVAGE_CMD_DMA_IDX:
924 j = (cmd_header.idx.count + 3) / 4;
925 /* j was check in savage_bci_cmdbuf */
926 ret = savage_dispatch_dma_idx(dev_priv,
927 &cmd_header, (const uint16_t *)cmdbuf,
928 dmabuf);
929 cmdbuf += j;
930 break;
931 case SAVAGE_CMD_VB_IDX:
932 j = (cmd_header.idx.count + 3) / 4;
933 /* j was check in savage_bci_cmdbuf */
934 ret = savage_dispatch_vb_idx(dev_priv,
935 &cmd_header, (const uint16_t *)cmdbuf,
936 (const uint32_t *)vtxbuf, vb_size,
937 vb_stride);
938 cmdbuf += j;
939 break;
940 default:
941 /* What's the best return code? EFAULT? */
942 DRM_ERROR("IMPLEMENTATION ERROR: "
943 "non-drawing-command %d\n",
944 cmd_header.cmd.cmd);
945 return -EINVAL;
946 }
947
948 if (ret != 0)
949 return ret;
950 }
951 }
952
953 return 0;
954}
955
956int savage_bci_cmdbuf(struct drm_device *dev, void *data, struct drm_file *file_priv)
957{
958 drm_savage_private_t *dev_priv = dev->dev_private;
959 struct drm_device_dma *dma = dev->dma;
960 struct drm_buf *dmabuf;
961 drm_savage_cmdbuf_t *cmdbuf = data;
962 drm_savage_cmd_header_t *kcmd_addr = NULL;
963 drm_savage_cmd_header_t *first_draw_cmd;
964 unsigned int *kvb_addr = NULL;
965 struct drm_clip_rect *kbox_addr = NULL;
966 unsigned int i, j;
967 int ret = 0;
968
969 DRM_DEBUG("\n");
970
971 LOCK_TEST_WITH_RETURN(dev, file_priv);
972
973 if (dma && dma->buflist) {
974 if (cmdbuf->dma_idx > dma->buf_count) {
975 DRM_ERROR
976 ("vertex buffer index %u out of range (0-%u)\n",
977 cmdbuf->dma_idx, dma->buf_count - 1);
978 return -EINVAL;
979 }
980 dmabuf = dma->buflist[cmdbuf->dma_idx];
981 } else {
982 dmabuf = NULL;
983 }
984
985 /* Copy the user buffers into kernel temporary areas. This hasn't been
986 * a performance loss compared to VERIFYAREA_READ/
987 * COPY_FROM_USER_UNCHECKED when done in other drivers, and is correct
988 * for locking on FreeBSD.
989 */
990 if (cmdbuf->size) {
991 kcmd_addr = drm_alloc(cmdbuf->size * 8, DRM_MEM_DRIVER);
992 if (kcmd_addr == NULL)
993 return -ENOMEM;
994
995 if (DRM_COPY_FROM_USER(kcmd_addr, cmdbuf->cmd_addr,
996 cmdbuf->size * 8))
997 {
998 drm_free(kcmd_addr, cmdbuf->size * 8, DRM_MEM_DRIVER);
999 return -EFAULT;
1000 }
1001 cmdbuf->cmd_addr = kcmd_addr;
1002 }
1003 if (cmdbuf->vb_size) {
1004 kvb_addr = drm_alloc(cmdbuf->vb_size, DRM_MEM_DRIVER);
1005 if (kvb_addr == NULL) {
1006 ret = -ENOMEM;
1007 goto done;
1008 }
1009
1010 if (DRM_COPY_FROM_USER(kvb_addr, cmdbuf->vb_addr,
1011 cmdbuf->vb_size)) {
1012 ret = -EFAULT;
1013 goto done;
1014 }
1015 cmdbuf->vb_addr = kvb_addr;
1016 }
1017 if (cmdbuf->nbox) {
1018 kbox_addr = drm_alloc(cmdbuf->nbox * sizeof(struct drm_clip_rect),
1019 DRM_MEM_DRIVER);
1020 if (kbox_addr == NULL) {
1021 ret = -ENOMEM;
1022 goto done;
1023 }
1024
1025 if (DRM_COPY_FROM_USER(kbox_addr, cmdbuf->box_addr,
1026 cmdbuf->nbox * sizeof(struct drm_clip_rect))) {
1027 ret = -EFAULT;
1028 goto done;
1029 }
1030 cmdbuf->box_addr = kbox_addr;
1031 }
1032
1033 /* Make sure writes to DMA buffers are finished before sending
1034 * DMA commands to the graphics hardware. */
1035 DRM_MEMORYBARRIER();
1036
1037 /* Coming from user space. Don't know if the Xserver has
1038 * emitted wait commands. Assuming the worst. */
1039 dev_priv->waiting = 1;
1040
1041 i = 0;
1042 first_draw_cmd = NULL;
1043 while (i < cmdbuf->size) {
1044 drm_savage_cmd_header_t cmd_header;
1045 cmd_header = *(drm_savage_cmd_header_t *)cmdbuf->cmd_addr;
1046 cmdbuf->cmd_addr++;
1047 i++;
1048
1049 /* Group drawing commands with same state to minimize
1050 * iterations over clip rects. */
1051 j = 0;
1052 switch (cmd_header.cmd.cmd) {
1053 case SAVAGE_CMD_DMA_IDX:
1054 case SAVAGE_CMD_VB_IDX:
1055 j = (cmd_header.idx.count + 3) / 4;
1056 if (i + j > cmdbuf->size) {
1057 DRM_ERROR("indexed drawing command extends "
1058 "beyond end of command buffer\n");
1059 DMA_FLUSH();
1060 return -EINVAL;
1061 }
1062 /* fall through */
1063 case SAVAGE_CMD_DMA_PRIM:
1064 case SAVAGE_CMD_VB_PRIM:
1065 if (!first_draw_cmd)
1066 first_draw_cmd = cmdbuf->cmd_addr - 1;
1067 cmdbuf->cmd_addr += j;
1068 i += j;
1069 break;
1070 default:
1071 if (first_draw_cmd) {
1072 ret = savage_dispatch_draw(
1073 dev_priv, first_draw_cmd,
1074 cmdbuf->cmd_addr - 1,
1075 dmabuf, cmdbuf->vb_addr, cmdbuf->vb_size,
1076 cmdbuf->vb_stride,
1077 cmdbuf->nbox, cmdbuf->box_addr);
1078 if (ret != 0)
1079 return ret;
1080 first_draw_cmd = NULL;
1081 }
1082 }
1083 if (first_draw_cmd)
1084 continue;
1085
1086 switch (cmd_header.cmd.cmd) {
1087 case SAVAGE_CMD_STATE:
1088 j = (cmd_header.state.count + 1) / 2;
1089 if (i + j > cmdbuf->size) {
1090 DRM_ERROR("command SAVAGE_CMD_STATE extends "
1091 "beyond end of command buffer\n");
1092 DMA_FLUSH();
1093 ret = -EINVAL;
1094 goto done;
1095 }
1096 ret = savage_dispatch_state(dev_priv, &cmd_header,
1097 (const uint32_t *)cmdbuf->cmd_addr);
1098 cmdbuf->cmd_addr += j;
1099 i += j;
1100 break;
1101 case SAVAGE_CMD_CLEAR:
1102 if (i + 1 > cmdbuf->size) {
1103 DRM_ERROR("command SAVAGE_CMD_CLEAR extends "
1104 "beyond end of command buffer\n");
1105 DMA_FLUSH();
1106 ret = -EINVAL;
1107 goto done;
1108 }
1109 ret = savage_dispatch_clear(dev_priv, &cmd_header,
1110 cmdbuf->cmd_addr,
1111 cmdbuf->nbox,
1112 cmdbuf->box_addr);
1113 cmdbuf->cmd_addr++;
1114 i++;
1115 break;
1116 case SAVAGE_CMD_SWAP:
1117 ret = savage_dispatch_swap(dev_priv, cmdbuf->nbox,
1118 cmdbuf->box_addr);
1119 break;
1120 default:
1121 DRM_ERROR("invalid command 0x%x\n",
1122 cmd_header.cmd.cmd);
1123 DMA_FLUSH();
1124 ret = -EINVAL;
1125 goto done;
1126 }
1127
1128 if (ret != 0) {
1129 DMA_FLUSH();
1130 goto done;
1131 }
1132 }
1133
1134 if (first_draw_cmd) {
1135 ret = savage_dispatch_draw (
1136 dev_priv, first_draw_cmd, cmdbuf->cmd_addr, dmabuf,
1137 cmdbuf->vb_addr, cmdbuf->vb_size, cmdbuf->vb_stride,
1138 cmdbuf->nbox, cmdbuf->box_addr);
1139 if (ret != 0) {
1140 DMA_FLUSH();
1141 goto done;
1142 }
1143 }
1144
1145 DMA_FLUSH();
1146
1147 if (dmabuf && cmdbuf->discard) {
1148 drm_savage_buf_priv_t *buf_priv = dmabuf->dev_private;
1149 uint16_t event;
1150 event = savage_bci_emit_event(dev_priv, SAVAGE_WAIT_3D);
1151 SET_AGE(&buf_priv->age, event, dev_priv->event_wrap);
1152 savage_freelist_put(dev, dmabuf);
1153 }
1154
1155done:
1156 /* If we didn't need to allocate them, these'll be NULL */
1157 drm_free(kcmd_addr, cmdbuf->size * 8, DRM_MEM_DRIVER);
1158 drm_free(kvb_addr, cmdbuf->vb_size, DRM_MEM_DRIVER);
1159 drm_free(kbox_addr, cmdbuf->nbox * sizeof(struct drm_clip_rect),
1160 DRM_MEM_DRIVER);
1161
1162 return ret;
1163}
diff --git a/drivers/char/drm/sis_drm.h b/drivers/char/drm/sis_drm.h
deleted file mode 100644
index 30f7b3827466..000000000000
--- a/drivers/char/drm/sis_drm.h
+++ /dev/null
@@ -1,67 +0,0 @@
1/* sis_drv.h -- Private header for sis driver -*- linux-c -*- */
2/*
3 * Copyright 2005 Eric Anholt
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the next
14 * paragraph) shall be included in all copies or substantial portions of the
15 * Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
24 *
25 */
26
27#ifndef __SIS_DRM_H__
28#define __SIS_DRM_H__
29
30/* SiS specific ioctls */
31#define NOT_USED_0_3
32#define DRM_SIS_FB_ALLOC 0x04
33#define DRM_SIS_FB_FREE 0x05
34#define NOT_USED_6_12
35#define DRM_SIS_AGP_INIT 0x13
36#define DRM_SIS_AGP_ALLOC 0x14
37#define DRM_SIS_AGP_FREE 0x15
38#define DRM_SIS_FB_INIT 0x16
39
40#define DRM_IOCTL_SIS_FB_ALLOC DRM_IOWR(DRM_COMMAND_BASE + DRM_SIS_FB_ALLOC, drm_sis_mem_t)
41#define DRM_IOCTL_SIS_FB_FREE DRM_IOW( DRM_COMMAND_BASE + DRM_SIS_FB_FREE, drm_sis_mem_t)
42#define DRM_IOCTL_SIS_AGP_INIT DRM_IOWR(DRM_COMMAND_BASE + DRM_SIS_AGP_INIT, drm_sis_agp_t)
43#define DRM_IOCTL_SIS_AGP_ALLOC DRM_IOWR(DRM_COMMAND_BASE + DRM_SIS_AGP_ALLOC, drm_sis_mem_t)
44#define DRM_IOCTL_SIS_AGP_FREE DRM_IOW( DRM_COMMAND_BASE + DRM_SIS_AGP_FREE, drm_sis_mem_t)
45#define DRM_IOCTL_SIS_FB_INIT DRM_IOW( DRM_COMMAND_BASE + DRM_SIS_FB_INIT, drm_sis_fb_t)
46/*
47#define DRM_IOCTL_SIS_FLIP DRM_IOW( 0x48, drm_sis_flip_t)
48#define DRM_IOCTL_SIS_FLIP_INIT DRM_IO( 0x49)
49#define DRM_IOCTL_SIS_FLIP_FINAL DRM_IO( 0x50)
50*/
51
52typedef struct {
53 int context;
54 unsigned int offset;
55 unsigned int size;
56 unsigned long free;
57} drm_sis_mem_t;
58
59typedef struct {
60 unsigned int offset, size;
61} drm_sis_agp_t;
62
63typedef struct {
64 unsigned int offset, size;
65} drm_sis_fb_t;
66
67#endif /* __SIS_DRM_H__ */
diff --git a/drivers/char/drm/sis_drv.c b/drivers/char/drm/sis_drv.c
deleted file mode 100644
index 7dacc64e9b56..000000000000
--- a/drivers/char/drm/sis_drv.c
+++ /dev/null
@@ -1,117 +0,0 @@
1/* sis.c -- sis driver -*- linux-c -*-
2 *
3 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
4 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
5 * All Rights Reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the next
15 * paragraph) shall be included in all copies or substantial portions of the
16 * Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
22 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 * DEALINGS IN THE SOFTWARE.
25 *
26 */
27
28#include "drmP.h"
29#include "sis_drm.h"
30#include "sis_drv.h"
31
32#include "drm_pciids.h"
33
34static struct pci_device_id pciidlist[] = {
35 sisdrv_PCI_IDS
36};
37
38static int sis_driver_load(struct drm_device *dev, unsigned long chipset)
39{
40 drm_sis_private_t *dev_priv;
41 int ret;
42
43 dev_priv = drm_calloc(1, sizeof(drm_sis_private_t), DRM_MEM_DRIVER);
44 if (dev_priv == NULL)
45 return -ENOMEM;
46
47 dev->dev_private = (void *)dev_priv;
48 dev_priv->chipset = chipset;
49 ret = drm_sman_init(&dev_priv->sman, 2, 12, 8);
50 if (ret) {
51 drm_free(dev_priv, sizeof(dev_priv), DRM_MEM_DRIVER);
52 }
53
54 return ret;
55}
56
57static int sis_driver_unload(struct drm_device *dev)
58{
59 drm_sis_private_t *dev_priv = dev->dev_private;
60
61 drm_sman_takedown(&dev_priv->sman);
62 drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER);
63
64 return 0;
65}
66
67static struct drm_driver driver = {
68 .driver_features = DRIVER_USE_AGP | DRIVER_USE_MTRR,
69 .load = sis_driver_load,
70 .unload = sis_driver_unload,
71 .context_dtor = NULL,
72 .dma_quiescent = sis_idle,
73 .reclaim_buffers = NULL,
74 .reclaim_buffers_idlelocked = sis_reclaim_buffers_locked,
75 .lastclose = sis_lastclose,
76 .get_map_ofs = drm_core_get_map_ofs,
77 .get_reg_ofs = drm_core_get_reg_ofs,
78 .ioctls = sis_ioctls,
79 .fops = {
80 .owner = THIS_MODULE,
81 .open = drm_open,
82 .release = drm_release,
83 .ioctl = drm_ioctl,
84 .mmap = drm_mmap,
85 .poll = drm_poll,
86 .fasync = drm_fasync,
87 },
88 .pci_driver = {
89 .name = DRIVER_NAME,
90 .id_table = pciidlist,
91 },
92
93 .name = DRIVER_NAME,
94 .desc = DRIVER_DESC,
95 .date = DRIVER_DATE,
96 .major = DRIVER_MAJOR,
97 .minor = DRIVER_MINOR,
98 .patchlevel = DRIVER_PATCHLEVEL,
99};
100
101static int __init sis_init(void)
102{
103 driver.num_ioctls = sis_max_ioctl;
104 return drm_init(&driver);
105}
106
107static void __exit sis_exit(void)
108{
109 drm_exit(&driver);
110}
111
112module_init(sis_init);
113module_exit(sis_exit);
114
115MODULE_AUTHOR(DRIVER_AUTHOR);
116MODULE_DESCRIPTION(DRIVER_DESC);
117MODULE_LICENSE("GPL and additional rights");
diff --git a/drivers/char/drm/sis_drv.h b/drivers/char/drm/sis_drv.h
deleted file mode 100644
index ef940bad63f7..000000000000
--- a/drivers/char/drm/sis_drv.h
+++ /dev/null
@@ -1,73 +0,0 @@
1/* sis_drv.h -- Private header for sis driver -*- linux-c -*- */
2/*
3 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
4 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
5 * All rights reserved.
6 *
7 * Permission is hereby granted, free of charge, to any person obtaining a
8 * copy of this software and associated documentation files (the "Software"),
9 * to deal in the Software without restriction, including without limitation
10 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
11 * and/or sell copies of the Software, and to permit persons to whom the
12 * Software is furnished to do so, subject to the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the next
15 * paragraph) shall be included in all copies or substantial portions of the
16 * Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
21 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
22 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
23 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
24 * DEALINGS IN THE SOFTWARE.
25 *
26 */
27
28#ifndef _SIS_DRV_H_
29#define _SIS_DRV_H_
30
31/* General customization:
32 */
33
34#define DRIVER_AUTHOR "SIS, Tungsten Graphics"
35#define DRIVER_NAME "sis"
36#define DRIVER_DESC "SIS 300/630/540 and XGI V3XE/V5/V8"
37#define DRIVER_DATE "20070626"
38#define DRIVER_MAJOR 1
39#define DRIVER_MINOR 3
40#define DRIVER_PATCHLEVEL 0
41
42enum sis_family {
43 SIS_OTHER = 0,
44 SIS_CHIP_315 = 1,
45};
46
47#include "drm_sman.h"
48
49
50#define SIS_BASE (dev_priv->mmio)
51#define SIS_READ(reg) DRM_READ32(SIS_BASE, reg);
52#define SIS_WRITE(reg, val) DRM_WRITE32(SIS_BASE, reg, val);
53
54typedef struct drm_sis_private {
55 drm_local_map_t *mmio;
56 unsigned int idle_fault;
57 struct drm_sman sman;
58 unsigned int chipset;
59 int vram_initialized;
60 int agp_initialized;
61 unsigned long vram_offset;
62 unsigned long agp_offset;
63} drm_sis_private_t;
64
65extern int sis_idle(struct drm_device *dev);
66extern void sis_reclaim_buffers_locked(struct drm_device *dev,
67 struct drm_file *file_priv);
68extern void sis_lastclose(struct drm_device *dev);
69
70extern struct drm_ioctl_desc sis_ioctls[];
71extern int sis_max_ioctl;
72
73#endif
diff --git a/drivers/char/drm/sis_mm.c b/drivers/char/drm/sis_mm.c
deleted file mode 100644
index b3878770fce1..000000000000
--- a/drivers/char/drm/sis_mm.c
+++ /dev/null
@@ -1,333 +0,0 @@
1/**************************************************************************
2 *
3 * Copyright 2006 Tungsten Graphics, Inc., Bismarck, ND., USA.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the
8 * "Software"), to deal in the Software without restriction, including
9 * without limitation the rights to use, copy, modify, merge, publish,
10 * distribute, sub license, and/or sell copies of the Software, and to
11 * permit persons to whom the Software is furnished to do so, subject to
12 * the following conditions:
13 *
14 * The above copyright notice and this permission notice (including the
15 * next paragraph) shall be included in all copies or substantial portions
16 * of the Software.
17 *
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
21 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
22 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
23 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
24 * USE OR OTHER DEALINGS IN THE SOFTWARE.
25 *
26 *
27 **************************************************************************/
28
29/*
30 * Authors:
31 * Thomas Hellström <thomas-at-tungstengraphics-dot-com>
32 */
33
34#include "drmP.h"
35#include "sis_drm.h"
36#include "sis_drv.h"
37
38#include <video/sisfb.h>
39
40#define VIDEO_TYPE 0
41#define AGP_TYPE 1
42
43
44#if defined(CONFIG_FB_SIS)
45/* fb management via fb device */
46
47#define SIS_MM_ALIGN_SHIFT 0
48#define SIS_MM_ALIGN_MASK 0
49
50static void *sis_sman_mm_allocate(void *private, unsigned long size,
51 unsigned alignment)
52{
53 struct sis_memreq req;
54
55 req.size = size;
56 sis_malloc(&req);
57 if (req.size == 0)
58 return NULL;
59 else
60 return (void *)~req.offset;
61}
62
63static void sis_sman_mm_free(void *private, void *ref)
64{
65 sis_free(~((unsigned long)ref));
66}
67
68static void sis_sman_mm_destroy(void *private)
69{
70 ;
71}
72
73static unsigned long sis_sman_mm_offset(void *private, void *ref)
74{
75 return ~((unsigned long)ref);
76}
77
78#else /* CONFIG_FB_SIS */
79
80#define SIS_MM_ALIGN_SHIFT 4
81#define SIS_MM_ALIGN_MASK ( (1 << SIS_MM_ALIGN_SHIFT) - 1)
82
83#endif /* CONFIG_FB_SIS */
84
85static int sis_fb_init(struct drm_device *dev, void *data, struct drm_file *file_priv)
86{
87 drm_sis_private_t *dev_priv = dev->dev_private;
88 drm_sis_fb_t *fb = data;
89 int ret;
90
91 mutex_lock(&dev->struct_mutex);
92#if defined(CONFIG_FB_SIS)
93 {
94 struct drm_sman_mm sman_mm;
95 sman_mm.private = (void *)0xFFFFFFFF;
96 sman_mm.allocate = sis_sman_mm_allocate;
97 sman_mm.free = sis_sman_mm_free;
98 sman_mm.destroy = sis_sman_mm_destroy;
99 sman_mm.offset = sis_sman_mm_offset;
100 ret =
101 drm_sman_set_manager(&dev_priv->sman, VIDEO_TYPE, &sman_mm);
102 }
103#else
104 ret = drm_sman_set_range(&dev_priv->sman, VIDEO_TYPE, 0,
105 fb->size >> SIS_MM_ALIGN_SHIFT);
106#endif
107
108 if (ret) {
109 DRM_ERROR("VRAM memory manager initialisation error\n");
110 mutex_unlock(&dev->struct_mutex);
111 return ret;
112 }
113
114 dev_priv->vram_initialized = 1;
115 dev_priv->vram_offset = fb->offset;
116
117 mutex_unlock(&dev->struct_mutex);
118 DRM_DEBUG("offset = %u, size = %u\n", fb->offset, fb->size);
119
120 return 0;
121}
122
123static int sis_drm_alloc(struct drm_device *dev, struct drm_file *file_priv,
124 void *data, int pool)
125{
126 drm_sis_private_t *dev_priv = dev->dev_private;
127 drm_sis_mem_t *mem = data;
128 int retval = 0;
129 struct drm_memblock_item *item;
130
131 mutex_lock(&dev->struct_mutex);
132
133 if (0 == ((pool == 0) ? dev_priv->vram_initialized :
134 dev_priv->agp_initialized)) {
135 DRM_ERROR
136 ("Attempt to allocate from uninitialized memory manager.\n");
137 mutex_unlock(&dev->struct_mutex);
138 return -EINVAL;
139 }
140
141 mem->size = (mem->size + SIS_MM_ALIGN_MASK) >> SIS_MM_ALIGN_SHIFT;
142 item = drm_sman_alloc(&dev_priv->sman, pool, mem->size, 0,
143 (unsigned long)file_priv);
144
145 mutex_unlock(&dev->struct_mutex);
146 if (item) {
147 mem->offset = ((pool == 0) ?
148 dev_priv->vram_offset : dev_priv->agp_offset) +
149 (item->mm->
150 offset(item->mm, item->mm_info) << SIS_MM_ALIGN_SHIFT);
151 mem->free = item->user_hash.key;
152 mem->size = mem->size << SIS_MM_ALIGN_SHIFT;
153 } else {
154 mem->offset = 0;
155 mem->size = 0;
156 mem->free = 0;
157 retval = -ENOMEM;
158 }
159
160 DRM_DEBUG("alloc %d, size = %d, offset = %d\n", pool, mem->size,
161 mem->offset);
162
163 return retval;
164}
165
166static int sis_drm_free(struct drm_device *dev, void *data, struct drm_file *file_priv)
167{
168 drm_sis_private_t *dev_priv = dev->dev_private;
169 drm_sis_mem_t *mem = data;
170 int ret;
171
172 mutex_lock(&dev->struct_mutex);
173 ret = drm_sman_free_key(&dev_priv->sman, mem->free);
174 mutex_unlock(&dev->struct_mutex);
175 DRM_DEBUG("free = 0x%lx\n", mem->free);
176
177 return ret;
178}
179
180static int sis_fb_alloc(struct drm_device *dev, void *data,
181 struct drm_file *file_priv)
182{
183 return sis_drm_alloc(dev, file_priv, data, VIDEO_TYPE);
184}
185
186static int sis_ioctl_agp_init(struct drm_device *dev, void *data,
187 struct drm_file *file_priv)
188{
189 drm_sis_private_t *dev_priv = dev->dev_private;
190 drm_sis_agp_t *agp = data;
191 int ret;
192 dev_priv = dev->dev_private;
193
194 mutex_lock(&dev->struct_mutex);
195 ret = drm_sman_set_range(&dev_priv->sman, AGP_TYPE, 0,
196 agp->size >> SIS_MM_ALIGN_SHIFT);
197
198 if (ret) {
199 DRM_ERROR("AGP memory manager initialisation error\n");
200 mutex_unlock(&dev->struct_mutex);
201 return ret;
202 }
203
204 dev_priv->agp_initialized = 1;
205 dev_priv->agp_offset = agp->offset;
206 mutex_unlock(&dev->struct_mutex);
207
208 DRM_DEBUG("offset = %u, size = %u\n", agp->offset, agp->size);
209 return 0;
210}
211
212static int sis_ioctl_agp_alloc(struct drm_device *dev, void *data,
213 struct drm_file *file_priv)
214{
215
216 return sis_drm_alloc(dev, file_priv, data, AGP_TYPE);
217}
218
219static drm_local_map_t *sis_reg_init(struct drm_device *dev)
220{
221 struct drm_map_list *entry;
222 drm_local_map_t *map;
223
224 list_for_each_entry(entry, &dev->maplist, head) {
225 map = entry->map;
226 if (!map)
227 continue;
228 if (map->type == _DRM_REGISTERS) {
229 return map;
230 }
231 }
232 return NULL;
233}
234
235int sis_idle(struct drm_device *dev)
236{
237 drm_sis_private_t *dev_priv = dev->dev_private;
238 uint32_t idle_reg;
239 unsigned long end;
240 int i;
241
242 if (dev_priv->idle_fault)
243 return 0;
244
245 if (dev_priv->mmio == NULL) {
246 dev_priv->mmio = sis_reg_init(dev);
247 if (dev_priv->mmio == NULL) {
248 DRM_ERROR("Could not find register map.\n");
249 return 0;
250 }
251 }
252
253 /*
254 * Implement a device switch here if needed
255 */
256
257 if (dev_priv->chipset != SIS_CHIP_315)
258 return 0;
259
260 /*
261 * Timeout after 3 seconds. We cannot use DRM_WAIT_ON here
262 * because its polling frequency is too low.
263 */
264
265 end = jiffies + (DRM_HZ * 3);
266
267 for (i=0; i<4; ++i) {
268 do {
269 idle_reg = SIS_READ(0x85cc);
270 } while ( !time_after_eq(jiffies, end) &&
271 ((idle_reg & 0x80000000) != 0x80000000));
272 }
273
274 if (time_after_eq(jiffies, end)) {
275 DRM_ERROR("Graphics engine idle timeout. "
276 "Disabling idle check\n");
277 dev_priv->idle_fault = 1;
278 }
279
280 /*
281 * The caller never sees an error code. It gets trapped
282 * in libdrm.
283 */
284
285 return 0;
286}
287
288
289void sis_lastclose(struct drm_device *dev)
290{
291 drm_sis_private_t *dev_priv = dev->dev_private;
292
293 if (!dev_priv)
294 return;
295
296 mutex_lock(&dev->struct_mutex);
297 drm_sman_cleanup(&dev_priv->sman);
298 dev_priv->vram_initialized = 0;
299 dev_priv->agp_initialized = 0;
300 dev_priv->mmio = NULL;
301 mutex_unlock(&dev->struct_mutex);
302}
303
304void sis_reclaim_buffers_locked(struct drm_device * dev,
305 struct drm_file *file_priv)
306{
307 drm_sis_private_t *dev_priv = dev->dev_private;
308
309 mutex_lock(&dev->struct_mutex);
310 if (drm_sman_owner_clean(&dev_priv->sman, (unsigned long)file_priv)) {
311 mutex_unlock(&dev->struct_mutex);
312 return;
313 }
314
315 if (dev->driver->dma_quiescent) {
316 dev->driver->dma_quiescent(dev);
317 }
318
319 drm_sman_owner_cleanup(&dev_priv->sman, (unsigned long)file_priv);
320 mutex_unlock(&dev->struct_mutex);
321 return;
322}
323
324struct drm_ioctl_desc sis_ioctls[] = {
325 DRM_IOCTL_DEF(DRM_SIS_FB_ALLOC, sis_fb_alloc, DRM_AUTH),
326 DRM_IOCTL_DEF(DRM_SIS_FB_FREE, sis_drm_free, DRM_AUTH),
327 DRM_IOCTL_DEF(DRM_SIS_AGP_INIT, sis_ioctl_agp_init, DRM_AUTH | DRM_MASTER | DRM_ROOT_ONLY),
328 DRM_IOCTL_DEF(DRM_SIS_AGP_ALLOC, sis_ioctl_agp_alloc, DRM_AUTH),
329 DRM_IOCTL_DEF(DRM_SIS_AGP_FREE, sis_drm_free, DRM_AUTH),
330 DRM_IOCTL_DEF(DRM_SIS_FB_INIT, sis_fb_init, DRM_AUTH | DRM_MASTER | DRM_ROOT_ONLY),
331};
332
333int sis_max_ioctl = DRM_ARRAY_SIZE(sis_ioctls);
diff --git a/drivers/char/drm/tdfx_drv.c b/drivers/char/drm/tdfx_drv.c
deleted file mode 100644
index 012ff2e356b2..000000000000
--- a/drivers/char/drm/tdfx_drv.c
+++ /dev/null
@@ -1,84 +0,0 @@
1/* tdfx_drv.c -- tdfx driver -*- linux-c -*-
2 * Created: Thu Oct 7 10:38:32 1999 by faith@precisioninsight.com
3 *
4 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
5 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
6 * All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice (including the next
16 * paragraph) shall be included in all copies or substantial portions of the
17 * Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
23 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
25 * DEALINGS IN THE SOFTWARE.
26 *
27 * Authors:
28 * Rickard E. (Rik) Faith <faith@valinux.com>
29 * Daryll Strauss <daryll@valinux.com>
30 * Gareth Hughes <gareth@valinux.com>
31 */
32
33#include "drmP.h"
34#include "tdfx_drv.h"
35
36#include "drm_pciids.h"
37
38static struct pci_device_id pciidlist[] = {
39 tdfx_PCI_IDS
40};
41
42static struct drm_driver driver = {
43 .driver_features = DRIVER_USE_MTRR,
44 .reclaim_buffers = drm_core_reclaim_buffers,
45 .get_map_ofs = drm_core_get_map_ofs,
46 .get_reg_ofs = drm_core_get_reg_ofs,
47 .fops = {
48 .owner = THIS_MODULE,
49 .open = drm_open,
50 .release = drm_release,
51 .ioctl = drm_ioctl,
52 .mmap = drm_mmap,
53 .poll = drm_poll,
54 .fasync = drm_fasync,
55 },
56 .pci_driver = {
57 .name = DRIVER_NAME,
58 .id_table = pciidlist,
59 },
60
61 .name = DRIVER_NAME,
62 .desc = DRIVER_DESC,
63 .date = DRIVER_DATE,
64 .major = DRIVER_MAJOR,
65 .minor = DRIVER_MINOR,
66 .patchlevel = DRIVER_PATCHLEVEL,
67};
68
69static int __init tdfx_init(void)
70{
71 return drm_init(&driver);
72}
73
74static void __exit tdfx_exit(void)
75{
76 drm_exit(&driver);
77}
78
79module_init(tdfx_init);
80module_exit(tdfx_exit);
81
82MODULE_AUTHOR(DRIVER_AUTHOR);
83MODULE_DESCRIPTION(DRIVER_DESC);
84MODULE_LICENSE("GPL and additional rights");
diff --git a/drivers/char/drm/tdfx_drv.h b/drivers/char/drm/tdfx_drv.h
deleted file mode 100644
index 84204ec1b046..000000000000
--- a/drivers/char/drm/tdfx_drv.h
+++ /dev/null
@@ -1,47 +0,0 @@
1/* tdfx.h -- 3dfx DRM template customization -*- linux-c -*-
2 * Created: Wed Feb 14 12:32:32 2001 by gareth@valinux.com
3 */
4/*
5 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
6 * All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice (including the next
16 * paragraph) shall be included in all copies or substantial portions of the
17 * Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
23 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25 * OTHER DEALINGS IN THE SOFTWARE.
26 *
27 * Authors:
28 * Gareth Hughes <gareth@valinux.com>
29 */
30
31#ifndef __TDFX_H__
32#define __TDFX_H__
33
34/* General customization:
35 */
36
37#define DRIVER_AUTHOR "VA Linux Systems Inc."
38
39#define DRIVER_NAME "tdfx"
40#define DRIVER_DESC "3dfx Banshee/Voodoo3+"
41#define DRIVER_DATE "20010216"
42
43#define DRIVER_MAJOR 1
44#define DRIVER_MINOR 0
45#define DRIVER_PATCHLEVEL 0
46
47#endif
diff --git a/drivers/char/drm/via_3d_reg.h b/drivers/char/drm/via_3d_reg.h
deleted file mode 100644
index 462375d543b9..000000000000
--- a/drivers/char/drm/via_3d_reg.h
+++ /dev/null
@@ -1,1650 +0,0 @@
1/*
2 * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sub license,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
14 * of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25#ifndef VIA_3D_REG_H
26#define VIA_3D_REG_H
27#define HC_REG_BASE 0x0400
28
29#define HC_REG_TRANS_SPACE 0x0040
30
31#define HC_ParaN_MASK 0xffffffff
32#define HC_Para_MASK 0x00ffffff
33#define HC_SubA_MASK 0xff000000
34#define HC_SubA_SHIFT 24
35/* Transmission Setting
36 */
37#define HC_REG_TRANS_SET 0x003c
38#define HC_ParaSubType_MASK 0xff000000
39#define HC_ParaType_MASK 0x00ff0000
40#define HC_ParaOS_MASK 0x0000ff00
41#define HC_ParaAdr_MASK 0x000000ff
42#define HC_ParaSubType_SHIFT 24
43#define HC_ParaType_SHIFT 16
44#define HC_ParaOS_SHIFT 8
45#define HC_ParaAdr_SHIFT 0
46
47#define HC_ParaType_CmdVdata 0x0000
48#define HC_ParaType_NotTex 0x0001
49#define HC_ParaType_Tex 0x0002
50#define HC_ParaType_Palette 0x0003
51#define HC_ParaType_PreCR 0x0010
52#define HC_ParaType_Auto 0x00fe
53
54/* Transmission Space
55 */
56#define HC_REG_Hpara0 0x0040
57#define HC_REG_HpataAF 0x02fc
58
59/* Read
60 */
61#define HC_REG_HREngSt 0x0000
62#define HC_REG_HRFIFOempty 0x0004
63#define HC_REG_HRFIFOfull 0x0008
64#define HC_REG_HRErr 0x000c
65#define HC_REG_FIFOstatus 0x0010
66/* HC_REG_HREngSt 0x0000
67 */
68#define HC_HDASZC_MASK 0x00010000
69#define HC_HSGEMI_MASK 0x0000f000
70#define HC_HLGEMISt_MASK 0x00000f00
71#define HC_HCRSt_MASK 0x00000080
72#define HC_HSE0St_MASK 0x00000040
73#define HC_HSE1St_MASK 0x00000020
74#define HC_HPESt_MASK 0x00000010
75#define HC_HXESt_MASK 0x00000008
76#define HC_HBESt_MASK 0x00000004
77#define HC_HE2St_MASK 0x00000002
78#define HC_HE3St_MASK 0x00000001
79/* HC_REG_HRFIFOempty 0x0004
80 */
81#define HC_HRZDempty_MASK 0x00000010
82#define HC_HRTXAempty_MASK 0x00000008
83#define HC_HRTXDempty_MASK 0x00000004
84#define HC_HWZDempty_MASK 0x00000002
85#define HC_HWCDempty_MASK 0x00000001
86/* HC_REG_HRFIFOfull 0x0008
87 */
88#define HC_HRZDfull_MASK 0x00000010
89#define HC_HRTXAfull_MASK 0x00000008
90#define HC_HRTXDfull_MASK 0x00000004
91#define HC_HWZDfull_MASK 0x00000002
92#define HC_HWCDfull_MASK 0x00000001
93/* HC_REG_HRErr 0x000c
94 */
95#define HC_HAGPCMErr_MASK 0x80000000
96#define HC_HAGPCMErrC_MASK 0x70000000
97/* HC_REG_FIFOstatus 0x0010
98 */
99#define HC_HRFIFOATall_MASK 0x80000000
100#define HC_HRFIFOATbusy_MASK 0x40000000
101#define HC_HRATFGMDo_MASK 0x00000100
102#define HC_HRATFGMDi_MASK 0x00000080
103#define HC_HRATFRZD_MASK 0x00000040
104#define HC_HRATFRTXA_MASK 0x00000020
105#define HC_HRATFRTXD_MASK 0x00000010
106#define HC_HRATFWZD_MASK 0x00000008
107#define HC_HRATFWCD_MASK 0x00000004
108#define HC_HRATTXTAG_MASK 0x00000002
109#define HC_HRATTXCH_MASK 0x00000001
110
111/* AGP Command Setting
112 */
113#define HC_SubA_HAGPBstL 0x0060
114#define HC_SubA_HAGPBendL 0x0061
115#define HC_SubA_HAGPCMNT 0x0062
116#define HC_SubA_HAGPBpL 0x0063
117#define HC_SubA_HAGPBpH 0x0064
118/* HC_SubA_HAGPCMNT 0x0062
119 */
120#define HC_HAGPCMNT_MASK 0x00800000
121#define HC_HCmdErrClr_MASK 0x00400000
122#define HC_HAGPBendH_MASK 0x0000ff00
123#define HC_HAGPBstH_MASK 0x000000ff
124#define HC_HAGPBendH_SHIFT 8
125#define HC_HAGPBstH_SHIFT 0
126/* HC_SubA_HAGPBpL 0x0063
127 */
128#define HC_HAGPBpL_MASK 0x00fffffc
129#define HC_HAGPBpID_MASK 0x00000003
130#define HC_HAGPBpID_PAUSE 0x00000000
131#define HC_HAGPBpID_JUMP 0x00000001
132#define HC_HAGPBpID_STOP 0x00000002
133/* HC_SubA_HAGPBpH 0x0064
134 */
135#define HC_HAGPBpH_MASK 0x00ffffff
136
137/* Miscellaneous Settings
138 */
139#define HC_SubA_HClipTB 0x0070
140#define HC_SubA_HClipLR 0x0071
141#define HC_SubA_HFPClipTL 0x0072
142#define HC_SubA_HFPClipBL 0x0073
143#define HC_SubA_HFPClipLL 0x0074
144#define HC_SubA_HFPClipRL 0x0075
145#define HC_SubA_HFPClipTBH 0x0076
146#define HC_SubA_HFPClipLRH 0x0077
147#define HC_SubA_HLP 0x0078
148#define HC_SubA_HLPRF 0x0079
149#define HC_SubA_HSolidCL 0x007a
150#define HC_SubA_HPixGC 0x007b
151#define HC_SubA_HSPXYOS 0x007c
152#define HC_SubA_HVertexCNT 0x007d
153
154#define HC_HClipT_MASK 0x00fff000
155#define HC_HClipT_SHIFT 12
156#define HC_HClipB_MASK 0x00000fff
157#define HC_HClipB_SHIFT 0
158#define HC_HClipL_MASK 0x00fff000
159#define HC_HClipL_SHIFT 12
160#define HC_HClipR_MASK 0x00000fff
161#define HC_HClipR_SHIFT 0
162#define HC_HFPClipBH_MASK 0x0000ff00
163#define HC_HFPClipBH_SHIFT 8
164#define HC_HFPClipTH_MASK 0x000000ff
165#define HC_HFPClipTH_SHIFT 0
166#define HC_HFPClipRH_MASK 0x0000ff00
167#define HC_HFPClipRH_SHIFT 8
168#define HC_HFPClipLH_MASK 0x000000ff
169#define HC_HFPClipLH_SHIFT 0
170#define HC_HSolidCH_MASK 0x000000ff
171#define HC_HPixGC_MASK 0x00800000
172#define HC_HSPXOS_MASK 0x00fff000
173#define HC_HSPXOS_SHIFT 12
174#define HC_HSPYOS_MASK 0x00000fff
175
176/* Command
177 * Command A
178 */
179#define HC_HCmdHeader_MASK 0xfe000000 /*0xffe00000 */
180#define HC_HE3Fire_MASK 0x00100000
181#define HC_HPMType_MASK 0x000f0000
182#define HC_HEFlag_MASK 0x0000e000
183#define HC_HShading_MASK 0x00001c00
184#define HC_HPMValidN_MASK 0x00000200
185#define HC_HPLEND_MASK 0x00000100
186#define HC_HVCycle_MASK 0x000000ff
187#define HC_HVCycle_Style_MASK 0x000000c0
188#define HC_HVCycle_ChgA_MASK 0x00000030
189#define HC_HVCycle_ChgB_MASK 0x0000000c
190#define HC_HVCycle_ChgC_MASK 0x00000003
191#define HC_HPMType_Point 0x00000000
192#define HC_HPMType_Line 0x00010000
193#define HC_HPMType_Tri 0x00020000
194#define HC_HPMType_TriWF 0x00040000
195#define HC_HEFlag_NoAA 0x00000000
196#define HC_HEFlag_ab 0x00008000
197#define HC_HEFlag_bc 0x00004000
198#define HC_HEFlag_ca 0x00002000
199#define HC_HShading_Solid 0x00000000
200#define HC_HShading_FlatA 0x00000400
201#define HC_HShading_FlatB 0x00000800
202#define HC_HShading_FlatC 0x00000c00
203#define HC_HShading_Gouraud 0x00001000
204#define HC_HVCycle_Full 0x00000000
205#define HC_HVCycle_AFP 0x00000040
206#define HC_HVCycle_One 0x000000c0
207#define HC_HVCycle_NewA 0x00000000
208#define HC_HVCycle_AA 0x00000010
209#define HC_HVCycle_AB 0x00000020
210#define HC_HVCycle_AC 0x00000030
211#define HC_HVCycle_NewB 0x00000000
212#define HC_HVCycle_BA 0x00000004
213#define HC_HVCycle_BB 0x00000008
214#define HC_HVCycle_BC 0x0000000c
215#define HC_HVCycle_NewC 0x00000000
216#define HC_HVCycle_CA 0x00000001
217#define HC_HVCycle_CB 0x00000002
218#define HC_HVCycle_CC 0x00000003
219
220/* Command B
221 */
222#define HC_HLPrst_MASK 0x00010000
223#define HC_HLLastP_MASK 0x00008000
224#define HC_HVPMSK_MASK 0x00007f80
225#define HC_HBFace_MASK 0x00000040
226#define HC_H2nd1VT_MASK 0x0000003f
227#define HC_HVPMSK_X 0x00004000
228#define HC_HVPMSK_Y 0x00002000
229#define HC_HVPMSK_Z 0x00001000
230#define HC_HVPMSK_W 0x00000800
231#define HC_HVPMSK_Cd 0x00000400
232#define HC_HVPMSK_Cs 0x00000200
233#define HC_HVPMSK_S 0x00000100
234#define HC_HVPMSK_T 0x00000080
235
236/* Enable Setting
237 */
238#define HC_SubA_HEnable 0x0000
239#define HC_HenTXEnvMap_MASK 0x00200000
240#define HC_HenVertexCNT_MASK 0x00100000
241#define HC_HenCPUDAZ_MASK 0x00080000
242#define HC_HenDASZWC_MASK 0x00040000
243#define HC_HenFBCull_MASK 0x00020000
244#define HC_HenCW_MASK 0x00010000
245#define HC_HenAA_MASK 0x00008000
246#define HC_HenST_MASK 0x00004000
247#define HC_HenZT_MASK 0x00002000
248#define HC_HenZW_MASK 0x00001000
249#define HC_HenAT_MASK 0x00000800
250#define HC_HenAW_MASK 0x00000400
251#define HC_HenSP_MASK 0x00000200
252#define HC_HenLP_MASK 0x00000100
253#define HC_HenTXCH_MASK 0x00000080
254#define HC_HenTXMP_MASK 0x00000040
255#define HC_HenTXPP_MASK 0x00000020
256#define HC_HenTXTR_MASK 0x00000010
257#define HC_HenCS_MASK 0x00000008
258#define HC_HenFOG_MASK 0x00000004
259#define HC_HenABL_MASK 0x00000002
260#define HC_HenDT_MASK 0x00000001
261
262/* Z Setting
263 */
264#define HC_SubA_HZWBBasL 0x0010
265#define HC_SubA_HZWBBasH 0x0011
266#define HC_SubA_HZWBType 0x0012
267#define HC_SubA_HZBiasL 0x0013
268#define HC_SubA_HZWBend 0x0014
269#define HC_SubA_HZWTMD 0x0015
270#define HC_SubA_HZWCDL 0x0016
271#define HC_SubA_HZWCTAGnum 0x0017
272#define HC_SubA_HZCYNum 0x0018
273#define HC_SubA_HZWCFire 0x0019
274/* HC_SubA_HZWBType
275 */
276#define HC_HZWBType_MASK 0x00800000
277#define HC_HZBiasedWB_MASK 0x00400000
278#define HC_HZONEasFF_MASK 0x00200000
279#define HC_HZOONEasFF_MASK 0x00100000
280#define HC_HZWBFM_MASK 0x00030000
281#define HC_HZWBLoc_MASK 0x0000c000
282#define HC_HZWBPit_MASK 0x00003fff
283#define HC_HZWBFM_16 0x00000000
284#define HC_HZWBFM_32 0x00020000
285#define HC_HZWBFM_24 0x00030000
286#define HC_HZWBLoc_Local 0x00000000
287#define HC_HZWBLoc_SyS 0x00004000
288/* HC_SubA_HZWBend
289 */
290#define HC_HZWBend_MASK 0x00ffe000
291#define HC_HZBiasH_MASK 0x000000ff
292#define HC_HZWBend_SHIFT 10
293/* HC_SubA_HZWTMD
294 */
295#define HC_HZWTMD_MASK 0x00070000
296#define HC_HEBEBias_MASK 0x00007f00
297#define HC_HZNF_MASK 0x000000ff
298#define HC_HZWTMD_NeverPass 0x00000000
299#define HC_HZWTMD_LT 0x00010000
300#define HC_HZWTMD_EQ 0x00020000
301#define HC_HZWTMD_LE 0x00030000
302#define HC_HZWTMD_GT 0x00040000
303#define HC_HZWTMD_NE 0x00050000
304#define HC_HZWTMD_GE 0x00060000
305#define HC_HZWTMD_AllPass 0x00070000
306#define HC_HEBEBias_SHIFT 8
307/* HC_SubA_HZWCDL 0x0016
308 */
309#define HC_HZWCDL_MASK 0x00ffffff
310/* HC_SubA_HZWCTAGnum 0x0017
311 */
312#define HC_HZWCTAGnum_MASK 0x00ff0000
313#define HC_HZWCTAGnum_SHIFT 16
314#define HC_HZWCDH_MASK 0x000000ff
315#define HC_HZWCDH_SHIFT 0
316/* HC_SubA_HZCYNum 0x0018
317 */
318#define HC_HZCYNum_MASK 0x00030000
319#define HC_HZCYNum_SHIFT 16
320#define HC_HZWCQWnum_MASK 0x00003fff
321#define HC_HZWCQWnum_SHIFT 0
322/* HC_SubA_HZWCFire 0x0019
323 */
324#define HC_ZWCFire_MASK 0x00010000
325#define HC_HZWCQWnumLast_MASK 0x00003fff
326#define HC_HZWCQWnumLast_SHIFT 0
327
328/* Stencil Setting
329 */
330#define HC_SubA_HSTREF 0x0023
331#define HC_SubA_HSTMD 0x0024
332/* HC_SubA_HSBFM
333 */
334#define HC_HSBFM_MASK 0x00030000
335#define HC_HSBLoc_MASK 0x0000c000
336#define HC_HSBPit_MASK 0x00003fff
337/* HC_SubA_HSTREF
338 */
339#define HC_HSTREF_MASK 0x00ff0000
340#define HC_HSTOPMSK_MASK 0x0000ff00
341#define HC_HSTBMSK_MASK 0x000000ff
342#define HC_HSTREF_SHIFT 16
343#define HC_HSTOPMSK_SHIFT 8
344/* HC_SubA_HSTMD
345 */
346#define HC_HSTMD_MASK 0x00070000
347#define HC_HSTOPSF_MASK 0x000001c0
348#define HC_HSTOPSPZF_MASK 0x00000038
349#define HC_HSTOPSPZP_MASK 0x00000007
350#define HC_HSTMD_NeverPass 0x00000000
351#define HC_HSTMD_LT 0x00010000
352#define HC_HSTMD_EQ 0x00020000
353#define HC_HSTMD_LE 0x00030000
354#define HC_HSTMD_GT 0x00040000
355#define HC_HSTMD_NE 0x00050000
356#define HC_HSTMD_GE 0x00060000
357#define HC_HSTMD_AllPass 0x00070000
358#define HC_HSTOPSF_KEEP 0x00000000
359#define HC_HSTOPSF_ZERO 0x00000040
360#define HC_HSTOPSF_REPLACE 0x00000080
361#define HC_HSTOPSF_INCRSAT 0x000000c0
362#define HC_HSTOPSF_DECRSAT 0x00000100
363#define HC_HSTOPSF_INVERT 0x00000140
364#define HC_HSTOPSF_INCR 0x00000180
365#define HC_HSTOPSF_DECR 0x000001c0
366#define HC_HSTOPSPZF_KEEP 0x00000000
367#define HC_HSTOPSPZF_ZERO 0x00000008
368#define HC_HSTOPSPZF_REPLACE 0x00000010
369#define HC_HSTOPSPZF_INCRSAT 0x00000018
370#define HC_HSTOPSPZF_DECRSAT 0x00000020
371#define HC_HSTOPSPZF_INVERT 0x00000028
372#define HC_HSTOPSPZF_INCR 0x00000030
373#define HC_HSTOPSPZF_DECR 0x00000038
374#define HC_HSTOPSPZP_KEEP 0x00000000
375#define HC_HSTOPSPZP_ZERO 0x00000001
376#define HC_HSTOPSPZP_REPLACE 0x00000002
377#define HC_HSTOPSPZP_INCRSAT 0x00000003
378#define HC_HSTOPSPZP_DECRSAT 0x00000004
379#define HC_HSTOPSPZP_INVERT 0x00000005
380#define HC_HSTOPSPZP_INCR 0x00000006
381#define HC_HSTOPSPZP_DECR 0x00000007
382
383/* Alpha Setting
384 */
385#define HC_SubA_HABBasL 0x0030
386#define HC_SubA_HABBasH 0x0031
387#define HC_SubA_HABFM 0x0032
388#define HC_SubA_HATMD 0x0033
389#define HC_SubA_HABLCsat 0x0034
390#define HC_SubA_HABLCop 0x0035
391#define HC_SubA_HABLAsat 0x0036
392#define HC_SubA_HABLAop 0x0037
393#define HC_SubA_HABLRCa 0x0038
394#define HC_SubA_HABLRFCa 0x0039
395#define HC_SubA_HABLRCbias 0x003a
396#define HC_SubA_HABLRCb 0x003b
397#define HC_SubA_HABLRFCb 0x003c
398#define HC_SubA_HABLRAa 0x003d
399#define HC_SubA_HABLRAb 0x003e
400/* HC_SubA_HABFM
401 */
402#define HC_HABFM_MASK 0x00030000
403#define HC_HABLoc_MASK 0x0000c000
404#define HC_HABPit_MASK 0x000007ff
405/* HC_SubA_HATMD
406 */
407#define HC_HATMD_MASK 0x00000700
408#define HC_HATREF_MASK 0x000000ff
409#define HC_HATMD_NeverPass 0x00000000
410#define HC_HATMD_LT 0x00000100
411#define HC_HATMD_EQ 0x00000200
412#define HC_HATMD_LE 0x00000300
413#define HC_HATMD_GT 0x00000400
414#define HC_HATMD_NE 0x00000500
415#define HC_HATMD_GE 0x00000600
416#define HC_HATMD_AllPass 0x00000700
417/* HC_SubA_HABLCsat
418 */
419#define HC_HABLCsat_MASK 0x00010000
420#define HC_HABLCa_MASK 0x0000fc00
421#define HC_HABLCa_C_MASK 0x0000c000
422#define HC_HABLCa_OPC_MASK 0x00003c00
423#define HC_HABLFCa_MASK 0x000003f0
424#define HC_HABLFCa_C_MASK 0x00000300
425#define HC_HABLFCa_OPC_MASK 0x000000f0
426#define HC_HABLCbias_MASK 0x0000000f
427#define HC_HABLCbias_C_MASK 0x00000008
428#define HC_HABLCbias_OPC_MASK 0x00000007
429/*-- Define the input color.
430 */
431#define HC_XC_Csrc 0x00000000
432#define HC_XC_Cdst 0x00000001
433#define HC_XC_Asrc 0x00000002
434#define HC_XC_Adst 0x00000003
435#define HC_XC_Fog 0x00000004
436#define HC_XC_HABLRC 0x00000005
437#define HC_XC_minSrcDst 0x00000006
438#define HC_XC_maxSrcDst 0x00000007
439#define HC_XC_mimAsrcInvAdst 0x00000008
440#define HC_XC_OPC 0x00000000
441#define HC_XC_InvOPC 0x00000010
442#define HC_XC_OPCp5 0x00000020
443/*-- Define the input Alpha
444 */
445#define HC_XA_OPA 0x00000000
446#define HC_XA_InvOPA 0x00000010
447#define HC_XA_OPAp5 0x00000020
448#define HC_XA_0 0x00000000
449#define HC_XA_Asrc 0x00000001
450#define HC_XA_Adst 0x00000002
451#define HC_XA_Fog 0x00000003
452#define HC_XA_minAsrcFog 0x00000004
453#define HC_XA_minAsrcAdst 0x00000005
454#define HC_XA_maxAsrcFog 0x00000006
455#define HC_XA_maxAsrcAdst 0x00000007
456#define HC_XA_HABLRA 0x00000008
457#define HC_XA_minAsrcInvAdst 0x00000008
458#define HC_XA_HABLFRA 0x00000009
459/*--
460 */
461#define HC_HABLCa_OPC (HC_XC_OPC << 10)
462#define HC_HABLCa_InvOPC (HC_XC_InvOPC << 10)
463#define HC_HABLCa_OPCp5 (HC_XC_OPCp5 << 10)
464#define HC_HABLCa_Csrc (HC_XC_Csrc << 10)
465#define HC_HABLCa_Cdst (HC_XC_Cdst << 10)
466#define HC_HABLCa_Asrc (HC_XC_Asrc << 10)
467#define HC_HABLCa_Adst (HC_XC_Adst << 10)
468#define HC_HABLCa_Fog (HC_XC_Fog << 10)
469#define HC_HABLCa_HABLRCa (HC_XC_HABLRC << 10)
470#define HC_HABLCa_minSrcDst (HC_XC_minSrcDst << 10)
471#define HC_HABLCa_maxSrcDst (HC_XC_maxSrcDst << 10)
472#define HC_HABLFCa_OPC (HC_XC_OPC << 4)
473#define HC_HABLFCa_InvOPC (HC_XC_InvOPC << 4)
474#define HC_HABLFCa_OPCp5 (HC_XC_OPCp5 << 4)
475#define HC_HABLFCa_Csrc (HC_XC_Csrc << 4)
476#define HC_HABLFCa_Cdst (HC_XC_Cdst << 4)
477#define HC_HABLFCa_Asrc (HC_XC_Asrc << 4)
478#define HC_HABLFCa_Adst (HC_XC_Adst << 4)
479#define HC_HABLFCa_Fog (HC_XC_Fog << 4)
480#define HC_HABLFCa_HABLRCa (HC_XC_HABLRC << 4)
481#define HC_HABLFCa_minSrcDst (HC_XC_minSrcDst << 4)
482#define HC_HABLFCa_maxSrcDst (HC_XC_maxSrcDst << 4)
483#define HC_HABLFCa_mimAsrcInvAdst (HC_XC_mimAsrcInvAdst << 4)
484#define HC_HABLCbias_HABLRCbias 0x00000000
485#define HC_HABLCbias_Asrc 0x00000001
486#define HC_HABLCbias_Adst 0x00000002
487#define HC_HABLCbias_Fog 0x00000003
488#define HC_HABLCbias_Cin 0x00000004
489/* HC_SubA_HABLCop 0x0035
490 */
491#define HC_HABLdot_MASK 0x00010000
492#define HC_HABLCop_MASK 0x00004000
493#define HC_HABLCb_MASK 0x00003f00
494#define HC_HABLCb_C_MASK 0x00003000
495#define HC_HABLCb_OPC_MASK 0x00000f00
496#define HC_HABLFCb_MASK 0x000000fc
497#define HC_HABLFCb_C_MASK 0x000000c0
498#define HC_HABLFCb_OPC_MASK 0x0000003c
499#define HC_HABLCshift_MASK 0x00000003
500#define HC_HABLCb_OPC (HC_XC_OPC << 8)
501#define HC_HABLCb_InvOPC (HC_XC_InvOPC << 8)
502#define HC_HABLCb_OPCp5 (HC_XC_OPCp5 << 8)
503#define HC_HABLCb_Csrc (HC_XC_Csrc << 8)
504#define HC_HABLCb_Cdst (HC_XC_Cdst << 8)
505#define HC_HABLCb_Asrc (HC_XC_Asrc << 8)
506#define HC_HABLCb_Adst (HC_XC_Adst << 8)
507#define HC_HABLCb_Fog (HC_XC_Fog << 8)
508#define HC_HABLCb_HABLRCa (HC_XC_HABLRC << 8)
509#define HC_HABLCb_minSrcDst (HC_XC_minSrcDst << 8)
510#define HC_HABLCb_maxSrcDst (HC_XC_maxSrcDst << 8)
511#define HC_HABLFCb_OPC (HC_XC_OPC << 2)
512#define HC_HABLFCb_InvOPC (HC_XC_InvOPC << 2)
513#define HC_HABLFCb_OPCp5 (HC_XC_OPCp5 << 2)
514#define HC_HABLFCb_Csrc (HC_XC_Csrc << 2)
515#define HC_HABLFCb_Cdst (HC_XC_Cdst << 2)
516#define HC_HABLFCb_Asrc (HC_XC_Asrc << 2)
517#define HC_HABLFCb_Adst (HC_XC_Adst << 2)
518#define HC_HABLFCb_Fog (HC_XC_Fog << 2)
519#define HC_HABLFCb_HABLRCb (HC_XC_HABLRC << 2)
520#define HC_HABLFCb_minSrcDst (HC_XC_minSrcDst << 2)
521#define HC_HABLFCb_maxSrcDst (HC_XC_maxSrcDst << 2)
522#define HC_HABLFCb_mimAsrcInvAdst (HC_XC_mimAsrcInvAdst << 2)
523/* HC_SubA_HABLAsat 0x0036
524 */
525#define HC_HABLAsat_MASK 0x00010000
526#define HC_HABLAa_MASK 0x0000fc00
527#define HC_HABLAa_A_MASK 0x0000c000
528#define HC_HABLAa_OPA_MASK 0x00003c00
529#define HC_HABLFAa_MASK 0x000003f0
530#define HC_HABLFAa_A_MASK 0x00000300
531#define HC_HABLFAa_OPA_MASK 0x000000f0
532#define HC_HABLAbias_MASK 0x0000000f
533#define HC_HABLAbias_A_MASK 0x00000008
534#define HC_HABLAbias_OPA_MASK 0x00000007
535#define HC_HABLAa_OPA (HC_XA_OPA << 10)
536#define HC_HABLAa_InvOPA (HC_XA_InvOPA << 10)
537#define HC_HABLAa_OPAp5 (HC_XA_OPAp5 << 10)
538#define HC_HABLAa_0 (HC_XA_0 << 10)
539#define HC_HABLAa_Asrc (HC_XA_Asrc << 10)
540#define HC_HABLAa_Adst (HC_XA_Adst << 10)
541#define HC_HABLAa_Fog (HC_XA_Fog << 10)
542#define HC_HABLAa_minAsrcFog (HC_XA_minAsrcFog << 10)
543#define HC_HABLAa_minAsrcAdst (HC_XA_minAsrcAdst << 10)
544#define HC_HABLAa_maxAsrcFog (HC_XA_maxAsrcFog << 10)
545#define HC_HABLAa_maxAsrcAdst (HC_XA_maxAsrcAdst << 10)
546#define HC_HABLAa_HABLRA (HC_XA_HABLRA << 10)
547#define HC_HABLFAa_OPA (HC_XA_OPA << 4)
548#define HC_HABLFAa_InvOPA (HC_XA_InvOPA << 4)
549#define HC_HABLFAa_OPAp5 (HC_XA_OPAp5 << 4)
550#define HC_HABLFAa_0 (HC_XA_0 << 4)
551#define HC_HABLFAa_Asrc (HC_XA_Asrc << 4)
552#define HC_HABLFAa_Adst (HC_XA_Adst << 4)
553#define HC_HABLFAa_Fog (HC_XA_Fog << 4)
554#define HC_HABLFAa_minAsrcFog (HC_XA_minAsrcFog << 4)
555#define HC_HABLFAa_minAsrcAdst (HC_XA_minAsrcAdst << 4)
556#define HC_HABLFAa_maxAsrcFog (HC_XA_maxAsrcFog << 4)
557#define HC_HABLFAa_maxAsrcAdst (HC_XA_maxAsrcAdst << 4)
558#define HC_HABLFAa_minAsrcInvAdst (HC_XA_minAsrcInvAdst << 4)
559#define HC_HABLFAa_HABLFRA (HC_XA_HABLFRA << 4)
560#define HC_HABLAbias_HABLRAbias 0x00000000
561#define HC_HABLAbias_Asrc 0x00000001
562#define HC_HABLAbias_Adst 0x00000002
563#define HC_HABLAbias_Fog 0x00000003
564#define HC_HABLAbias_Aaa 0x00000004
565/* HC_SubA_HABLAop 0x0037
566 */
567#define HC_HABLAop_MASK 0x00004000
568#define HC_HABLAb_MASK 0x00003f00
569#define HC_HABLAb_OPA_MASK 0x00000f00
570#define HC_HABLFAb_MASK 0x000000fc
571#define HC_HABLFAb_OPA_MASK 0x0000003c
572#define HC_HABLAshift_MASK 0x00000003
573#define HC_HABLAb_OPA (HC_XA_OPA << 8)
574#define HC_HABLAb_InvOPA (HC_XA_InvOPA << 8)
575#define HC_HABLAb_OPAp5 (HC_XA_OPAp5 << 8)
576#define HC_HABLAb_0 (HC_XA_0 << 8)
577#define HC_HABLAb_Asrc (HC_XA_Asrc << 8)
578#define HC_HABLAb_Adst (HC_XA_Adst << 8)
579#define HC_HABLAb_Fog (HC_XA_Fog << 8)
580#define HC_HABLAb_minAsrcFog (HC_XA_minAsrcFog << 8)
581#define HC_HABLAb_minAsrcAdst (HC_XA_minAsrcAdst << 8)
582#define HC_HABLAb_maxAsrcFog (HC_XA_maxAsrcFog << 8)
583#define HC_HABLAb_maxAsrcAdst (HC_XA_maxAsrcAdst << 8)
584#define HC_HABLAb_HABLRA (HC_XA_HABLRA << 8)
585#define HC_HABLFAb_OPA (HC_XA_OPA << 2)
586#define HC_HABLFAb_InvOPA (HC_XA_InvOPA << 2)
587#define HC_HABLFAb_OPAp5 (HC_XA_OPAp5 << 2)
588#define HC_HABLFAb_0 (HC_XA_0 << 2)
589#define HC_HABLFAb_Asrc (HC_XA_Asrc << 2)
590#define HC_HABLFAb_Adst (HC_XA_Adst << 2)
591#define HC_HABLFAb_Fog (HC_XA_Fog << 2)
592#define HC_HABLFAb_minAsrcFog (HC_XA_minAsrcFog << 2)
593#define HC_HABLFAb_minAsrcAdst (HC_XA_minAsrcAdst << 2)
594#define HC_HABLFAb_maxAsrcFog (HC_XA_maxAsrcFog << 2)
595#define HC_HABLFAb_maxAsrcAdst (HC_XA_maxAsrcAdst << 2)
596#define HC_HABLFAb_minAsrcInvAdst (HC_XA_minAsrcInvAdst << 2)
597#define HC_HABLFAb_HABLFRA (HC_XA_HABLFRA << 2)
598/* HC_SubA_HABLRAa 0x003d
599 */
600#define HC_HABLRAa_MASK 0x00ff0000
601#define HC_HABLRFAa_MASK 0x0000ff00
602#define HC_HABLRAbias_MASK 0x000000ff
603#define HC_HABLRAa_SHIFT 16
604#define HC_HABLRFAa_SHIFT 8
605/* HC_SubA_HABLRAb 0x003e
606 */
607#define HC_HABLRAb_MASK 0x0000ff00
608#define HC_HABLRFAb_MASK 0x000000ff
609#define HC_HABLRAb_SHIFT 8
610
611/* Destination Setting
612 */
613#define HC_SubA_HDBBasL 0x0040
614#define HC_SubA_HDBBasH 0x0041
615#define HC_SubA_HDBFM 0x0042
616#define HC_SubA_HFBBMSKL 0x0043
617#define HC_SubA_HROP 0x0044
618/* HC_SubA_HDBFM 0x0042
619 */
620#define HC_HDBFM_MASK 0x001f0000
621#define HC_HDBLoc_MASK 0x0000c000
622#define HC_HDBPit_MASK 0x00003fff
623#define HC_HDBFM_RGB555 0x00000000
624#define HC_HDBFM_RGB565 0x00010000
625#define HC_HDBFM_ARGB4444 0x00020000
626#define HC_HDBFM_ARGB1555 0x00030000
627#define HC_HDBFM_BGR555 0x00040000
628#define HC_HDBFM_BGR565 0x00050000
629#define HC_HDBFM_ABGR4444 0x00060000
630#define HC_HDBFM_ABGR1555 0x00070000
631#define HC_HDBFM_ARGB0888 0x00080000
632#define HC_HDBFM_ARGB8888 0x00090000
633#define HC_HDBFM_ABGR0888 0x000a0000
634#define HC_HDBFM_ABGR8888 0x000b0000
635#define HC_HDBLoc_Local 0x00000000
636#define HC_HDBLoc_Sys 0x00004000
637/* HC_SubA_HROP 0x0044
638 */
639#define HC_HROP_MASK 0x00000f00
640#define HC_HFBBMSKH_MASK 0x000000ff
641#define HC_HROP_BLACK 0x00000000
642#define HC_HROP_DPon 0x00000100
643#define HC_HROP_DPna 0x00000200
644#define HC_HROP_Pn 0x00000300
645#define HC_HROP_PDna 0x00000400
646#define HC_HROP_Dn 0x00000500
647#define HC_HROP_DPx 0x00000600
648#define HC_HROP_DPan 0x00000700
649#define HC_HROP_DPa 0x00000800
650#define HC_HROP_DPxn 0x00000900
651#define HC_HROP_D 0x00000a00
652#define HC_HROP_DPno 0x00000b00
653#define HC_HROP_P 0x00000c00
654#define HC_HROP_PDno 0x00000d00
655#define HC_HROP_DPo 0x00000e00
656#define HC_HROP_WHITE 0x00000f00
657
658/* Fog Setting
659 */
660#define HC_SubA_HFogLF 0x0050
661#define HC_SubA_HFogCL 0x0051
662#define HC_SubA_HFogCH 0x0052
663#define HC_SubA_HFogStL 0x0053
664#define HC_SubA_HFogStH 0x0054
665#define HC_SubA_HFogOOdMF 0x0055
666#define HC_SubA_HFogOOdEF 0x0056
667#define HC_SubA_HFogEndL 0x0057
668#define HC_SubA_HFogDenst 0x0058
669/* HC_SubA_FogLF 0x0050
670 */
671#define HC_FogLF_MASK 0x00000010
672#define HC_FogEq_MASK 0x00000008
673#define HC_FogMD_MASK 0x00000007
674#define HC_FogMD_LocalFog 0x00000000
675#define HC_FogMD_LinearFog 0x00000002
676#define HC_FogMD_ExponentialFog 0x00000004
677#define HC_FogMD_Exponential2Fog 0x00000005
678/* #define HC_FogMD_FogTable 0x00000003 */
679
680/* HC_SubA_HFogDenst 0x0058
681 */
682#define HC_FogDenst_MASK 0x001fff00
683#define HC_FogEndL_MASK 0x000000ff
684
685/* Texture subtype definitions
686 */
687#define HC_SubType_Tex0 0x00000000
688#define HC_SubType_Tex1 0x00000001
689#define HC_SubType_TexGeneral 0x000000fe
690
691/* Attribute of texture n
692 */
693#define HC_SubA_HTXnL0BasL 0x0000
694#define HC_SubA_HTXnL1BasL 0x0001
695#define HC_SubA_HTXnL2BasL 0x0002
696#define HC_SubA_HTXnL3BasL 0x0003
697#define HC_SubA_HTXnL4BasL 0x0004
698#define HC_SubA_HTXnL5BasL 0x0005
699#define HC_SubA_HTXnL6BasL 0x0006
700#define HC_SubA_HTXnL7BasL 0x0007
701#define HC_SubA_HTXnL8BasL 0x0008
702#define HC_SubA_HTXnL9BasL 0x0009
703#define HC_SubA_HTXnLaBasL 0x000a
704#define HC_SubA_HTXnLbBasL 0x000b
705#define HC_SubA_HTXnLcBasL 0x000c
706#define HC_SubA_HTXnLdBasL 0x000d
707#define HC_SubA_HTXnLeBasL 0x000e
708#define HC_SubA_HTXnLfBasL 0x000f
709#define HC_SubA_HTXnL10BasL 0x0010
710#define HC_SubA_HTXnL11BasL 0x0011
711#define HC_SubA_HTXnL012BasH 0x0020
712#define HC_SubA_HTXnL345BasH 0x0021
713#define HC_SubA_HTXnL678BasH 0x0022
714#define HC_SubA_HTXnL9abBasH 0x0023
715#define HC_SubA_HTXnLcdeBasH 0x0024
716#define HC_SubA_HTXnLf1011BasH 0x0025
717#define HC_SubA_HTXnL0Pit 0x002b
718#define HC_SubA_HTXnL1Pit 0x002c
719#define HC_SubA_HTXnL2Pit 0x002d
720#define HC_SubA_HTXnL3Pit 0x002e
721#define HC_SubA_HTXnL4Pit 0x002f
722#define HC_SubA_HTXnL5Pit 0x0030
723#define HC_SubA_HTXnL6Pit 0x0031
724#define HC_SubA_HTXnL7Pit 0x0032
725#define HC_SubA_HTXnL8Pit 0x0033
726#define HC_SubA_HTXnL9Pit 0x0034
727#define HC_SubA_HTXnLaPit 0x0035
728#define HC_SubA_HTXnLbPit 0x0036
729#define HC_SubA_HTXnLcPit 0x0037
730#define HC_SubA_HTXnLdPit 0x0038
731#define HC_SubA_HTXnLePit 0x0039
732#define HC_SubA_HTXnLfPit 0x003a
733#define HC_SubA_HTXnL10Pit 0x003b
734#define HC_SubA_HTXnL11Pit 0x003c
735#define HC_SubA_HTXnL0_5WE 0x004b
736#define HC_SubA_HTXnL6_bWE 0x004c
737#define HC_SubA_HTXnLc_11WE 0x004d
738#define HC_SubA_HTXnL0_5HE 0x0051
739#define HC_SubA_HTXnL6_bHE 0x0052
740#define HC_SubA_HTXnLc_11HE 0x0053
741#define HC_SubA_HTXnL0OS 0x0077
742#define HC_SubA_HTXnTB 0x0078
743#define HC_SubA_HTXnMPMD 0x0079
744#define HC_SubA_HTXnCLODu 0x007a
745#define HC_SubA_HTXnFM 0x007b
746#define HC_SubA_HTXnTRCH 0x007c
747#define HC_SubA_HTXnTRCL 0x007d
748#define HC_SubA_HTXnTBC 0x007e
749#define HC_SubA_HTXnTRAH 0x007f
750#define HC_SubA_HTXnTBLCsat 0x0080
751#define HC_SubA_HTXnTBLCop 0x0081
752#define HC_SubA_HTXnTBLMPfog 0x0082
753#define HC_SubA_HTXnTBLAsat 0x0083
754#define HC_SubA_HTXnTBLRCa 0x0085
755#define HC_SubA_HTXnTBLRCb 0x0086
756#define HC_SubA_HTXnTBLRCc 0x0087
757#define HC_SubA_HTXnTBLRCbias 0x0088
758#define HC_SubA_HTXnTBLRAa 0x0089
759#define HC_SubA_HTXnTBLRFog 0x008a
760#define HC_SubA_HTXnBumpM00 0x0090
761#define HC_SubA_HTXnBumpM01 0x0091
762#define HC_SubA_HTXnBumpM10 0x0092
763#define HC_SubA_HTXnBumpM11 0x0093
764#define HC_SubA_HTXnLScale 0x0094
765#define HC_SubA_HTXSMD 0x0000
766/* HC_SubA_HTXnL012BasH 0x0020
767 */
768#define HC_HTXnL0BasH_MASK 0x000000ff
769#define HC_HTXnL1BasH_MASK 0x0000ff00
770#define HC_HTXnL2BasH_MASK 0x00ff0000
771#define HC_HTXnL1BasH_SHIFT 8
772#define HC_HTXnL2BasH_SHIFT 16
773/* HC_SubA_HTXnL345BasH 0x0021
774 */
775#define HC_HTXnL3BasH_MASK 0x000000ff
776#define HC_HTXnL4BasH_MASK 0x0000ff00
777#define HC_HTXnL5BasH_MASK 0x00ff0000
778#define HC_HTXnL4BasH_SHIFT 8
779#define HC_HTXnL5BasH_SHIFT 16
780/* HC_SubA_HTXnL678BasH 0x0022
781 */
782#define HC_HTXnL6BasH_MASK 0x000000ff
783#define HC_HTXnL7BasH_MASK 0x0000ff00
784#define HC_HTXnL8BasH_MASK 0x00ff0000
785#define HC_HTXnL7BasH_SHIFT 8
786#define HC_HTXnL8BasH_SHIFT 16
787/* HC_SubA_HTXnL9abBasH 0x0023
788 */
789#define HC_HTXnL9BasH_MASK 0x000000ff
790#define HC_HTXnLaBasH_MASK 0x0000ff00
791#define HC_HTXnLbBasH_MASK 0x00ff0000
792#define HC_HTXnLaBasH_SHIFT 8
793#define HC_HTXnLbBasH_SHIFT 16
794/* HC_SubA_HTXnLcdeBasH 0x0024
795 */
796#define HC_HTXnLcBasH_MASK 0x000000ff
797#define HC_HTXnLdBasH_MASK 0x0000ff00
798#define HC_HTXnLeBasH_MASK 0x00ff0000
799#define HC_HTXnLdBasH_SHIFT 8
800#define HC_HTXnLeBasH_SHIFT 16
801/* HC_SubA_HTXnLcdeBasH 0x0025
802 */
803#define HC_HTXnLfBasH_MASK 0x000000ff
804#define HC_HTXnL10BasH_MASK 0x0000ff00
805#define HC_HTXnL11BasH_MASK 0x00ff0000
806#define HC_HTXnL10BasH_SHIFT 8
807#define HC_HTXnL11BasH_SHIFT 16
808/* HC_SubA_HTXnL0Pit 0x002b
809 */
810#define HC_HTXnLnPit_MASK 0x00003fff
811#define HC_HTXnEnPit_MASK 0x00080000
812#define HC_HTXnLnPitE_MASK 0x00f00000
813#define HC_HTXnLnPitE_SHIFT 20
814/* HC_SubA_HTXnL0_5WE 0x004b
815 */
816#define HC_HTXnL0WE_MASK 0x0000000f
817#define HC_HTXnL1WE_MASK 0x000000f0
818#define HC_HTXnL2WE_MASK 0x00000f00
819#define HC_HTXnL3WE_MASK 0x0000f000
820#define HC_HTXnL4WE_MASK 0x000f0000
821#define HC_HTXnL5WE_MASK 0x00f00000
822#define HC_HTXnL1WE_SHIFT 4
823#define HC_HTXnL2WE_SHIFT 8
824#define HC_HTXnL3WE_SHIFT 12
825#define HC_HTXnL4WE_SHIFT 16
826#define HC_HTXnL5WE_SHIFT 20
827/* HC_SubA_HTXnL6_bWE 0x004c
828 */
829#define HC_HTXnL6WE_MASK 0x0000000f
830#define HC_HTXnL7WE_MASK 0x000000f0
831#define HC_HTXnL8WE_MASK 0x00000f00
832#define HC_HTXnL9WE_MASK 0x0000f000
833#define HC_HTXnLaWE_MASK 0x000f0000
834#define HC_HTXnLbWE_MASK 0x00f00000
835#define HC_HTXnL7WE_SHIFT 4
836#define HC_HTXnL8WE_SHIFT 8
837#define HC_HTXnL9WE_SHIFT 12
838#define HC_HTXnLaWE_SHIFT 16
839#define HC_HTXnLbWE_SHIFT 20
840/* HC_SubA_HTXnLc_11WE 0x004d
841 */
842#define HC_HTXnLcWE_MASK 0x0000000f
843#define HC_HTXnLdWE_MASK 0x000000f0
844#define HC_HTXnLeWE_MASK 0x00000f00
845#define HC_HTXnLfWE_MASK 0x0000f000
846#define HC_HTXnL10WE_MASK 0x000f0000
847#define HC_HTXnL11WE_MASK 0x00f00000
848#define HC_HTXnLdWE_SHIFT 4
849#define HC_HTXnLeWE_SHIFT 8
850#define HC_HTXnLfWE_SHIFT 12
851#define HC_HTXnL10WE_SHIFT 16
852#define HC_HTXnL11WE_SHIFT 20
853/* HC_SubA_HTXnL0_5HE 0x0051
854 */
855#define HC_HTXnL0HE_MASK 0x0000000f
856#define HC_HTXnL1HE_MASK 0x000000f0
857#define HC_HTXnL2HE_MASK 0x00000f00
858#define HC_HTXnL3HE_MASK 0x0000f000
859#define HC_HTXnL4HE_MASK 0x000f0000
860#define HC_HTXnL5HE_MASK 0x00f00000
861#define HC_HTXnL1HE_SHIFT 4
862#define HC_HTXnL2HE_SHIFT 8
863#define HC_HTXnL3HE_SHIFT 12
864#define HC_HTXnL4HE_SHIFT 16
865#define HC_HTXnL5HE_SHIFT 20
866/* HC_SubA_HTXnL6_bHE 0x0052
867 */
868#define HC_HTXnL6HE_MASK 0x0000000f
869#define HC_HTXnL7HE_MASK 0x000000f0
870#define HC_HTXnL8HE_MASK 0x00000f00
871#define HC_HTXnL9HE_MASK 0x0000f000
872#define HC_HTXnLaHE_MASK 0x000f0000
873#define HC_HTXnLbHE_MASK 0x00f00000
874#define HC_HTXnL7HE_SHIFT 4
875#define HC_HTXnL8HE_SHIFT 8
876#define HC_HTXnL9HE_SHIFT 12
877#define HC_HTXnLaHE_SHIFT 16
878#define HC_HTXnLbHE_SHIFT 20
879/* HC_SubA_HTXnLc_11HE 0x0053
880 */
881#define HC_HTXnLcHE_MASK 0x0000000f
882#define HC_HTXnLdHE_MASK 0x000000f0
883#define HC_HTXnLeHE_MASK 0x00000f00
884#define HC_HTXnLfHE_MASK 0x0000f000
885#define HC_HTXnL10HE_MASK 0x000f0000
886#define HC_HTXnL11HE_MASK 0x00f00000
887#define HC_HTXnLdHE_SHIFT 4
888#define HC_HTXnLeHE_SHIFT 8
889#define HC_HTXnLfHE_SHIFT 12
890#define HC_HTXnL10HE_SHIFT 16
891#define HC_HTXnL11HE_SHIFT 20
892/* HC_SubA_HTXnL0OS 0x0077
893 */
894#define HC_HTXnL0OS_MASK 0x003ff000
895#define HC_HTXnLVmax_MASK 0x00000fc0
896#define HC_HTXnLVmin_MASK 0x0000003f
897#define HC_HTXnL0OS_SHIFT 12
898#define HC_HTXnLVmax_SHIFT 6
899/* HC_SubA_HTXnTB 0x0078
900 */
901#define HC_HTXnTB_MASK 0x00f00000
902#define HC_HTXnFLSe_MASK 0x0000e000
903#define HC_HTXnFLSs_MASK 0x00001c00
904#define HC_HTXnFLTe_MASK 0x00000380
905#define HC_HTXnFLTs_MASK 0x00000070
906#define HC_HTXnFLDs_MASK 0x0000000f
907#define HC_HTXnTB_NoTB 0x00000000
908#define HC_HTXnTB_TBC_S 0x00100000
909#define HC_HTXnTB_TBC_T 0x00200000
910#define HC_HTXnTB_TB_S 0x00400000
911#define HC_HTXnTB_TB_T 0x00800000
912#define HC_HTXnFLSe_Nearest 0x00000000
913#define HC_HTXnFLSe_Linear 0x00002000
914#define HC_HTXnFLSe_NonLinear 0x00004000
915#define HC_HTXnFLSe_Sharp 0x00008000
916#define HC_HTXnFLSe_Flat_Gaussian_Cubic 0x0000c000
917#define HC_HTXnFLSs_Nearest 0x00000000
918#define HC_HTXnFLSs_Linear 0x00000400
919#define HC_HTXnFLSs_NonLinear 0x00000800
920#define HC_HTXnFLSs_Flat_Gaussian_Cubic 0x00001800
921#define HC_HTXnFLTe_Nearest 0x00000000
922#define HC_HTXnFLTe_Linear 0x00000080
923#define HC_HTXnFLTe_NonLinear 0x00000100
924#define HC_HTXnFLTe_Sharp 0x00000180
925#define HC_HTXnFLTe_Flat_Gaussian_Cubic 0x00000300
926#define HC_HTXnFLTs_Nearest 0x00000000
927#define HC_HTXnFLTs_Linear 0x00000010
928#define HC_HTXnFLTs_NonLinear 0x00000020
929#define HC_HTXnFLTs_Flat_Gaussian_Cubic 0x00000060
930#define HC_HTXnFLDs_Tex0 0x00000000
931#define HC_HTXnFLDs_Nearest 0x00000001
932#define HC_HTXnFLDs_Linear 0x00000002
933#define HC_HTXnFLDs_NonLinear 0x00000003
934#define HC_HTXnFLDs_Dither 0x00000004
935#define HC_HTXnFLDs_ConstLOD 0x00000005
936#define HC_HTXnFLDs_Ani 0x00000006
937#define HC_HTXnFLDs_AniDither 0x00000007
938/* HC_SubA_HTXnMPMD 0x0079
939 */
940#define HC_HTXnMPMD_SMASK 0x00070000
941#define HC_HTXnMPMD_TMASK 0x00380000
942#define HC_HTXnLODDTf_MASK 0x00000007
943#define HC_HTXnXY2ST_MASK 0x00000008
944#define HC_HTXnMPMD_Tsingle 0x00000000
945#define HC_HTXnMPMD_Tclamp 0x00080000
946#define HC_HTXnMPMD_Trepeat 0x00100000
947#define HC_HTXnMPMD_Tmirror 0x00180000
948#define HC_HTXnMPMD_Twrap 0x00200000
949#define HC_HTXnMPMD_Ssingle 0x00000000
950#define HC_HTXnMPMD_Sclamp 0x00010000
951#define HC_HTXnMPMD_Srepeat 0x00020000
952#define HC_HTXnMPMD_Smirror 0x00030000
953#define HC_HTXnMPMD_Swrap 0x00040000
954/* HC_SubA_HTXnCLODu 0x007a
955 */
956#define HC_HTXnCLODu_MASK 0x000ffc00
957#define HC_HTXnCLODd_MASK 0x000003ff
958#define HC_HTXnCLODu_SHIFT 10
959/* HC_SubA_HTXnFM 0x007b
960 */
961#define HC_HTXnFM_MASK 0x00ff0000
962#define HC_HTXnLoc_MASK 0x00000003
963#define HC_HTXnFM_INDEX 0x00000000
964#define HC_HTXnFM_Intensity 0x00080000
965#define HC_HTXnFM_Lum 0x00100000
966#define HC_HTXnFM_Alpha 0x00180000
967#define HC_HTXnFM_DX 0x00280000
968#define HC_HTXnFM_ARGB16 0x00880000
969#define HC_HTXnFM_ARGB32 0x00980000
970#define HC_HTXnFM_ABGR16 0x00a80000
971#define HC_HTXnFM_ABGR32 0x00b80000
972#define HC_HTXnFM_RGBA16 0x00c80000
973#define HC_HTXnFM_RGBA32 0x00d80000
974#define HC_HTXnFM_BGRA16 0x00e80000
975#define HC_HTXnFM_BGRA32 0x00f80000
976#define HC_HTXnFM_BUMPMAP 0x00380000
977#define HC_HTXnFM_Index1 (HC_HTXnFM_INDEX | 0x00000000)
978#define HC_HTXnFM_Index2 (HC_HTXnFM_INDEX | 0x00010000)
979#define HC_HTXnFM_Index4 (HC_HTXnFM_INDEX | 0x00020000)
980#define HC_HTXnFM_Index8 (HC_HTXnFM_INDEX | 0x00030000)
981#define HC_HTXnFM_T1 (HC_HTXnFM_Intensity | 0x00000000)
982#define HC_HTXnFM_T2 (HC_HTXnFM_Intensity | 0x00010000)
983#define HC_HTXnFM_T4 (HC_HTXnFM_Intensity | 0x00020000)
984#define HC_HTXnFM_T8 (HC_HTXnFM_Intensity | 0x00030000)
985#define HC_HTXnFM_L1 (HC_HTXnFM_Lum | 0x00000000)
986#define HC_HTXnFM_L2 (HC_HTXnFM_Lum | 0x00010000)
987#define HC_HTXnFM_L4 (HC_HTXnFM_Lum | 0x00020000)
988#define HC_HTXnFM_L8 (HC_HTXnFM_Lum | 0x00030000)
989#define HC_HTXnFM_AL44 (HC_HTXnFM_Lum | 0x00040000)
990#define HC_HTXnFM_AL88 (HC_HTXnFM_Lum | 0x00050000)
991#define HC_HTXnFM_A1 (HC_HTXnFM_Alpha | 0x00000000)
992#define HC_HTXnFM_A2 (HC_HTXnFM_Alpha | 0x00010000)
993#define HC_HTXnFM_A4 (HC_HTXnFM_Alpha | 0x00020000)
994#define HC_HTXnFM_A8 (HC_HTXnFM_Alpha | 0x00030000)
995#define HC_HTXnFM_DX1 (HC_HTXnFM_DX | 0x00010000)
996#define HC_HTXnFM_DX23 (HC_HTXnFM_DX | 0x00020000)
997#define HC_HTXnFM_DX45 (HC_HTXnFM_DX | 0x00030000)
998#define HC_HTXnFM_RGB555 (HC_HTXnFM_ARGB16 | 0x00000000)
999#define HC_HTXnFM_RGB565 (HC_HTXnFM_ARGB16 | 0x00010000)
1000#define HC_HTXnFM_ARGB1555 (HC_HTXnFM_ARGB16 | 0x00020000)
1001#define HC_HTXnFM_ARGB4444 (HC_HTXnFM_ARGB16 | 0x00030000)
1002#define HC_HTXnFM_ARGB0888 (HC_HTXnFM_ARGB32 | 0x00000000)
1003#define HC_HTXnFM_ARGB8888 (HC_HTXnFM_ARGB32 | 0x00010000)
1004#define HC_HTXnFM_BGR555 (HC_HTXnFM_ABGR16 | 0x00000000)
1005#define HC_HTXnFM_BGR565 (HC_HTXnFM_ABGR16 | 0x00010000)
1006#define HC_HTXnFM_ABGR1555 (HC_HTXnFM_ABGR16 | 0x00020000)
1007#define HC_HTXnFM_ABGR4444 (HC_HTXnFM_ABGR16 | 0x00030000)
1008#define HC_HTXnFM_ABGR0888 (HC_HTXnFM_ABGR32 | 0x00000000)
1009#define HC_HTXnFM_ABGR8888 (HC_HTXnFM_ABGR32 | 0x00010000)
1010#define HC_HTXnFM_RGBA5550 (HC_HTXnFM_RGBA16 | 0x00000000)
1011#define HC_HTXnFM_RGBA5551 (HC_HTXnFM_RGBA16 | 0x00020000)
1012#define HC_HTXnFM_RGBA4444 (HC_HTXnFM_RGBA16 | 0x00030000)
1013#define HC_HTXnFM_RGBA8880 (HC_HTXnFM_RGBA32 | 0x00000000)
1014#define HC_HTXnFM_RGBA8888 (HC_HTXnFM_RGBA32 | 0x00010000)
1015#define HC_HTXnFM_BGRA5550 (HC_HTXnFM_BGRA16 | 0x00000000)
1016#define HC_HTXnFM_BGRA5551 (HC_HTXnFM_BGRA16 | 0x00020000)
1017#define HC_HTXnFM_BGRA4444 (HC_HTXnFM_BGRA16 | 0x00030000)
1018#define HC_HTXnFM_BGRA8880 (HC_HTXnFM_BGRA32 | 0x00000000)
1019#define HC_HTXnFM_BGRA8888 (HC_HTXnFM_BGRA32 | 0x00010000)
1020#define HC_HTXnFM_VU88 (HC_HTXnFM_BUMPMAP | 0x00000000)
1021#define HC_HTXnFM_LVU655 (HC_HTXnFM_BUMPMAP | 0x00010000)
1022#define HC_HTXnFM_LVU888 (HC_HTXnFM_BUMPMAP | 0x00020000)
1023#define HC_HTXnLoc_Local 0x00000000
1024#define HC_HTXnLoc_Sys 0x00000002
1025#define HC_HTXnLoc_AGP 0x00000003
1026/* HC_SubA_HTXnTRAH 0x007f
1027 */
1028#define HC_HTXnTRAH_MASK 0x00ff0000
1029#define HC_HTXnTRAL_MASK 0x0000ff00
1030#define HC_HTXnTBA_MASK 0x000000ff
1031#define HC_HTXnTRAH_SHIFT 16
1032#define HC_HTXnTRAL_SHIFT 8
1033/* HC_SubA_HTXnTBLCsat 0x0080
1034 *-- Define the input texture.
1035 */
1036#define HC_XTC_TOPC 0x00000000
1037#define HC_XTC_InvTOPC 0x00000010
1038#define HC_XTC_TOPCp5 0x00000020
1039#define HC_XTC_Cbias 0x00000000
1040#define HC_XTC_InvCbias 0x00000010
1041#define HC_XTC_0 0x00000000
1042#define HC_XTC_Dif 0x00000001
1043#define HC_XTC_Spec 0x00000002
1044#define HC_XTC_Tex 0x00000003
1045#define HC_XTC_Cur 0x00000004
1046#define HC_XTC_Adif 0x00000005
1047#define HC_XTC_Fog 0x00000006
1048#define HC_XTC_Atex 0x00000007
1049#define HC_XTC_Acur 0x00000008
1050#define HC_XTC_HTXnTBLRC 0x00000009
1051#define HC_XTC_Ctexnext 0x0000000a
1052/*--
1053 */
1054#define HC_HTXnTBLCsat_MASK 0x00800000
1055#define HC_HTXnTBLCa_MASK 0x000fc000
1056#define HC_HTXnTBLCb_MASK 0x00001f80
1057#define HC_HTXnTBLCc_MASK 0x0000003f
1058#define HC_HTXnTBLCa_TOPC (HC_XTC_TOPC << 14)
1059#define HC_HTXnTBLCa_InvTOPC (HC_XTC_InvTOPC << 14)
1060#define HC_HTXnTBLCa_TOPCp5 (HC_XTC_TOPCp5 << 14)
1061#define HC_HTXnTBLCa_0 (HC_XTC_0 << 14)
1062#define HC_HTXnTBLCa_Dif (HC_XTC_Dif << 14)
1063#define HC_HTXnTBLCa_Spec (HC_XTC_Spec << 14)
1064#define HC_HTXnTBLCa_Tex (HC_XTC_Tex << 14)
1065#define HC_HTXnTBLCa_Cur (HC_XTC_Cur << 14)
1066#define HC_HTXnTBLCa_Adif (HC_XTC_Adif << 14)
1067#define HC_HTXnTBLCa_Fog (HC_XTC_Fog << 14)
1068#define HC_HTXnTBLCa_Atex (HC_XTC_Atex << 14)
1069#define HC_HTXnTBLCa_Acur (HC_XTC_Acur << 14)
1070#define HC_HTXnTBLCa_HTXnTBLRC (HC_XTC_HTXnTBLRC << 14)
1071#define HC_HTXnTBLCa_Ctexnext (HC_XTC_Ctexnext << 14)
1072#define HC_HTXnTBLCb_TOPC (HC_XTC_TOPC << 7)
1073#define HC_HTXnTBLCb_InvTOPC (HC_XTC_InvTOPC << 7)
1074#define HC_HTXnTBLCb_TOPCp5 (HC_XTC_TOPCp5 << 7)
1075#define HC_HTXnTBLCb_0 (HC_XTC_0 << 7)
1076#define HC_HTXnTBLCb_Dif (HC_XTC_Dif << 7)
1077#define HC_HTXnTBLCb_Spec (HC_XTC_Spec << 7)
1078#define HC_HTXnTBLCb_Tex (HC_XTC_Tex << 7)
1079#define HC_HTXnTBLCb_Cur (HC_XTC_Cur << 7)
1080#define HC_HTXnTBLCb_Adif (HC_XTC_Adif << 7)
1081#define HC_HTXnTBLCb_Fog (HC_XTC_Fog << 7)
1082#define HC_HTXnTBLCb_Atex (HC_XTC_Atex << 7)
1083#define HC_HTXnTBLCb_Acur (HC_XTC_Acur << 7)
1084#define HC_HTXnTBLCb_HTXnTBLRC (HC_XTC_HTXnTBLRC << 7)
1085#define HC_HTXnTBLCb_Ctexnext (HC_XTC_Ctexnext << 7)
1086#define HC_HTXnTBLCc_TOPC (HC_XTC_TOPC << 0)
1087#define HC_HTXnTBLCc_InvTOPC (HC_XTC_InvTOPC << 0)
1088#define HC_HTXnTBLCc_TOPCp5 (HC_XTC_TOPCp5 << 0)
1089#define HC_HTXnTBLCc_0 (HC_XTC_0 << 0)
1090#define HC_HTXnTBLCc_Dif (HC_XTC_Dif << 0)
1091#define HC_HTXnTBLCc_Spec (HC_XTC_Spec << 0)
1092#define HC_HTXnTBLCc_Tex (HC_XTC_Tex << 0)
1093#define HC_HTXnTBLCc_Cur (HC_XTC_Cur << 0)
1094#define HC_HTXnTBLCc_Adif (HC_XTC_Adif << 0)
1095#define HC_HTXnTBLCc_Fog (HC_XTC_Fog << 0)
1096#define HC_HTXnTBLCc_Atex (HC_XTC_Atex << 0)
1097#define HC_HTXnTBLCc_Acur (HC_XTC_Acur << 0)
1098#define HC_HTXnTBLCc_HTXnTBLRC (HC_XTC_HTXnTBLRC << 0)
1099#define HC_HTXnTBLCc_Ctexnext (HC_XTC_Ctexnext << 0)
1100/* HC_SubA_HTXnTBLCop 0x0081
1101 */
1102#define HC_HTXnTBLdot_MASK 0x00c00000
1103#define HC_HTXnTBLCop_MASK 0x00380000
1104#define HC_HTXnTBLCbias_MASK 0x0007c000
1105#define HC_HTXnTBLCshift_MASK 0x00001800
1106#define HC_HTXnTBLAop_MASK 0x00000380
1107#define HC_HTXnTBLAbias_MASK 0x00000078
1108#define HC_HTXnTBLAshift_MASK 0x00000003
1109#define HC_HTXnTBLCop_Add 0x00000000
1110#define HC_HTXnTBLCop_Sub 0x00080000
1111#define HC_HTXnTBLCop_Min 0x00100000
1112#define HC_HTXnTBLCop_Max 0x00180000
1113#define HC_HTXnTBLCop_Mask 0x00200000
1114#define HC_HTXnTBLCbias_Cbias (HC_XTC_Cbias << 14)
1115#define HC_HTXnTBLCbias_InvCbias (HC_XTC_InvCbias << 14)
1116#define HC_HTXnTBLCbias_0 (HC_XTC_0 << 14)
1117#define HC_HTXnTBLCbias_Dif (HC_XTC_Dif << 14)
1118#define HC_HTXnTBLCbias_Spec (HC_XTC_Spec << 14)
1119#define HC_HTXnTBLCbias_Tex (HC_XTC_Tex << 14)
1120#define HC_HTXnTBLCbias_Cur (HC_XTC_Cur << 14)
1121#define HC_HTXnTBLCbias_Adif (HC_XTC_Adif << 14)
1122#define HC_HTXnTBLCbias_Fog (HC_XTC_Fog << 14)
1123#define HC_HTXnTBLCbias_Atex (HC_XTC_Atex << 14)
1124#define HC_HTXnTBLCbias_Acur (HC_XTC_Acur << 14)
1125#define HC_HTXnTBLCbias_HTXnTBLRC (HC_XTC_HTXnTBLRC << 14)
1126#define HC_HTXnTBLCshift_1 0x00000000
1127#define HC_HTXnTBLCshift_2 0x00000800
1128#define HC_HTXnTBLCshift_No 0x00001000
1129#define HC_HTXnTBLCshift_DotP 0x00001800
1130/*=* John Sheng [2003.7.18] texture combine *=*/
1131#define HC_HTXnTBLDOT3 0x00080000
1132#define HC_HTXnTBLDOT4 0x000C0000
1133
1134#define HC_HTXnTBLAop_Add 0x00000000
1135#define HC_HTXnTBLAop_Sub 0x00000080
1136#define HC_HTXnTBLAop_Min 0x00000100
1137#define HC_HTXnTBLAop_Max 0x00000180
1138#define HC_HTXnTBLAop_Mask 0x00000200
1139#define HC_HTXnTBLAbias_Inv 0x00000040
1140#define HC_HTXnTBLAbias_Adif 0x00000000
1141#define HC_HTXnTBLAbias_Fog 0x00000008
1142#define HC_HTXnTBLAbias_Acur 0x00000010
1143#define HC_HTXnTBLAbias_HTXnTBLRAbias 0x00000018
1144#define HC_HTXnTBLAbias_Atex 0x00000020
1145#define HC_HTXnTBLAshift_1 0x00000000
1146#define HC_HTXnTBLAshift_2 0x00000001
1147#define HC_HTXnTBLAshift_No 0x00000002
1148/* #define HC_HTXnTBLAshift_DotP 0x00000003 */
1149/* HC_SubA_HTXnTBLMPFog 0x0082
1150 */
1151#define HC_HTXnTBLMPfog_MASK 0x00e00000
1152#define HC_HTXnTBLMPfog_0 0x00000000
1153#define HC_HTXnTBLMPfog_Adif 0x00200000
1154#define HC_HTXnTBLMPfog_Fog 0x00400000
1155#define HC_HTXnTBLMPfog_Atex 0x00600000
1156#define HC_HTXnTBLMPfog_Acur 0x00800000
1157#define HC_HTXnTBLMPfog_GHTXnTBLRFog 0x00a00000
1158/* HC_SubA_HTXnTBLAsat 0x0083
1159 *-- Define the texture alpha input.
1160 */
1161#define HC_XTA_TOPA 0x00000000
1162#define HC_XTA_InvTOPA 0x00000008
1163#define HC_XTA_TOPAp5 0x00000010
1164#define HC_XTA_Adif 0x00000000
1165#define HC_XTA_Fog 0x00000001
1166#define HC_XTA_Acur 0x00000002
1167#define HC_XTA_HTXnTBLRA 0x00000003
1168#define HC_XTA_Atex 0x00000004
1169#define HC_XTA_Atexnext 0x00000005
1170/*--
1171 */
1172#define HC_HTXnTBLAsat_MASK 0x00800000
1173#define HC_HTXnTBLAMB_MASK 0x00700000
1174#define HC_HTXnTBLAa_MASK 0x0007c000
1175#define HC_HTXnTBLAb_MASK 0x00000f80
1176#define HC_HTXnTBLAc_MASK 0x0000001f
1177#define HC_HTXnTBLAMB_SHIFT 20
1178#define HC_HTXnTBLAa_TOPA (HC_XTA_TOPA << 14)
1179#define HC_HTXnTBLAa_InvTOPA (HC_XTA_InvTOPA << 14)
1180#define HC_HTXnTBLAa_TOPAp5 (HC_XTA_TOPAp5 << 14)
1181#define HC_HTXnTBLAa_Adif (HC_XTA_Adif << 14)
1182#define HC_HTXnTBLAa_Fog (HC_XTA_Fog << 14)
1183#define HC_HTXnTBLAa_Acur (HC_XTA_Acur << 14)
1184#define HC_HTXnTBLAa_HTXnTBLRA (HC_XTA_HTXnTBLRA << 14)
1185#define HC_HTXnTBLAa_Atex (HC_XTA_Atex << 14)
1186#define HC_HTXnTBLAa_Atexnext (HC_XTA_Atexnext << 14)
1187#define HC_HTXnTBLAb_TOPA (HC_XTA_TOPA << 7)
1188#define HC_HTXnTBLAb_InvTOPA (HC_XTA_InvTOPA << 7)
1189#define HC_HTXnTBLAb_TOPAp5 (HC_XTA_TOPAp5 << 7)
1190#define HC_HTXnTBLAb_Adif (HC_XTA_Adif << 7)
1191#define HC_HTXnTBLAb_Fog (HC_XTA_Fog << 7)
1192#define HC_HTXnTBLAb_Acur (HC_XTA_Acur << 7)
1193#define HC_HTXnTBLAb_HTXnTBLRA (HC_XTA_HTXnTBLRA << 7)
1194#define HC_HTXnTBLAb_Atex (HC_XTA_Atex << 7)
1195#define HC_HTXnTBLAb_Atexnext (HC_XTA_Atexnext << 7)
1196#define HC_HTXnTBLAc_TOPA (HC_XTA_TOPA << 0)
1197#define HC_HTXnTBLAc_InvTOPA (HC_XTA_InvTOPA << 0)
1198#define HC_HTXnTBLAc_TOPAp5 (HC_XTA_TOPAp5 << 0)
1199#define HC_HTXnTBLAc_Adif (HC_XTA_Adif << 0)
1200#define HC_HTXnTBLAc_Fog (HC_XTA_Fog << 0)
1201#define HC_HTXnTBLAc_Acur (HC_XTA_Acur << 0)
1202#define HC_HTXnTBLAc_HTXnTBLRA (HC_XTA_HTXnTBLRA << 0)
1203#define HC_HTXnTBLAc_Atex (HC_XTA_Atex << 0)
1204#define HC_HTXnTBLAc_Atexnext (HC_XTA_Atexnext << 0)
1205/* HC_SubA_HTXnTBLRAa 0x0089
1206 */
1207#define HC_HTXnTBLRAa_MASK 0x00ff0000
1208#define HC_HTXnTBLRAb_MASK 0x0000ff00
1209#define HC_HTXnTBLRAc_MASK 0x000000ff
1210#define HC_HTXnTBLRAa_SHIFT 16
1211#define HC_HTXnTBLRAb_SHIFT 8
1212#define HC_HTXnTBLRAc_SHIFT 0
1213/* HC_SubA_HTXnTBLRFog 0x008a
1214 */
1215#define HC_HTXnTBLRFog_MASK 0x0000ff00
1216#define HC_HTXnTBLRAbias_MASK 0x000000ff
1217#define HC_HTXnTBLRFog_SHIFT 8
1218#define HC_HTXnTBLRAbias_SHIFT 0
1219/* HC_SubA_HTXnLScale 0x0094
1220 */
1221#define HC_HTXnLScale_MASK 0x0007fc00
1222#define HC_HTXnLOff_MASK 0x000001ff
1223#define HC_HTXnLScale_SHIFT 10
1224/* HC_SubA_HTXSMD 0x0000
1225 */
1226#define HC_HTXSMD_MASK 0x00000080
1227#define HC_HTXTMD_MASK 0x00000040
1228#define HC_HTXNum_MASK 0x00000038
1229#define HC_HTXTRMD_MASK 0x00000006
1230#define HC_HTXCHCLR_MASK 0x00000001
1231#define HC_HTXNum_SHIFT 3
1232
1233/* Texture Palette n
1234 */
1235#define HC_SubType_TexPalette0 0x00000000
1236#define HC_SubType_TexPalette1 0x00000001
1237#define HC_SubType_FogTable 0x00000010
1238#define HC_SubType_Stipple 0x00000014
1239/* HC_SubA_TexPalette0 0x0000
1240 */
1241#define HC_HTPnA_MASK 0xff000000
1242#define HC_HTPnR_MASK 0x00ff0000
1243#define HC_HTPnG_MASK 0x0000ff00
1244#define HC_HTPnB_MASK 0x000000ff
1245/* HC_SubA_FogTable 0x0010
1246 */
1247#define HC_HFPn3_MASK 0xff000000
1248#define HC_HFPn2_MASK 0x00ff0000
1249#define HC_HFPn1_MASK 0x0000ff00
1250#define HC_HFPn_MASK 0x000000ff
1251#define HC_HFPn3_SHIFT 24
1252#define HC_HFPn2_SHIFT 16
1253#define HC_HFPn1_SHIFT 8
1254
1255/* Auto Testing & Security
1256 */
1257#define HC_SubA_HenFIFOAT 0x0000
1258#define HC_SubA_HFBDrawFirst 0x0004
1259#define HC_SubA_HFBBasL 0x0005
1260#define HC_SubA_HFBDst 0x0006
1261/* HC_SubA_HenFIFOAT 0x0000
1262 */
1263#define HC_HenFIFOAT_MASK 0x00000020
1264#define HC_HenGEMILock_MASK 0x00000010
1265#define HC_HenFBASwap_MASK 0x00000008
1266#define HC_HenOT_MASK 0x00000004
1267#define HC_HenCMDQ_MASK 0x00000002
1268#define HC_HenTXCTSU_MASK 0x00000001
1269/* HC_SubA_HFBDrawFirst 0x0004
1270 */
1271#define HC_HFBDrawFirst_MASK 0x00000800
1272#define HC_HFBQueue_MASK 0x00000400
1273#define HC_HFBLock_MASK 0x00000200
1274#define HC_HEOF_MASK 0x00000100
1275#define HC_HFBBasH_MASK 0x000000ff
1276
1277/* GEMI Setting
1278 */
1279#define HC_SubA_HTArbRCM 0x0008
1280#define HC_SubA_HTArbRZ 0x000a
1281#define HC_SubA_HTArbWZ 0x000b
1282#define HC_SubA_HTArbRTX 0x000c
1283#define HC_SubA_HTArbRCW 0x000d
1284#define HC_SubA_HTArbE2 0x000e
1285#define HC_SubA_HArbRQCM 0x0010
1286#define HC_SubA_HArbWQCM 0x0011
1287#define HC_SubA_HGEMITout 0x0020
1288#define HC_SubA_HFthRTXD 0x0040
1289#define HC_SubA_HFthRTXA 0x0044
1290#define HC_SubA_HCMDQstL 0x0050
1291#define HC_SubA_HCMDQendL 0x0051
1292#define HC_SubA_HCMDQLen 0x0052
1293/* HC_SubA_HTArbRCM 0x0008
1294 */
1295#define HC_HTArbRCM_MASK 0x0000ffff
1296/* HC_SubA_HTArbRZ 0x000a
1297 */
1298#define HC_HTArbRZ_MASK 0x0000ffff
1299/* HC_SubA_HTArbWZ 0x000b
1300 */
1301#define HC_HTArbWZ_MASK 0x0000ffff
1302/* HC_SubA_HTArbRTX 0x000c
1303 */
1304#define HC_HTArbRTX_MASK 0x0000ffff
1305/* HC_SubA_HTArbRCW 0x000d
1306 */
1307#define HC_HTArbRCW_MASK 0x0000ffff
1308/* HC_SubA_HTArbE2 0x000e
1309 */
1310#define HC_HTArbE2_MASK 0x0000ffff
1311/* HC_SubA_HArbRQCM 0x0010
1312 */
1313#define HC_HTArbRQCM_MASK 0x0000ffff
1314/* HC_SubA_HArbWQCM 0x0011
1315 */
1316#define HC_HArbWQCM_MASK 0x0000ffff
1317/* HC_SubA_HGEMITout 0x0020
1318 */
1319#define HC_HGEMITout_MASK 0x000f0000
1320#define HC_HNPArbZC_MASK 0x0000ffff
1321#define HC_HGEMITout_SHIFT 16
1322/* HC_SubA_HFthRTXD 0x0040
1323 */
1324#define HC_HFthRTXD_MASK 0x00ff0000
1325#define HC_HFthRZD_MASK 0x0000ff00
1326#define HC_HFthWZD_MASK 0x000000ff
1327#define HC_HFthRTXD_SHIFT 16
1328#define HC_HFthRZD_SHIFT 8
1329/* HC_SubA_HFthRTXA 0x0044
1330 */
1331#define HC_HFthRTXA_MASK 0x000000ff
1332
1333/******************************************************************************
1334** Define the Halcyon Internal register access constants. For simulator only.
1335******************************************************************************/
1336#define HC_SIMA_HAGPBstL 0x0000
1337#define HC_SIMA_HAGPBendL 0x0001
1338#define HC_SIMA_HAGPCMNT 0x0002
1339#define HC_SIMA_HAGPBpL 0x0003
1340#define HC_SIMA_HAGPBpH 0x0004
1341#define HC_SIMA_HClipTB 0x0005
1342#define HC_SIMA_HClipLR 0x0006
1343#define HC_SIMA_HFPClipTL 0x0007
1344#define HC_SIMA_HFPClipBL 0x0008
1345#define HC_SIMA_HFPClipLL 0x0009
1346#define HC_SIMA_HFPClipRL 0x000a
1347#define HC_SIMA_HFPClipTBH 0x000b
1348#define HC_SIMA_HFPClipLRH 0x000c
1349#define HC_SIMA_HLP 0x000d
1350#define HC_SIMA_HLPRF 0x000e
1351#define HC_SIMA_HSolidCL 0x000f
1352#define HC_SIMA_HPixGC 0x0010
1353#define HC_SIMA_HSPXYOS 0x0011
1354#define HC_SIMA_HCmdA 0x0012
1355#define HC_SIMA_HCmdB 0x0013
1356#define HC_SIMA_HEnable 0x0014
1357#define HC_SIMA_HZWBBasL 0x0015
1358#define HC_SIMA_HZWBBasH 0x0016
1359#define HC_SIMA_HZWBType 0x0017
1360#define HC_SIMA_HZBiasL 0x0018
1361#define HC_SIMA_HZWBend 0x0019
1362#define HC_SIMA_HZWTMD 0x001a
1363#define HC_SIMA_HZWCDL 0x001b
1364#define HC_SIMA_HZWCTAGnum 0x001c
1365#define HC_SIMA_HZCYNum 0x001d
1366#define HC_SIMA_HZWCFire 0x001e
1367/* #define HC_SIMA_HSBBasL 0x001d */
1368/* #define HC_SIMA_HSBBasH 0x001e */
1369/* #define HC_SIMA_HSBFM 0x001f */
1370#define HC_SIMA_HSTREF 0x0020
1371#define HC_SIMA_HSTMD 0x0021
1372#define HC_SIMA_HABBasL 0x0022
1373#define HC_SIMA_HABBasH 0x0023
1374#define HC_SIMA_HABFM 0x0024
1375#define HC_SIMA_HATMD 0x0025
1376#define HC_SIMA_HABLCsat 0x0026
1377#define HC_SIMA_HABLCop 0x0027
1378#define HC_SIMA_HABLAsat 0x0028
1379#define HC_SIMA_HABLAop 0x0029
1380#define HC_SIMA_HABLRCa 0x002a
1381#define HC_SIMA_HABLRFCa 0x002b
1382#define HC_SIMA_HABLRCbias 0x002c
1383#define HC_SIMA_HABLRCb 0x002d
1384#define HC_SIMA_HABLRFCb 0x002e
1385#define HC_SIMA_HABLRAa 0x002f
1386#define HC_SIMA_HABLRAb 0x0030
1387#define HC_SIMA_HDBBasL 0x0031
1388#define HC_SIMA_HDBBasH 0x0032
1389#define HC_SIMA_HDBFM 0x0033
1390#define HC_SIMA_HFBBMSKL 0x0034
1391#define HC_SIMA_HROP 0x0035
1392#define HC_SIMA_HFogLF 0x0036
1393#define HC_SIMA_HFogCL 0x0037
1394#define HC_SIMA_HFogCH 0x0038
1395#define HC_SIMA_HFogStL 0x0039
1396#define HC_SIMA_HFogStH 0x003a
1397#define HC_SIMA_HFogOOdMF 0x003b
1398#define HC_SIMA_HFogOOdEF 0x003c
1399#define HC_SIMA_HFogEndL 0x003d
1400#define HC_SIMA_HFogDenst 0x003e
1401/*---- start of texture 0 setting ----
1402 */
1403#define HC_SIMA_HTX0L0BasL 0x0040
1404#define HC_SIMA_HTX0L1BasL 0x0041
1405#define HC_SIMA_HTX0L2BasL 0x0042
1406#define HC_SIMA_HTX0L3BasL 0x0043
1407#define HC_SIMA_HTX0L4BasL 0x0044
1408#define HC_SIMA_HTX0L5BasL 0x0045
1409#define HC_SIMA_HTX0L6BasL 0x0046
1410#define HC_SIMA_HTX0L7BasL 0x0047
1411#define HC_SIMA_HTX0L8BasL 0x0048
1412#define HC_SIMA_HTX0L9BasL 0x0049
1413#define HC_SIMA_HTX0LaBasL 0x004a
1414#define HC_SIMA_HTX0LbBasL 0x004b
1415#define HC_SIMA_HTX0LcBasL 0x004c
1416#define HC_SIMA_HTX0LdBasL 0x004d
1417#define HC_SIMA_HTX0LeBasL 0x004e
1418#define HC_SIMA_HTX0LfBasL 0x004f
1419#define HC_SIMA_HTX0L10BasL 0x0050
1420#define HC_SIMA_HTX0L11BasL 0x0051
1421#define HC_SIMA_HTX0L012BasH 0x0052
1422#define HC_SIMA_HTX0L345BasH 0x0053
1423#define HC_SIMA_HTX0L678BasH 0x0054
1424#define HC_SIMA_HTX0L9abBasH 0x0055
1425#define HC_SIMA_HTX0LcdeBasH 0x0056
1426#define HC_SIMA_HTX0Lf1011BasH 0x0057
1427#define HC_SIMA_HTX0L0Pit 0x0058
1428#define HC_SIMA_HTX0L1Pit 0x0059
1429#define HC_SIMA_HTX0L2Pit 0x005a
1430#define HC_SIMA_HTX0L3Pit 0x005b
1431#define HC_SIMA_HTX0L4Pit 0x005c
1432#define HC_SIMA_HTX0L5Pit 0x005d
1433#define HC_SIMA_HTX0L6Pit 0x005e
1434#define HC_SIMA_HTX0L7Pit 0x005f
1435#define HC_SIMA_HTX0L8Pit 0x0060
1436#define HC_SIMA_HTX0L9Pit 0x0061
1437#define HC_SIMA_HTX0LaPit 0x0062
1438#define HC_SIMA_HTX0LbPit 0x0063
1439#define HC_SIMA_HTX0LcPit 0x0064
1440#define HC_SIMA_HTX0LdPit 0x0065
1441#define HC_SIMA_HTX0LePit 0x0066
1442#define HC_SIMA_HTX0LfPit 0x0067
1443#define HC_SIMA_HTX0L10Pit 0x0068
1444#define HC_SIMA_HTX0L11Pit 0x0069
1445#define HC_SIMA_HTX0L0_5WE 0x006a
1446#define HC_SIMA_HTX0L6_bWE 0x006b
1447#define HC_SIMA_HTX0Lc_11WE 0x006c
1448#define HC_SIMA_HTX0L0_5HE 0x006d
1449#define HC_SIMA_HTX0L6_bHE 0x006e
1450#define HC_SIMA_HTX0Lc_11HE 0x006f
1451#define HC_SIMA_HTX0L0OS 0x0070
1452#define HC_SIMA_HTX0TB 0x0071
1453#define HC_SIMA_HTX0MPMD 0x0072
1454#define HC_SIMA_HTX0CLODu 0x0073
1455#define HC_SIMA_HTX0FM 0x0074
1456#define HC_SIMA_HTX0TRCH 0x0075
1457#define HC_SIMA_HTX0TRCL 0x0076
1458#define HC_SIMA_HTX0TBC 0x0077
1459#define HC_SIMA_HTX0TRAH 0x0078
1460#define HC_SIMA_HTX0TBLCsat 0x0079
1461#define HC_SIMA_HTX0TBLCop 0x007a
1462#define HC_SIMA_HTX0TBLMPfog 0x007b
1463#define HC_SIMA_HTX0TBLAsat 0x007c
1464#define HC_SIMA_HTX0TBLRCa 0x007d
1465#define HC_SIMA_HTX0TBLRCb 0x007e
1466#define HC_SIMA_HTX0TBLRCc 0x007f
1467#define HC_SIMA_HTX0TBLRCbias 0x0080
1468#define HC_SIMA_HTX0TBLRAa 0x0081
1469#define HC_SIMA_HTX0TBLRFog 0x0082
1470#define HC_SIMA_HTX0BumpM00 0x0083
1471#define HC_SIMA_HTX0BumpM01 0x0084
1472#define HC_SIMA_HTX0BumpM10 0x0085
1473#define HC_SIMA_HTX0BumpM11 0x0086
1474#define HC_SIMA_HTX0LScale 0x0087
1475/*---- end of texture 0 setting ---- 0x008f
1476 */
1477#define HC_SIMA_TX0TX1_OFF 0x0050
1478/*---- start of texture 1 setting ----
1479 */
1480#define HC_SIMA_HTX1L0BasL (HC_SIMA_HTX0L0BasL + HC_SIMA_TX0TX1_OFF)
1481#define HC_SIMA_HTX1L1BasL (HC_SIMA_HTX0L1BasL + HC_SIMA_TX0TX1_OFF)
1482#define HC_SIMA_HTX1L2BasL (HC_SIMA_HTX0L2BasL + HC_SIMA_TX0TX1_OFF)
1483#define HC_SIMA_HTX1L3BasL (HC_SIMA_HTX0L3BasL + HC_SIMA_TX0TX1_OFF)
1484#define HC_SIMA_HTX1L4BasL (HC_SIMA_HTX0L4BasL + HC_SIMA_TX0TX1_OFF)
1485#define HC_SIMA_HTX1L5BasL (HC_SIMA_HTX0L5BasL + HC_SIMA_TX0TX1_OFF)
1486#define HC_SIMA_HTX1L6BasL (HC_SIMA_HTX0L6BasL + HC_SIMA_TX0TX1_OFF)
1487#define HC_SIMA_HTX1L7BasL (HC_SIMA_HTX0L7BasL + HC_SIMA_TX0TX1_OFF)
1488#define HC_SIMA_HTX1L8BasL (HC_SIMA_HTX0L8BasL + HC_SIMA_TX0TX1_OFF)
1489#define HC_SIMA_HTX1L9BasL (HC_SIMA_HTX0L9BasL + HC_SIMA_TX0TX1_OFF)
1490#define HC_SIMA_HTX1LaBasL (HC_SIMA_HTX0LaBasL + HC_SIMA_TX0TX1_OFF)
1491#define HC_SIMA_HTX1LbBasL (HC_SIMA_HTX0LbBasL + HC_SIMA_TX0TX1_OFF)
1492#define HC_SIMA_HTX1LcBasL (HC_SIMA_HTX0LcBasL + HC_SIMA_TX0TX1_OFF)
1493#define HC_SIMA_HTX1LdBasL (HC_SIMA_HTX0LdBasL + HC_SIMA_TX0TX1_OFF)
1494#define HC_SIMA_HTX1LeBasL (HC_SIMA_HTX0LeBasL + HC_SIMA_TX0TX1_OFF)
1495#define HC_SIMA_HTX1LfBasL (HC_SIMA_HTX0LfBasL + HC_SIMA_TX0TX1_OFF)
1496#define HC_SIMA_HTX1L10BasL (HC_SIMA_HTX0L10BasL + HC_SIMA_TX0TX1_OFF)
1497#define HC_SIMA_HTX1L11BasL (HC_SIMA_HTX0L11BasL + HC_SIMA_TX0TX1_OFF)
1498#define HC_SIMA_HTX1L012BasH (HC_SIMA_HTX0L012BasH + HC_SIMA_TX0TX1_OFF)
1499#define HC_SIMA_HTX1L345BasH (HC_SIMA_HTX0L345BasH + HC_SIMA_TX0TX1_OFF)
1500#define HC_SIMA_HTX1L678BasH (HC_SIMA_HTX0L678BasH + HC_SIMA_TX0TX1_OFF)
1501#define HC_SIMA_HTX1L9abBasH (HC_SIMA_HTX0L9abBasH + HC_SIMA_TX0TX1_OFF)
1502#define HC_SIMA_HTX1LcdeBasH (HC_SIMA_HTX0LcdeBasH + HC_SIMA_TX0TX1_OFF)
1503#define HC_SIMA_HTX1Lf1011BasH (HC_SIMA_HTX0Lf1011BasH + HC_SIMA_TX0TX1_OFF)
1504#define HC_SIMA_HTX1L0Pit (HC_SIMA_HTX0L0Pit + HC_SIMA_TX0TX1_OFF)
1505#define HC_SIMA_HTX1L1Pit (HC_SIMA_HTX0L1Pit + HC_SIMA_TX0TX1_OFF)
1506#define HC_SIMA_HTX1L2Pit (HC_SIMA_HTX0L2Pit + HC_SIMA_TX0TX1_OFF)
1507#define HC_SIMA_HTX1L3Pit (HC_SIMA_HTX0L3Pit + HC_SIMA_TX0TX1_OFF)
1508#define HC_SIMA_HTX1L4Pit (HC_SIMA_HTX0L4Pit + HC_SIMA_TX0TX1_OFF)
1509#define HC_SIMA_HTX1L5Pit (HC_SIMA_HTX0L5Pit + HC_SIMA_TX0TX1_OFF)
1510#define HC_SIMA_HTX1L6Pit (HC_SIMA_HTX0L6Pit + HC_SIMA_TX0TX1_OFF)
1511#define HC_SIMA_HTX1L7Pit (HC_SIMA_HTX0L7Pit + HC_SIMA_TX0TX1_OFF)
1512#define HC_SIMA_HTX1L8Pit (HC_SIMA_HTX0L8Pit + HC_SIMA_TX0TX1_OFF)
1513#define HC_SIMA_HTX1L9Pit (HC_SIMA_HTX0L9Pit + HC_SIMA_TX0TX1_OFF)
1514#define HC_SIMA_HTX1LaPit (HC_SIMA_HTX0LaPit + HC_SIMA_TX0TX1_OFF)
1515#define HC_SIMA_HTX1LbPit (HC_SIMA_HTX0LbPit + HC_SIMA_TX0TX1_OFF)
1516#define HC_SIMA_HTX1LcPit (HC_SIMA_HTX0LcPit + HC_SIMA_TX0TX1_OFF)
1517#define HC_SIMA_HTX1LdPit (HC_SIMA_HTX0LdPit + HC_SIMA_TX0TX1_OFF)
1518#define HC_SIMA_HTX1LePit (HC_SIMA_HTX0LePit + HC_SIMA_TX0TX1_OFF)
1519#define HC_SIMA_HTX1LfPit (HC_SIMA_HTX0LfPit + HC_SIMA_TX0TX1_OFF)
1520#define HC_SIMA_HTX1L10Pit (HC_SIMA_HTX0L10Pit + HC_SIMA_TX0TX1_OFF)
1521#define HC_SIMA_HTX1L11Pit (HC_SIMA_HTX0L11Pit + HC_SIMA_TX0TX1_OFF)
1522#define HC_SIMA_HTX1L0_5WE (HC_SIMA_HTX0L0_5WE + HC_SIMA_TX0TX1_OFF)
1523#define HC_SIMA_HTX1L6_bWE (HC_SIMA_HTX0L6_bWE + HC_SIMA_TX0TX1_OFF)
1524#define HC_SIMA_HTX1Lc_11WE (HC_SIMA_HTX0Lc_11WE + HC_SIMA_TX0TX1_OFF)
1525#define HC_SIMA_HTX1L0_5HE (HC_SIMA_HTX0L0_5HE + HC_SIMA_TX0TX1_OFF)
1526#define HC_SIMA_HTX1L6_bHE (HC_SIMA_HTX0L6_bHE + HC_SIMA_TX0TX1_OFF)
1527#define HC_SIMA_HTX1Lc_11HE (HC_SIMA_HTX0Lc_11HE + HC_SIMA_TX0TX1_OFF)
1528#define HC_SIMA_HTX1L0OS (HC_SIMA_HTX0L0OS + HC_SIMA_TX0TX1_OFF)
1529#define HC_SIMA_HTX1TB (HC_SIMA_HTX0TB + HC_SIMA_TX0TX1_OFF)
1530#define HC_SIMA_HTX1MPMD (HC_SIMA_HTX0MPMD + HC_SIMA_TX0TX1_OFF)
1531#define HC_SIMA_HTX1CLODu (HC_SIMA_HTX0CLODu + HC_SIMA_TX0TX1_OFF)
1532#define HC_SIMA_HTX1FM (HC_SIMA_HTX0FM + HC_SIMA_TX0TX1_OFF)
1533#define HC_SIMA_HTX1TRCH (HC_SIMA_HTX0TRCH + HC_SIMA_TX0TX1_OFF)
1534#define HC_SIMA_HTX1TRCL (HC_SIMA_HTX0TRCL + HC_SIMA_TX0TX1_OFF)
1535#define HC_SIMA_HTX1TBC (HC_SIMA_HTX0TBC + HC_SIMA_TX0TX1_OFF)
1536#define HC_SIMA_HTX1TRAH (HC_SIMA_HTX0TRAH + HC_SIMA_TX0TX1_OFF)
1537#define HC_SIMA_HTX1LTC (HC_SIMA_HTX0LTC + HC_SIMA_TX0TX1_OFF)
1538#define HC_SIMA_HTX1LTA (HC_SIMA_HTX0LTA + HC_SIMA_TX0TX1_OFF)
1539#define HC_SIMA_HTX1TBLCsat (HC_SIMA_HTX0TBLCsat + HC_SIMA_TX0TX1_OFF)
1540#define HC_SIMA_HTX1TBLCop (HC_SIMA_HTX0TBLCop + HC_SIMA_TX0TX1_OFF)
1541#define HC_SIMA_HTX1TBLMPfog (HC_SIMA_HTX0TBLMPfog + HC_SIMA_TX0TX1_OFF)
1542#define HC_SIMA_HTX1TBLAsat (HC_SIMA_HTX0TBLAsat + HC_SIMA_TX0TX1_OFF)
1543#define HC_SIMA_HTX1TBLRCa (HC_SIMA_HTX0TBLRCa + HC_SIMA_TX0TX1_OFF)
1544#define HC_SIMA_HTX1TBLRCb (HC_SIMA_HTX0TBLRCb + HC_SIMA_TX0TX1_OFF)
1545#define HC_SIMA_HTX1TBLRCc (HC_SIMA_HTX0TBLRCc + HC_SIMA_TX0TX1_OFF)
1546#define HC_SIMA_HTX1TBLRCbias (HC_SIMA_HTX0TBLRCbias + HC_SIMA_TX0TX1_OFF)
1547#define HC_SIMA_HTX1TBLRAa (HC_SIMA_HTX0TBLRAa + HC_SIMA_TX0TX1_OFF)
1548#define HC_SIMA_HTX1TBLRFog (HC_SIMA_HTX0TBLRFog + HC_SIMA_TX0TX1_OFF)
1549#define HC_SIMA_HTX1BumpM00 (HC_SIMA_HTX0BumpM00 + HC_SIMA_TX0TX1_OFF)
1550#define HC_SIMA_HTX1BumpM01 (HC_SIMA_HTX0BumpM01 + HC_SIMA_TX0TX1_OFF)
1551#define HC_SIMA_HTX1BumpM10 (HC_SIMA_HTX0BumpM10 + HC_SIMA_TX0TX1_OFF)
1552#define HC_SIMA_HTX1BumpM11 (HC_SIMA_HTX0BumpM11 + HC_SIMA_TX0TX1_OFF)
1553#define HC_SIMA_HTX1LScale (HC_SIMA_HTX0LScale + HC_SIMA_TX0TX1_OFF)
1554/*---- end of texture 1 setting ---- 0xaf
1555 */
1556#define HC_SIMA_HTXSMD 0x00b0
1557#define HC_SIMA_HenFIFOAT 0x00b1
1558#define HC_SIMA_HFBDrawFirst 0x00b2
1559#define HC_SIMA_HFBBasL 0x00b3
1560#define HC_SIMA_HTArbRCM 0x00b4
1561#define HC_SIMA_HTArbRZ 0x00b5
1562#define HC_SIMA_HTArbWZ 0x00b6
1563#define HC_SIMA_HTArbRTX 0x00b7
1564#define HC_SIMA_HTArbRCW 0x00b8
1565#define HC_SIMA_HTArbE2 0x00b9
1566#define HC_SIMA_HGEMITout 0x00ba
1567#define HC_SIMA_HFthRTXD 0x00bb
1568#define HC_SIMA_HFthRTXA 0x00bc
1569/* Define the texture palette 0
1570 */
1571#define HC_SIMA_HTP0 0x0100
1572#define HC_SIMA_HTP1 0x0200
1573#define HC_SIMA_FOGTABLE 0x0300
1574#define HC_SIMA_STIPPLE 0x0400
1575#define HC_SIMA_HE3Fire 0x0440
1576#define HC_SIMA_TRANS_SET 0x0441
1577#define HC_SIMA_HREngSt 0x0442
1578#define HC_SIMA_HRFIFOempty 0x0443
1579#define HC_SIMA_HRFIFOfull 0x0444
1580#define HC_SIMA_HRErr 0x0445
1581#define HC_SIMA_FIFOstatus 0x0446
1582
1583/******************************************************************************
1584** Define the AGP command header.
1585******************************************************************************/
1586#define HC_ACMD_MASK 0xfe000000
1587#define HC_ACMD_SUB_MASK 0x0c000000
1588#define HC_ACMD_HCmdA 0xee000000
1589#define HC_ACMD_HCmdB 0xec000000
1590#define HC_ACMD_HCmdC 0xea000000
1591#define HC_ACMD_H1 0xf0000000
1592#define HC_ACMD_H2 0xf2000000
1593#define HC_ACMD_H3 0xf4000000
1594#define HC_ACMD_H4 0xf6000000
1595
1596#define HC_ACMD_H1IO_MASK 0x000001ff
1597#define HC_ACMD_H2IO1_MASK 0x001ff000
1598#define HC_ACMD_H2IO2_MASK 0x000001ff
1599#define HC_ACMD_H2IO1_SHIFT 12
1600#define HC_ACMD_H2IO2_SHIFT 0
1601#define HC_ACMD_H3IO_MASK 0x000001ff
1602#define HC_ACMD_H3COUNT_MASK 0x01fff000
1603#define HC_ACMD_H3COUNT_SHIFT 12
1604#define HC_ACMD_H4ID_MASK 0x000001ff
1605#define HC_ACMD_H4COUNT_MASK 0x01fffe00
1606#define HC_ACMD_H4COUNT_SHIFT 9
1607
1608/********************************************************************************
1609** Define Header
1610********************************************************************************/
1611#define HC_HEADER2 0xF210F110
1612
1613/********************************************************************************
1614** Define Dummy Value
1615********************************************************************************/
1616#define HC_DUMMY 0xCCCCCCCC
1617/********************************************************************************
1618** Define for DMA use
1619********************************************************************************/
1620#define HALCYON_HEADER2 0XF210F110
1621#define HALCYON_FIRECMD 0XEE100000
1622#define HALCYON_FIREMASK 0XFFF00000
1623#define HALCYON_CMDB 0XEC000000
1624#define HALCYON_CMDBMASK 0XFFFE0000
1625#define HALCYON_SUB_ADDR0 0X00000000
1626#define HALCYON_HEADER1MASK 0XFFFFFC00
1627#define HALCYON_HEADER1 0XF0000000
1628#define HC_SubA_HAGPBstL 0x0060
1629#define HC_SubA_HAGPBendL 0x0061
1630#define HC_SubA_HAGPCMNT 0x0062
1631#define HC_SubA_HAGPBpL 0x0063
1632#define HC_SubA_HAGPBpH 0x0064
1633#define HC_HAGPCMNT_MASK 0x00800000
1634#define HC_HCmdErrClr_MASK 0x00400000
1635#define HC_HAGPBendH_MASK 0x0000ff00
1636#define HC_HAGPBstH_MASK 0x000000ff
1637#define HC_HAGPBendH_SHIFT 8
1638#define HC_HAGPBstH_SHIFT 0
1639#define HC_HAGPBpL_MASK 0x00fffffc
1640#define HC_HAGPBpID_MASK 0x00000003
1641#define HC_HAGPBpID_PAUSE 0x00000000
1642#define HC_HAGPBpID_JUMP 0x00000001
1643#define HC_HAGPBpID_STOP 0x00000002
1644#define HC_HAGPBpH_MASK 0x00ffffff
1645
1646#define VIA_VIDEO_HEADER5 0xFE040000
1647#define VIA_VIDEO_HEADER6 0xFE050000
1648#define VIA_VIDEO_HEADER7 0xFE060000
1649#define VIA_VIDEOMASK 0xFFFF0000
1650#endif
diff --git a/drivers/char/drm/via_dma.c b/drivers/char/drm/via_dma.c
deleted file mode 100644
index 7a339dba6a69..000000000000
--- a/drivers/char/drm/via_dma.c
+++ /dev/null
@@ -1,755 +0,0 @@
1/* via_dma.c -- DMA support for the VIA Unichrome/Pro
2 *
3 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
4 * All Rights Reserved.
5 *
6 * Copyright 2004 Digeo, Inc., Palo Alto, CA, U.S.A.
7 * All Rights Reserved.
8 *
9 * Copyright 2004 The Unichrome project.
10 * All Rights Reserved.
11 *
12 * Permission is hereby granted, free of charge, to any person obtaining a
13 * copy of this software and associated documentation files (the "Software"),
14 * to deal in the Software without restriction, including without limitation
15 * the rights to use, copy, modify, merge, publish, distribute, sub license,
16 * and/or sell copies of the Software, and to permit persons to whom the
17 * Software is furnished to do so, subject to the following conditions:
18 *
19 * The above copyright notice and this permission notice (including the
20 * next paragraph) shall be included in all copies or substantial portions
21 * of the Software.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
24 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
26 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
27 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
28 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
29 * USE OR OTHER DEALINGS IN THE SOFTWARE.
30 *
31 * Authors:
32 * Tungsten Graphics,
33 * Erdi Chen,
34 * Thomas Hellstrom.
35 */
36
37#include "drmP.h"
38#include "drm.h"
39#include "via_drm.h"
40#include "via_drv.h"
41#include "via_3d_reg.h"
42
43#define CMDBUF_ALIGNMENT_SIZE (0x100)
44#define CMDBUF_ALIGNMENT_MASK (0x0ff)
45
46/* defines for VIA 3D registers */
47#define VIA_REG_STATUS 0x400
48#define VIA_REG_TRANSET 0x43C
49#define VIA_REG_TRANSPACE 0x440
50
51/* VIA_REG_STATUS(0x400): Engine Status */
52#define VIA_CMD_RGTR_BUSY 0x00000080 /* Command Regulator is busy */
53#define VIA_2D_ENG_BUSY 0x00000001 /* 2D Engine is busy */
54#define VIA_3D_ENG_BUSY 0x00000002 /* 3D Engine is busy */
55#define VIA_VR_QUEUE_BUSY 0x00020000 /* Virtual Queue is busy */
56
57#define SetReg2DAGP(nReg, nData) { \
58 *((uint32_t *)(vb)) = ((nReg) >> 2) | HALCYON_HEADER1; \
59 *((uint32_t *)(vb) + 1) = (nData); \
60 vb = ((uint32_t *)vb) + 2; \
61 dev_priv->dma_low +=8; \
62}
63
64#define via_flush_write_combine() DRM_MEMORYBARRIER()
65
66#define VIA_OUT_RING_QW(w1,w2) \
67 *vb++ = (w1); \
68 *vb++ = (w2); \
69 dev_priv->dma_low += 8;
70
71static void via_cmdbuf_start(drm_via_private_t * dev_priv);
72static void via_cmdbuf_pause(drm_via_private_t * dev_priv);
73static void via_cmdbuf_reset(drm_via_private_t * dev_priv);
74static void via_cmdbuf_rewind(drm_via_private_t * dev_priv);
75static int via_wait_idle(drm_via_private_t * dev_priv);
76static void via_pad_cache(drm_via_private_t * dev_priv, int qwords);
77
78/*
79 * Free space in command buffer.
80 */
81
82static uint32_t via_cmdbuf_space(drm_via_private_t * dev_priv)
83{
84 uint32_t agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr;
85 uint32_t hw_addr = *(dev_priv->hw_addr_ptr) - agp_base;
86
87 return ((hw_addr <= dev_priv->dma_low) ?
88 (dev_priv->dma_high + hw_addr - dev_priv->dma_low) :
89 (hw_addr - dev_priv->dma_low));
90}
91
92/*
93 * How much does the command regulator lag behind?
94 */
95
96static uint32_t via_cmdbuf_lag(drm_via_private_t * dev_priv)
97{
98 uint32_t agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr;
99 uint32_t hw_addr = *(dev_priv->hw_addr_ptr) - agp_base;
100
101 return ((hw_addr <= dev_priv->dma_low) ?
102 (dev_priv->dma_low - hw_addr) :
103 (dev_priv->dma_wrap + dev_priv->dma_low - hw_addr));
104}
105
106/*
107 * Check that the given size fits in the buffer, otherwise wait.
108 */
109
110static inline int
111via_cmdbuf_wait(drm_via_private_t * dev_priv, unsigned int size)
112{
113 uint32_t agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr;
114 uint32_t cur_addr, hw_addr, next_addr;
115 volatile uint32_t *hw_addr_ptr;
116 uint32_t count;
117 hw_addr_ptr = dev_priv->hw_addr_ptr;
118 cur_addr = dev_priv->dma_low;
119 next_addr = cur_addr + size + 512 * 1024;
120 count = 1000000;
121 do {
122 hw_addr = *hw_addr_ptr - agp_base;
123 if (count-- == 0) {
124 DRM_ERROR
125 ("via_cmdbuf_wait timed out hw %x cur_addr %x next_addr %x\n",
126 hw_addr, cur_addr, next_addr);
127 return -1;
128 }
129 if ((cur_addr < hw_addr) && (next_addr >= hw_addr))
130 msleep(1);
131 } while ((cur_addr < hw_addr) && (next_addr >= hw_addr));
132 return 0;
133}
134
135/*
136 * Checks whether buffer head has reach the end. Rewind the ring buffer
137 * when necessary.
138 *
139 * Returns virtual pointer to ring buffer.
140 */
141
142static inline uint32_t *via_check_dma(drm_via_private_t * dev_priv,
143 unsigned int size)
144{
145 if ((dev_priv->dma_low + size + 4 * CMDBUF_ALIGNMENT_SIZE) >
146 dev_priv->dma_high) {
147 via_cmdbuf_rewind(dev_priv);
148 }
149 if (via_cmdbuf_wait(dev_priv, size) != 0) {
150 return NULL;
151 }
152
153 return (uint32_t *) (dev_priv->dma_ptr + dev_priv->dma_low);
154}
155
156int via_dma_cleanup(struct drm_device * dev)
157{
158 if (dev->dev_private) {
159 drm_via_private_t *dev_priv =
160 (drm_via_private_t *) dev->dev_private;
161
162 if (dev_priv->ring.virtual_start) {
163 via_cmdbuf_reset(dev_priv);
164
165 drm_core_ioremapfree(&dev_priv->ring.map, dev);
166 dev_priv->ring.virtual_start = NULL;
167 }
168
169 }
170
171 return 0;
172}
173
174static int via_initialize(struct drm_device * dev,
175 drm_via_private_t * dev_priv,
176 drm_via_dma_init_t * init)
177{
178 if (!dev_priv || !dev_priv->mmio) {
179 DRM_ERROR("via_dma_init called before via_map_init\n");
180 return -EFAULT;
181 }
182
183 if (dev_priv->ring.virtual_start != NULL) {
184 DRM_ERROR("called again without calling cleanup\n");
185 return -EFAULT;
186 }
187
188 if (!dev->agp || !dev->agp->base) {
189 DRM_ERROR("called with no agp memory available\n");
190 return -EFAULT;
191 }
192
193 if (dev_priv->chipset == VIA_DX9_0) {
194 DRM_ERROR("AGP DMA is not supported on this chip\n");
195 return -EINVAL;
196 }
197
198 dev_priv->ring.map.offset = dev->agp->base + init->offset;
199 dev_priv->ring.map.size = init->size;
200 dev_priv->ring.map.type = 0;
201 dev_priv->ring.map.flags = 0;
202 dev_priv->ring.map.mtrr = 0;
203
204 drm_core_ioremap(&dev_priv->ring.map, dev);
205
206 if (dev_priv->ring.map.handle == NULL) {
207 via_dma_cleanup(dev);
208 DRM_ERROR("can not ioremap virtual address for"
209 " ring buffer\n");
210 return -ENOMEM;
211 }
212
213 dev_priv->ring.virtual_start = dev_priv->ring.map.handle;
214
215 dev_priv->dma_ptr = dev_priv->ring.virtual_start;
216 dev_priv->dma_low = 0;
217 dev_priv->dma_high = init->size;
218 dev_priv->dma_wrap = init->size;
219 dev_priv->dma_offset = init->offset;
220 dev_priv->last_pause_ptr = NULL;
221 dev_priv->hw_addr_ptr =
222 (volatile uint32_t *)((char *)dev_priv->mmio->handle +
223 init->reg_pause_addr);
224
225 via_cmdbuf_start(dev_priv);
226
227 return 0;
228}
229
230static int via_dma_init(struct drm_device *dev, void *data, struct drm_file *file_priv)
231{
232 drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
233 drm_via_dma_init_t *init = data;
234 int retcode = 0;
235
236 switch (init->func) {
237 case VIA_INIT_DMA:
238 if (!DRM_SUSER(DRM_CURPROC))
239 retcode = -EPERM;
240 else
241 retcode = via_initialize(dev, dev_priv, init);
242 break;
243 case VIA_CLEANUP_DMA:
244 if (!DRM_SUSER(DRM_CURPROC))
245 retcode = -EPERM;
246 else
247 retcode = via_dma_cleanup(dev);
248 break;
249 case VIA_DMA_INITIALIZED:
250 retcode = (dev_priv->ring.virtual_start != NULL) ?
251 0 : -EFAULT;
252 break;
253 default:
254 retcode = -EINVAL;
255 break;
256 }
257
258 return retcode;
259}
260
261static int via_dispatch_cmdbuffer(struct drm_device * dev, drm_via_cmdbuffer_t * cmd)
262{
263 drm_via_private_t *dev_priv;
264 uint32_t *vb;
265 int ret;
266
267 dev_priv = (drm_via_private_t *) dev->dev_private;
268
269 if (dev_priv->ring.virtual_start == NULL) {
270 DRM_ERROR("called without initializing AGP ring buffer.\n");
271 return -EFAULT;
272 }
273
274 if (cmd->size > VIA_PCI_BUF_SIZE) {
275 return -ENOMEM;
276 }
277
278 if (DRM_COPY_FROM_USER(dev_priv->pci_buf, cmd->buf, cmd->size))
279 return -EFAULT;
280
281 /*
282 * Running this function on AGP memory is dead slow. Therefore
283 * we run it on a temporary cacheable system memory buffer and
284 * copy it to AGP memory when ready.
285 */
286
287 if ((ret =
288 via_verify_command_stream((uint32_t *) dev_priv->pci_buf,
289 cmd->size, dev, 1))) {
290 return ret;
291 }
292
293 vb = via_check_dma(dev_priv, (cmd->size < 0x100) ? 0x102 : cmd->size);
294 if (vb == NULL) {
295 return -EAGAIN;
296 }
297
298 memcpy(vb, dev_priv->pci_buf, cmd->size);
299
300 dev_priv->dma_low += cmd->size;
301
302 /*
303 * Small submissions somehow stalls the CPU. (AGP cache effects?)
304 * pad to greater size.
305 */
306
307 if (cmd->size < 0x100)
308 via_pad_cache(dev_priv, (0x100 - cmd->size) >> 3);
309 via_cmdbuf_pause(dev_priv);
310
311 return 0;
312}
313
314int via_driver_dma_quiescent(struct drm_device * dev)
315{
316 drm_via_private_t *dev_priv = dev->dev_private;
317
318 if (!via_wait_idle(dev_priv)) {
319 return -EBUSY;
320 }
321 return 0;
322}
323
324static int via_flush_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv)
325{
326
327 LOCK_TEST_WITH_RETURN(dev, file_priv);
328
329 return via_driver_dma_quiescent(dev);
330}
331
332static int via_cmdbuffer(struct drm_device *dev, void *data, struct drm_file *file_priv)
333{
334 drm_via_cmdbuffer_t *cmdbuf = data;
335 int ret;
336
337 LOCK_TEST_WITH_RETURN(dev, file_priv);
338
339 DRM_DEBUG("buf %p size %lu\n", cmdbuf->buf, cmdbuf->size);
340
341 ret = via_dispatch_cmdbuffer(dev, cmdbuf);
342 if (ret) {
343 return ret;
344 }
345
346 return 0;
347}
348
349static int via_dispatch_pci_cmdbuffer(struct drm_device * dev,
350 drm_via_cmdbuffer_t * cmd)
351{
352 drm_via_private_t *dev_priv = dev->dev_private;
353 int ret;
354
355 if (cmd->size > VIA_PCI_BUF_SIZE) {
356 return -ENOMEM;
357 }
358 if (DRM_COPY_FROM_USER(dev_priv->pci_buf, cmd->buf, cmd->size))
359 return -EFAULT;
360
361 if ((ret =
362 via_verify_command_stream((uint32_t *) dev_priv->pci_buf,
363 cmd->size, dev, 0))) {
364 return ret;
365 }
366
367 ret =
368 via_parse_command_stream(dev, (const uint32_t *)dev_priv->pci_buf,
369 cmd->size);
370 return ret;
371}
372
373static int via_pci_cmdbuffer(struct drm_device *dev, void *data, struct drm_file *file_priv)
374{
375 drm_via_cmdbuffer_t *cmdbuf = data;
376 int ret;
377
378 LOCK_TEST_WITH_RETURN(dev, file_priv);
379
380 DRM_DEBUG("buf %p size %lu\n", cmdbuf->buf, cmdbuf->size);
381
382 ret = via_dispatch_pci_cmdbuffer(dev, cmdbuf);
383 if (ret) {
384 return ret;
385 }
386
387 return 0;
388}
389
390static inline uint32_t *via_align_buffer(drm_via_private_t * dev_priv,
391 uint32_t * vb, int qw_count)
392{
393 for (; qw_count > 0; --qw_count) {
394 VIA_OUT_RING_QW(HC_DUMMY, HC_DUMMY);
395 }
396 return vb;
397}
398
399/*
400 * This function is used internally by ring buffer management code.
401 *
402 * Returns virtual pointer to ring buffer.
403 */
404static inline uint32_t *via_get_dma(drm_via_private_t * dev_priv)
405{
406 return (uint32_t *) (dev_priv->dma_ptr + dev_priv->dma_low);
407}
408
409/*
410 * Hooks a segment of data into the tail of the ring-buffer by
411 * modifying the pause address stored in the buffer itself. If
412 * the regulator has already paused, restart it.
413 */
414static int via_hook_segment(drm_via_private_t * dev_priv,
415 uint32_t pause_addr_hi, uint32_t pause_addr_lo,
416 int no_pci_fire)
417{
418 int paused, count;
419 volatile uint32_t *paused_at = dev_priv->last_pause_ptr;
420 uint32_t reader,ptr;
421 uint32_t diff;
422
423 paused = 0;
424 via_flush_write_combine();
425 (void) *(volatile uint32_t *)(via_get_dma(dev_priv) -1);
426
427 *paused_at = pause_addr_lo;
428 via_flush_write_combine();
429 (void) *paused_at;
430
431 reader = *(dev_priv->hw_addr_ptr);
432 ptr = ((volatile char *)paused_at - dev_priv->dma_ptr) +
433 dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr + 4;
434
435 dev_priv->last_pause_ptr = via_get_dma(dev_priv) - 1;
436
437 /*
438 * If there is a possibility that the command reader will
439 * miss the new pause address and pause on the old one,
440 * In that case we need to program the new start address
441 * using PCI.
442 */
443
444 diff = (uint32_t) (ptr - reader) - dev_priv->dma_diff;
445 count = 10000000;
446 while(diff == 0 && count--) {
447 paused = (VIA_READ(0x41c) & 0x80000000);
448 if (paused)
449 break;
450 reader = *(dev_priv->hw_addr_ptr);
451 diff = (uint32_t) (ptr - reader) - dev_priv->dma_diff;
452 }
453
454 paused = VIA_READ(0x41c) & 0x80000000;
455
456 if (paused && !no_pci_fire) {
457 reader = *(dev_priv->hw_addr_ptr);
458 diff = (uint32_t) (ptr - reader) - dev_priv->dma_diff;
459 diff &= (dev_priv->dma_high - 1);
460 if (diff != 0 && diff < (dev_priv->dma_high >> 1)) {
461 DRM_ERROR("Paused at incorrect address. "
462 "0x%08x, 0x%08x 0x%08x\n",
463 ptr, reader, dev_priv->dma_diff);
464 } else if (diff == 0) {
465 /*
466 * There is a concern that these writes may stall the PCI bus
467 * if the GPU is not idle. However, idling the GPU first
468 * doesn't make a difference.
469 */
470
471 VIA_WRITE(VIA_REG_TRANSET, (HC_ParaType_PreCR << 16));
472 VIA_WRITE(VIA_REG_TRANSPACE, pause_addr_hi);
473 VIA_WRITE(VIA_REG_TRANSPACE, pause_addr_lo);
474 VIA_READ(VIA_REG_TRANSPACE);
475 }
476 }
477 return paused;
478}
479
480static int via_wait_idle(drm_via_private_t * dev_priv)
481{
482 int count = 10000000;
483
484 while (!(VIA_READ(VIA_REG_STATUS) & VIA_VR_QUEUE_BUSY) && count--);
485
486 while (count-- && (VIA_READ(VIA_REG_STATUS) &
487 (VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY |
488 VIA_3D_ENG_BUSY))) ;
489 return count;
490}
491
492static uint32_t *via_align_cmd(drm_via_private_t * dev_priv, uint32_t cmd_type,
493 uint32_t addr, uint32_t * cmd_addr_hi,
494 uint32_t * cmd_addr_lo, int skip_wait)
495{
496 uint32_t agp_base;
497 uint32_t cmd_addr, addr_lo, addr_hi;
498 uint32_t *vb;
499 uint32_t qw_pad_count;
500
501 if (!skip_wait)
502 via_cmdbuf_wait(dev_priv, 2 * CMDBUF_ALIGNMENT_SIZE);
503
504 vb = via_get_dma(dev_priv);
505 VIA_OUT_RING_QW(HC_HEADER2 | ((VIA_REG_TRANSET >> 2) << 12) |
506 (VIA_REG_TRANSPACE >> 2), HC_ParaType_PreCR << 16);
507 agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr;
508 qw_pad_count = (CMDBUF_ALIGNMENT_SIZE >> 3) -
509 ((dev_priv->dma_low & CMDBUF_ALIGNMENT_MASK) >> 3);
510
511 cmd_addr = (addr) ? addr :
512 agp_base + dev_priv->dma_low - 8 + (qw_pad_count << 3);
513 addr_lo = ((HC_SubA_HAGPBpL << 24) | (cmd_type & HC_HAGPBpID_MASK) |
514 (cmd_addr & HC_HAGPBpL_MASK));
515 addr_hi = ((HC_SubA_HAGPBpH << 24) | (cmd_addr >> 24));
516
517 vb = via_align_buffer(dev_priv, vb, qw_pad_count - 1);
518 VIA_OUT_RING_QW(*cmd_addr_hi = addr_hi, *cmd_addr_lo = addr_lo);
519 return vb;
520}
521
522static void via_cmdbuf_start(drm_via_private_t * dev_priv)
523{
524 uint32_t pause_addr_lo, pause_addr_hi;
525 uint32_t start_addr, start_addr_lo;
526 uint32_t end_addr, end_addr_lo;
527 uint32_t command;
528 uint32_t agp_base;
529 uint32_t ptr;
530 uint32_t reader;
531 int count;
532
533 dev_priv->dma_low = 0;
534
535 agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr;
536 start_addr = agp_base;
537 end_addr = agp_base + dev_priv->dma_high;
538
539 start_addr_lo = ((HC_SubA_HAGPBstL << 24) | (start_addr & 0xFFFFFF));
540 end_addr_lo = ((HC_SubA_HAGPBendL << 24) | (end_addr & 0xFFFFFF));
541 command = ((HC_SubA_HAGPCMNT << 24) | (start_addr >> 24) |
542 ((end_addr & 0xff000000) >> 16));
543
544 dev_priv->last_pause_ptr =
545 via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0,
546 &pause_addr_hi, &pause_addr_lo, 1) - 1;
547
548 via_flush_write_combine();
549 (void) *(volatile uint32_t *)dev_priv->last_pause_ptr;
550
551 VIA_WRITE(VIA_REG_TRANSET, (HC_ParaType_PreCR << 16));
552 VIA_WRITE(VIA_REG_TRANSPACE, command);
553 VIA_WRITE(VIA_REG_TRANSPACE, start_addr_lo);
554 VIA_WRITE(VIA_REG_TRANSPACE, end_addr_lo);
555
556 VIA_WRITE(VIA_REG_TRANSPACE, pause_addr_hi);
557 VIA_WRITE(VIA_REG_TRANSPACE, pause_addr_lo);
558 DRM_WRITEMEMORYBARRIER();
559 VIA_WRITE(VIA_REG_TRANSPACE, command | HC_HAGPCMNT_MASK);
560 VIA_READ(VIA_REG_TRANSPACE);
561
562 dev_priv->dma_diff = 0;
563
564 count = 10000000;
565 while (!(VIA_READ(0x41c) & 0x80000000) && count--);
566
567 reader = *(dev_priv->hw_addr_ptr);
568 ptr = ((volatile char *)dev_priv->last_pause_ptr - dev_priv->dma_ptr) +
569 dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr + 4;
570
571 /*
572 * This is the difference between where we tell the
573 * command reader to pause and where it actually pauses.
574 * This differs between hw implementation so we need to
575 * detect it.
576 */
577
578 dev_priv->dma_diff = ptr - reader;
579}
580
581static void via_pad_cache(drm_via_private_t * dev_priv, int qwords)
582{
583 uint32_t *vb;
584
585 via_cmdbuf_wait(dev_priv, qwords + 2);
586 vb = via_get_dma(dev_priv);
587 VIA_OUT_RING_QW(HC_HEADER2, HC_ParaType_NotTex << 16);
588 via_align_buffer(dev_priv, vb, qwords);
589}
590
591static inline void via_dummy_bitblt(drm_via_private_t * dev_priv)
592{
593 uint32_t *vb = via_get_dma(dev_priv);
594 SetReg2DAGP(0x0C, (0 | (0 << 16)));
595 SetReg2DAGP(0x10, 0 | (0 << 16));
596 SetReg2DAGP(0x0, 0x1 | 0x2000 | 0xAA000000);
597}
598
599static void via_cmdbuf_jump(drm_via_private_t * dev_priv)
600{
601 uint32_t agp_base;
602 uint32_t pause_addr_lo, pause_addr_hi;
603 uint32_t jump_addr_lo, jump_addr_hi;
604 volatile uint32_t *last_pause_ptr;
605 uint32_t dma_low_save1, dma_low_save2;
606
607 agp_base = dev_priv->dma_offset + (uint32_t) dev_priv->agpAddr;
608 via_align_cmd(dev_priv, HC_HAGPBpID_JUMP, 0, &jump_addr_hi,
609 &jump_addr_lo, 0);
610
611 dev_priv->dma_wrap = dev_priv->dma_low;
612
613 /*
614 * Wrap command buffer to the beginning.
615 */
616
617 dev_priv->dma_low = 0;
618 if (via_cmdbuf_wait(dev_priv, CMDBUF_ALIGNMENT_SIZE) != 0) {
619 DRM_ERROR("via_cmdbuf_jump failed\n");
620 }
621
622 via_dummy_bitblt(dev_priv);
623 via_dummy_bitblt(dev_priv);
624
625 last_pause_ptr =
626 via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi,
627 &pause_addr_lo, 0) - 1;
628 via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi,
629 &pause_addr_lo, 0);
630
631 *last_pause_ptr = pause_addr_lo;
632 dma_low_save1 = dev_priv->dma_low;
633
634 /*
635 * Now, set a trap that will pause the regulator if it tries to rerun the old
636 * command buffer. (Which may happen if via_hook_segment detecs a command regulator pause
637 * and reissues the jump command over PCI, while the regulator has already taken the jump
638 * and actually paused at the current buffer end).
639 * There appears to be no other way to detect this condition, since the hw_addr_pointer
640 * does not seem to get updated immediately when a jump occurs.
641 */
642
643 last_pause_ptr =
644 via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi,
645 &pause_addr_lo, 0) - 1;
646 via_align_cmd(dev_priv, HC_HAGPBpID_PAUSE, 0, &pause_addr_hi,
647 &pause_addr_lo, 0);
648 *last_pause_ptr = pause_addr_lo;
649
650 dma_low_save2 = dev_priv->dma_low;
651 dev_priv->dma_low = dma_low_save1;
652 via_hook_segment(dev_priv, jump_addr_hi, jump_addr_lo, 0);
653 dev_priv->dma_low = dma_low_save2;
654 via_hook_segment(dev_priv, pause_addr_hi, pause_addr_lo, 0);
655}
656
657
658static void via_cmdbuf_rewind(drm_via_private_t * dev_priv)
659{
660 via_cmdbuf_jump(dev_priv);
661}
662
663static void via_cmdbuf_flush(drm_via_private_t * dev_priv, uint32_t cmd_type)
664{
665 uint32_t pause_addr_lo, pause_addr_hi;
666
667 via_align_cmd(dev_priv, cmd_type, 0, &pause_addr_hi, &pause_addr_lo, 0);
668 via_hook_segment(dev_priv, pause_addr_hi, pause_addr_lo, 0);
669}
670
671static void via_cmdbuf_pause(drm_via_private_t * dev_priv)
672{
673 via_cmdbuf_flush(dev_priv, HC_HAGPBpID_PAUSE);
674}
675
676static void via_cmdbuf_reset(drm_via_private_t * dev_priv)
677{
678 via_cmdbuf_flush(dev_priv, HC_HAGPBpID_STOP);
679 via_wait_idle(dev_priv);
680}
681
682/*
683 * User interface to the space and lag functions.
684 */
685
686static int via_cmdbuf_size(struct drm_device *dev, void *data, struct drm_file *file_priv)
687{
688 drm_via_cmdbuf_size_t *d_siz = data;
689 int ret = 0;
690 uint32_t tmp_size, count;
691 drm_via_private_t *dev_priv;
692
693 DRM_DEBUG("\n");
694 LOCK_TEST_WITH_RETURN(dev, file_priv);
695
696 dev_priv = (drm_via_private_t *) dev->dev_private;
697
698 if (dev_priv->ring.virtual_start == NULL) {
699 DRM_ERROR("called without initializing AGP ring buffer.\n");
700 return -EFAULT;
701 }
702
703 count = 1000000;
704 tmp_size = d_siz->size;
705 switch (d_siz->func) {
706 case VIA_CMDBUF_SPACE:
707 while (((tmp_size = via_cmdbuf_space(dev_priv)) < d_siz->size)
708 && count--) {
709 if (!d_siz->wait) {
710 break;
711 }
712 }
713 if (!count) {
714 DRM_ERROR("VIA_CMDBUF_SPACE timed out.\n");
715 ret = -EAGAIN;
716 }
717 break;
718 case VIA_CMDBUF_LAG:
719 while (((tmp_size = via_cmdbuf_lag(dev_priv)) > d_siz->size)
720 && count--) {
721 if (!d_siz->wait) {
722 break;
723 }
724 }
725 if (!count) {
726 DRM_ERROR("VIA_CMDBUF_LAG timed out.\n");
727 ret = -EAGAIN;
728 }
729 break;
730 default:
731 ret = -EFAULT;
732 }
733 d_siz->size = tmp_size;
734
735 return ret;
736}
737
738struct drm_ioctl_desc via_ioctls[] = {
739 DRM_IOCTL_DEF(DRM_VIA_ALLOCMEM, via_mem_alloc, DRM_AUTH),
740 DRM_IOCTL_DEF(DRM_VIA_FREEMEM, via_mem_free, DRM_AUTH),
741 DRM_IOCTL_DEF(DRM_VIA_AGP_INIT, via_agp_init, DRM_AUTH|DRM_MASTER),
742 DRM_IOCTL_DEF(DRM_VIA_FB_INIT, via_fb_init, DRM_AUTH|DRM_MASTER),
743 DRM_IOCTL_DEF(DRM_VIA_MAP_INIT, via_map_init, DRM_AUTH|DRM_MASTER),
744 DRM_IOCTL_DEF(DRM_VIA_DEC_FUTEX, via_decoder_futex, DRM_AUTH),
745 DRM_IOCTL_DEF(DRM_VIA_DMA_INIT, via_dma_init, DRM_AUTH),
746 DRM_IOCTL_DEF(DRM_VIA_CMDBUFFER, via_cmdbuffer, DRM_AUTH),
747 DRM_IOCTL_DEF(DRM_VIA_FLUSH, via_flush_ioctl, DRM_AUTH),
748 DRM_IOCTL_DEF(DRM_VIA_PCICMD, via_pci_cmdbuffer, DRM_AUTH),
749 DRM_IOCTL_DEF(DRM_VIA_CMDBUF_SIZE, via_cmdbuf_size, DRM_AUTH),
750 DRM_IOCTL_DEF(DRM_VIA_WAIT_IRQ, via_wait_irq, DRM_AUTH),
751 DRM_IOCTL_DEF(DRM_VIA_DMA_BLIT, via_dma_blit, DRM_AUTH),
752 DRM_IOCTL_DEF(DRM_VIA_BLIT_SYNC, via_dma_blit_sync, DRM_AUTH)
753};
754
755int via_max_ioctl = DRM_ARRAY_SIZE(via_ioctls);
diff --git a/drivers/char/drm/via_dmablit.c b/drivers/char/drm/via_dmablit.c
deleted file mode 100644
index 409e00afdd07..000000000000
--- a/drivers/char/drm/via_dmablit.c
+++ /dev/null
@@ -1,816 +0,0 @@
1/* via_dmablit.c -- PCI DMA BitBlt support for the VIA Unichrome/Pro
2 *
3 * Copyright (C) 2005 Thomas Hellstrom, All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sub license,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
14 * of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
21 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
22 * USE OR OTHER DEALINGS IN THE SOFTWARE.
23 *
24 * Authors:
25 * Thomas Hellstrom.
26 * Partially based on code obtained from Digeo Inc.
27 */
28
29
30/*
31 * Unmaps the DMA mappings.
32 * FIXME: Is this a NoOp on x86? Also
33 * FIXME: What happens if this one is called and a pending blit has previously done
34 * the same DMA mappings?
35 */
36
37#include "drmP.h"
38#include "via_drm.h"
39#include "via_drv.h"
40#include "via_dmablit.h"
41
42#include <linux/pagemap.h>
43
44#define VIA_PGDN(x) (((unsigned long)(x)) & PAGE_MASK)
45#define VIA_PGOFF(x) (((unsigned long)(x)) & ~PAGE_MASK)
46#define VIA_PFN(x) ((unsigned long)(x) >> PAGE_SHIFT)
47
48typedef struct _drm_via_descriptor {
49 uint32_t mem_addr;
50 uint32_t dev_addr;
51 uint32_t size;
52 uint32_t next;
53} drm_via_descriptor_t;
54
55
56/*
57 * Unmap a DMA mapping.
58 */
59
60
61
62static void
63via_unmap_blit_from_device(struct pci_dev *pdev, drm_via_sg_info_t *vsg)
64{
65 int num_desc = vsg->num_desc;
66 unsigned cur_descriptor_page = num_desc / vsg->descriptors_per_page;
67 unsigned descriptor_this_page = num_desc % vsg->descriptors_per_page;
68 drm_via_descriptor_t *desc_ptr = vsg->desc_pages[cur_descriptor_page] +
69 descriptor_this_page;
70 dma_addr_t next = vsg->chain_start;
71
72 while(num_desc--) {
73 if (descriptor_this_page-- == 0) {
74 cur_descriptor_page--;
75 descriptor_this_page = vsg->descriptors_per_page - 1;
76 desc_ptr = vsg->desc_pages[cur_descriptor_page] +
77 descriptor_this_page;
78 }
79 dma_unmap_single(&pdev->dev, next, sizeof(*desc_ptr), DMA_TO_DEVICE);
80 dma_unmap_page(&pdev->dev, desc_ptr->mem_addr, desc_ptr->size, vsg->direction);
81 next = (dma_addr_t) desc_ptr->next;
82 desc_ptr--;
83 }
84}
85
86/*
87 * If mode = 0, count how many descriptors are needed.
88 * If mode = 1, Map the DMA pages for the device, put together and map also the descriptors.
89 * Descriptors are run in reverse order by the hardware because we are not allowed to update the
90 * 'next' field without syncing calls when the descriptor is already mapped.
91 */
92
93static void
94via_map_blit_for_device(struct pci_dev *pdev,
95 const drm_via_dmablit_t *xfer,
96 drm_via_sg_info_t *vsg,
97 int mode)
98{
99 unsigned cur_descriptor_page = 0;
100 unsigned num_descriptors_this_page = 0;
101 unsigned char *mem_addr = xfer->mem_addr;
102 unsigned char *cur_mem;
103 unsigned char *first_addr = (unsigned char *)VIA_PGDN(mem_addr);
104 uint32_t fb_addr = xfer->fb_addr;
105 uint32_t cur_fb;
106 unsigned long line_len;
107 unsigned remaining_len;
108 int num_desc = 0;
109 int cur_line;
110 dma_addr_t next = 0 | VIA_DMA_DPR_EC;
111 drm_via_descriptor_t *desc_ptr = NULL;
112
113 if (mode == 1)
114 desc_ptr = vsg->desc_pages[cur_descriptor_page];
115
116 for (cur_line = 0; cur_line < xfer->num_lines; ++cur_line) {
117
118 line_len = xfer->line_length;
119 cur_fb = fb_addr;
120 cur_mem = mem_addr;
121
122 while (line_len > 0) {
123
124 remaining_len = min(PAGE_SIZE-VIA_PGOFF(cur_mem), line_len);
125 line_len -= remaining_len;
126
127 if (mode == 1) {
128 desc_ptr->mem_addr =
129 dma_map_page(&pdev->dev,
130 vsg->pages[VIA_PFN(cur_mem) -
131 VIA_PFN(first_addr)],
132 VIA_PGOFF(cur_mem), remaining_len,
133 vsg->direction);
134 desc_ptr->dev_addr = cur_fb;
135
136 desc_ptr->size = remaining_len;
137 desc_ptr->next = (uint32_t) next;
138 next = dma_map_single(&pdev->dev, desc_ptr, sizeof(*desc_ptr),
139 DMA_TO_DEVICE);
140 desc_ptr++;
141 if (++num_descriptors_this_page >= vsg->descriptors_per_page) {
142 num_descriptors_this_page = 0;
143 desc_ptr = vsg->desc_pages[++cur_descriptor_page];
144 }
145 }
146
147 num_desc++;
148 cur_mem += remaining_len;
149 cur_fb += remaining_len;
150 }
151
152 mem_addr += xfer->mem_stride;
153 fb_addr += xfer->fb_stride;
154 }
155
156 if (mode == 1) {
157 vsg->chain_start = next;
158 vsg->state = dr_via_device_mapped;
159 }
160 vsg->num_desc = num_desc;
161}
162
163/*
164 * Function that frees up all resources for a blit. It is usable even if the
165 * blit info has only been partially built as long as the status enum is consistent
166 * with the actual status of the used resources.
167 */
168
169
170static void
171via_free_sg_info(struct pci_dev *pdev, drm_via_sg_info_t *vsg)
172{
173 struct page *page;
174 int i;
175
176 switch(vsg->state) {
177 case dr_via_device_mapped:
178 via_unmap_blit_from_device(pdev, vsg);
179 case dr_via_desc_pages_alloc:
180 for (i=0; i<vsg->num_desc_pages; ++i) {
181 if (vsg->desc_pages[i] != NULL)
182 free_page((unsigned long)vsg->desc_pages[i]);
183 }
184 kfree(vsg->desc_pages);
185 case dr_via_pages_locked:
186 for (i=0; i<vsg->num_pages; ++i) {
187 if ( NULL != (page = vsg->pages[i])) {
188 if (! PageReserved(page) && (DMA_FROM_DEVICE == vsg->direction))
189 SetPageDirty(page);
190 page_cache_release(page);
191 }
192 }
193 case dr_via_pages_alloc:
194 vfree(vsg->pages);
195 default:
196 vsg->state = dr_via_sg_init;
197 }
198 if (vsg->bounce_buffer) {
199 vfree(vsg->bounce_buffer);
200 vsg->bounce_buffer = NULL;
201 }
202 vsg->free_on_sequence = 0;
203}
204
205/*
206 * Fire a blit engine.
207 */
208
209static void
210via_fire_dmablit(struct drm_device *dev, drm_via_sg_info_t *vsg, int engine)
211{
212 drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private;
213
214 VIA_WRITE(VIA_PCI_DMA_MAR0 + engine*0x10, 0);
215 VIA_WRITE(VIA_PCI_DMA_DAR0 + engine*0x10, 0);
216 VIA_WRITE(VIA_PCI_DMA_CSR0 + engine*0x04, VIA_DMA_CSR_DD | VIA_DMA_CSR_TD |
217 VIA_DMA_CSR_DE);
218 VIA_WRITE(VIA_PCI_DMA_MR0 + engine*0x04, VIA_DMA_MR_CM | VIA_DMA_MR_TDIE);
219 VIA_WRITE(VIA_PCI_DMA_BCR0 + engine*0x10, 0);
220 VIA_WRITE(VIA_PCI_DMA_DPR0 + engine*0x10, vsg->chain_start);
221 DRM_WRITEMEMORYBARRIER();
222 VIA_WRITE(VIA_PCI_DMA_CSR0 + engine*0x04, VIA_DMA_CSR_DE | VIA_DMA_CSR_TS);
223 VIA_READ(VIA_PCI_DMA_CSR0 + engine*0x04);
224}
225
226/*
227 * Obtain a page pointer array and lock all pages into system memory. A segmentation violation will
228 * occur here if the calling user does not have access to the submitted address.
229 */
230
231static int
232via_lock_all_dma_pages(drm_via_sg_info_t *vsg, drm_via_dmablit_t *xfer)
233{
234 int ret;
235 unsigned long first_pfn = VIA_PFN(xfer->mem_addr);
236 vsg->num_pages = VIA_PFN(xfer->mem_addr + (xfer->num_lines * xfer->mem_stride -1)) -
237 first_pfn + 1;
238
239 if (NULL == (vsg->pages = vmalloc(sizeof(struct page *) * vsg->num_pages)))
240 return -ENOMEM;
241 memset(vsg->pages, 0, sizeof(struct page *) * vsg->num_pages);
242 down_read(&current->mm->mmap_sem);
243 ret = get_user_pages(current, current->mm,
244 (unsigned long)xfer->mem_addr,
245 vsg->num_pages,
246 (vsg->direction == DMA_FROM_DEVICE),
247 0, vsg->pages, NULL);
248
249 up_read(&current->mm->mmap_sem);
250 if (ret != vsg->num_pages) {
251 if (ret < 0)
252 return ret;
253 vsg->state = dr_via_pages_locked;
254 return -EINVAL;
255 }
256 vsg->state = dr_via_pages_locked;
257 DRM_DEBUG("DMA pages locked\n");
258 return 0;
259}
260
261/*
262 * Allocate DMA capable memory for the blit descriptor chain, and an array that keeps track of the
263 * pages we allocate. We don't want to use kmalloc for the descriptor chain because it may be
264 * quite large for some blits, and pages don't need to be contingous.
265 */
266
267static int
268via_alloc_desc_pages(drm_via_sg_info_t *vsg)
269{
270 int i;
271
272 vsg->descriptors_per_page = PAGE_SIZE / sizeof( drm_via_descriptor_t);
273 vsg->num_desc_pages = (vsg->num_desc + vsg->descriptors_per_page - 1) /
274 vsg->descriptors_per_page;
275
276 if (NULL == (vsg->desc_pages = kcalloc(vsg->num_desc_pages, sizeof(void *), GFP_KERNEL)))
277 return -ENOMEM;
278
279 vsg->state = dr_via_desc_pages_alloc;
280 for (i=0; i<vsg->num_desc_pages; ++i) {
281 if (NULL == (vsg->desc_pages[i] =
282 (drm_via_descriptor_t *) __get_free_page(GFP_KERNEL)))
283 return -ENOMEM;
284 }
285 DRM_DEBUG("Allocated %d pages for %d descriptors.\n", vsg->num_desc_pages,
286 vsg->num_desc);
287 return 0;
288}
289
290static void
291via_abort_dmablit(struct drm_device *dev, int engine)
292{
293 drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private;
294
295 VIA_WRITE(VIA_PCI_DMA_CSR0 + engine*0x04, VIA_DMA_CSR_TA);
296}
297
298static void
299via_dmablit_engine_off(struct drm_device *dev, int engine)
300{
301 drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private;
302
303 VIA_WRITE(VIA_PCI_DMA_CSR0 + engine*0x04, VIA_DMA_CSR_TD | VIA_DMA_CSR_DD);
304}
305
306
307
308/*
309 * The dmablit part of the IRQ handler. Trying to do only reasonably fast things here.
310 * The rest, like unmapping and freeing memory for done blits is done in a separate workqueue
311 * task. Basically the task of the interrupt handler is to submit a new blit to the engine, while
312 * the workqueue task takes care of processing associated with the old blit.
313 */
314
315void
316via_dmablit_handler(struct drm_device *dev, int engine, int from_irq)
317{
318 drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private;
319 drm_via_blitq_t *blitq = dev_priv->blit_queues + engine;
320 int cur;
321 int done_transfer;
322 unsigned long irqsave=0;
323 uint32_t status = 0;
324
325 DRM_DEBUG("DMA blit handler called. engine = %d, from_irq = %d, blitq = 0x%lx\n",
326 engine, from_irq, (unsigned long) blitq);
327
328 if (from_irq) {
329 spin_lock(&blitq->blit_lock);
330 } else {
331 spin_lock_irqsave(&blitq->blit_lock, irqsave);
332 }
333
334 done_transfer = blitq->is_active &&
335 (( status = VIA_READ(VIA_PCI_DMA_CSR0 + engine*0x04)) & VIA_DMA_CSR_TD);
336 done_transfer = done_transfer || ( blitq->aborting && !(status & VIA_DMA_CSR_DE));
337
338 cur = blitq->cur;
339 if (done_transfer) {
340
341 blitq->blits[cur]->aborted = blitq->aborting;
342 blitq->done_blit_handle++;
343 DRM_WAKEUP(blitq->blit_queue + cur);
344
345 cur++;
346 if (cur >= VIA_NUM_BLIT_SLOTS)
347 cur = 0;
348 blitq->cur = cur;
349
350 /*
351 * Clear transfer done flag.
352 */
353
354 VIA_WRITE(VIA_PCI_DMA_CSR0 + engine*0x04, VIA_DMA_CSR_TD);
355
356 blitq->is_active = 0;
357 blitq->aborting = 0;
358 schedule_work(&blitq->wq);
359
360 } else if (blitq->is_active && time_after_eq(jiffies, blitq->end)) {
361
362 /*
363 * Abort transfer after one second.
364 */
365
366 via_abort_dmablit(dev, engine);
367 blitq->aborting = 1;
368 blitq->end = jiffies + DRM_HZ;
369 }
370
371 if (!blitq->is_active) {
372 if (blitq->num_outstanding) {
373 via_fire_dmablit(dev, blitq->blits[cur], engine);
374 blitq->is_active = 1;
375 blitq->cur = cur;
376 blitq->num_outstanding--;
377 blitq->end = jiffies + DRM_HZ;
378 if (!timer_pending(&blitq->poll_timer))
379 mod_timer(&blitq->poll_timer, jiffies + 1);
380 } else {
381 if (timer_pending(&blitq->poll_timer)) {
382 del_timer(&blitq->poll_timer);
383 }
384 via_dmablit_engine_off(dev, engine);
385 }
386 }
387
388 if (from_irq) {
389 spin_unlock(&blitq->blit_lock);
390 } else {
391 spin_unlock_irqrestore(&blitq->blit_lock, irqsave);
392 }
393}
394
395
396
397/*
398 * Check whether this blit is still active, performing necessary locking.
399 */
400
401static int
402via_dmablit_active(drm_via_blitq_t *blitq, int engine, uint32_t handle, wait_queue_head_t **queue)
403{
404 unsigned long irqsave;
405 uint32_t slot;
406 int active;
407
408 spin_lock_irqsave(&blitq->blit_lock, irqsave);
409
410 /*
411 * Allow for handle wraparounds.
412 */
413
414 active = ((blitq->done_blit_handle - handle) > (1 << 23)) &&
415 ((blitq->cur_blit_handle - handle) <= (1 << 23));
416
417 if (queue && active) {
418 slot = handle - blitq->done_blit_handle + blitq->cur -1;
419 if (slot >= VIA_NUM_BLIT_SLOTS) {
420 slot -= VIA_NUM_BLIT_SLOTS;
421 }
422 *queue = blitq->blit_queue + slot;
423 }
424
425 spin_unlock_irqrestore(&blitq->blit_lock, irqsave);
426
427 return active;
428}
429
430/*
431 * Sync. Wait for at least three seconds for the blit to be performed.
432 */
433
434static int
435via_dmablit_sync(struct drm_device *dev, uint32_t handle, int engine)
436{
437
438 drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private;
439 drm_via_blitq_t *blitq = dev_priv->blit_queues + engine;
440 wait_queue_head_t *queue;
441 int ret = 0;
442
443 if (via_dmablit_active(blitq, engine, handle, &queue)) {
444 DRM_WAIT_ON(ret, *queue, 3 * DRM_HZ,
445 !via_dmablit_active(blitq, engine, handle, NULL));
446 }
447 DRM_DEBUG("DMA blit sync handle 0x%x engine %d returned %d\n",
448 handle, engine, ret);
449
450 return ret;
451}
452
453
454/*
455 * A timer that regularly polls the blit engine in cases where we don't have interrupts:
456 * a) Broken hardware (typically those that don't have any video capture facility).
457 * b) Blit abort. The hardware doesn't send an interrupt when a blit is aborted.
458 * The timer and hardware IRQ's can and do work in parallel. If the hardware has
459 * irqs, it will shorten the latency somewhat.
460 */
461
462
463
464static void
465via_dmablit_timer(unsigned long data)
466{
467 drm_via_blitq_t *blitq = (drm_via_blitq_t *) data;
468 struct drm_device *dev = blitq->dev;
469 int engine = (int)
470 (blitq - ((drm_via_private_t *)dev->dev_private)->blit_queues);
471
472 DRM_DEBUG("Polling timer called for engine %d, jiffies %lu\n", engine,
473 (unsigned long) jiffies);
474
475 via_dmablit_handler(dev, engine, 0);
476
477 if (!timer_pending(&blitq->poll_timer)) {
478 mod_timer(&blitq->poll_timer, jiffies + 1);
479
480 /*
481 * Rerun handler to delete timer if engines are off, and
482 * to shorten abort latency. This is a little nasty.
483 */
484
485 via_dmablit_handler(dev, engine, 0);
486
487 }
488}
489
490
491
492
493/*
494 * Workqueue task that frees data and mappings associated with a blit.
495 * Also wakes up waiting processes. Each of these tasks handles one
496 * blit engine only and may not be called on each interrupt.
497 */
498
499
500static void
501via_dmablit_workqueue(struct work_struct *work)
502{
503 drm_via_blitq_t *blitq = container_of(work, drm_via_blitq_t, wq);
504 struct drm_device *dev = blitq->dev;
505 unsigned long irqsave;
506 drm_via_sg_info_t *cur_sg;
507 int cur_released;
508
509
510 DRM_DEBUG("Workqueue task called for blit engine %ld\n",(unsigned long)
511 (blitq - ((drm_via_private_t *)dev->dev_private)->blit_queues));
512
513 spin_lock_irqsave(&blitq->blit_lock, irqsave);
514
515 while(blitq->serviced != blitq->cur) {
516
517 cur_released = blitq->serviced++;
518
519 DRM_DEBUG("Releasing blit slot %d\n", cur_released);
520
521 if (blitq->serviced >= VIA_NUM_BLIT_SLOTS)
522 blitq->serviced = 0;
523
524 cur_sg = blitq->blits[cur_released];
525 blitq->num_free++;
526
527 spin_unlock_irqrestore(&blitq->blit_lock, irqsave);
528
529 DRM_WAKEUP(&blitq->busy_queue);
530
531 via_free_sg_info(dev->pdev, cur_sg);
532 kfree(cur_sg);
533
534 spin_lock_irqsave(&blitq->blit_lock, irqsave);
535 }
536
537 spin_unlock_irqrestore(&blitq->blit_lock, irqsave);
538}
539
540
541/*
542 * Init all blit engines. Currently we use two, but some hardware have 4.
543 */
544
545
546void
547via_init_dmablit(struct drm_device *dev)
548{
549 int i,j;
550 drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private;
551 drm_via_blitq_t *blitq;
552
553 pci_set_master(dev->pdev);
554
555 for (i=0; i< VIA_NUM_BLIT_ENGINES; ++i) {
556 blitq = dev_priv->blit_queues + i;
557 blitq->dev = dev;
558 blitq->cur_blit_handle = 0;
559 blitq->done_blit_handle = 0;
560 blitq->head = 0;
561 blitq->cur = 0;
562 blitq->serviced = 0;
563 blitq->num_free = VIA_NUM_BLIT_SLOTS - 1;
564 blitq->num_outstanding = 0;
565 blitq->is_active = 0;
566 blitq->aborting = 0;
567 spin_lock_init(&blitq->blit_lock);
568 for (j=0; j<VIA_NUM_BLIT_SLOTS; ++j) {
569 DRM_INIT_WAITQUEUE(blitq->blit_queue + j);
570 }
571 DRM_INIT_WAITQUEUE(&blitq->busy_queue);
572 INIT_WORK(&blitq->wq, via_dmablit_workqueue);
573 setup_timer(&blitq->poll_timer, via_dmablit_timer,
574 (unsigned long)blitq);
575 }
576}
577
578/*
579 * Build all info and do all mappings required for a blit.
580 */
581
582
583static int
584via_build_sg_info(struct drm_device *dev, drm_via_sg_info_t *vsg, drm_via_dmablit_t *xfer)
585{
586 int draw = xfer->to_fb;
587 int ret = 0;
588
589 vsg->direction = (draw) ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
590 vsg->bounce_buffer = NULL;
591
592 vsg->state = dr_via_sg_init;
593
594 if (xfer->num_lines <= 0 || xfer->line_length <= 0) {
595 DRM_ERROR("Zero size bitblt.\n");
596 return -EINVAL;
597 }
598
599 /*
600 * Below check is a driver limitation, not a hardware one. We
601 * don't want to lock unused pages, and don't want to incoporate the
602 * extra logic of avoiding them. Make sure there are no.
603 * (Not a big limitation anyway.)
604 */
605
606 if ((xfer->mem_stride - xfer->line_length) > 2*PAGE_SIZE) {
607 DRM_ERROR("Too large system memory stride. Stride: %d, "
608 "Length: %d\n", xfer->mem_stride, xfer->line_length);
609 return -EINVAL;
610 }
611
612 if ((xfer->mem_stride == xfer->line_length) &&
613 (xfer->fb_stride == xfer->line_length)) {
614 xfer->mem_stride *= xfer->num_lines;
615 xfer->line_length = xfer->mem_stride;
616 xfer->fb_stride = xfer->mem_stride;
617 xfer->num_lines = 1;
618 }
619
620 /*
621 * Don't lock an arbitrary large number of pages, since that causes a
622 * DOS security hole.
623 */
624
625 if (xfer->num_lines > 2048 || (xfer->num_lines*xfer->mem_stride > (2048*2048*4))) {
626 DRM_ERROR("Too large PCI DMA bitblt.\n");
627 return -EINVAL;
628 }
629
630 /*
631 * we allow a negative fb stride to allow flipping of images in
632 * transfer.
633 */
634
635 if (xfer->mem_stride < xfer->line_length ||
636 abs(xfer->fb_stride) < xfer->line_length) {
637 DRM_ERROR("Invalid frame-buffer / memory stride.\n");
638 return -EINVAL;
639 }
640
641 /*
642 * A hardware bug seems to be worked around if system memory addresses start on
643 * 16 byte boundaries. This seems a bit restrictive however. VIA is contacted
644 * about this. Meanwhile, impose the following restrictions:
645 */
646
647#ifdef VIA_BUGFREE
648 if ((((unsigned long)xfer->mem_addr & 3) != ((unsigned long)xfer->fb_addr & 3)) ||
649 ((xfer->num_lines > 1) && ((xfer->mem_stride & 3) != (xfer->fb_stride & 3)))) {
650 DRM_ERROR("Invalid DRM bitblt alignment.\n");
651 return -EINVAL;
652 }
653#else
654 if ((((unsigned long)xfer->mem_addr & 15) ||
655 ((unsigned long)xfer->fb_addr & 3)) ||
656 ((xfer->num_lines > 1) &&
657 ((xfer->mem_stride & 15) || (xfer->fb_stride & 3)))) {
658 DRM_ERROR("Invalid DRM bitblt alignment.\n");
659 return -EINVAL;
660 }
661#endif
662
663 if (0 != (ret = via_lock_all_dma_pages(vsg, xfer))) {
664 DRM_ERROR("Could not lock DMA pages.\n");
665 via_free_sg_info(dev->pdev, vsg);
666 return ret;
667 }
668
669 via_map_blit_for_device(dev->pdev, xfer, vsg, 0);
670 if (0 != (ret = via_alloc_desc_pages(vsg))) {
671 DRM_ERROR("Could not allocate DMA descriptor pages.\n");
672 via_free_sg_info(dev->pdev, vsg);
673 return ret;
674 }
675 via_map_blit_for_device(dev->pdev, xfer, vsg, 1);
676
677 return 0;
678}
679
680
681/*
682 * Reserve one free slot in the blit queue. Will wait for one second for one
683 * to become available. Otherwise -EBUSY is returned.
684 */
685
686static int
687via_dmablit_grab_slot(drm_via_blitq_t *blitq, int engine)
688{
689 int ret=0;
690 unsigned long irqsave;
691
692 DRM_DEBUG("Num free is %d\n", blitq->num_free);
693 spin_lock_irqsave(&blitq->blit_lock, irqsave);
694 while(blitq->num_free == 0) {
695 spin_unlock_irqrestore(&blitq->blit_lock, irqsave);
696
697 DRM_WAIT_ON(ret, blitq->busy_queue, DRM_HZ, blitq->num_free > 0);
698 if (ret) {
699 return (-EINTR == ret) ? -EAGAIN : ret;
700 }
701
702 spin_lock_irqsave(&blitq->blit_lock, irqsave);
703 }
704
705 blitq->num_free--;
706 spin_unlock_irqrestore(&blitq->blit_lock, irqsave);
707
708 return 0;
709}
710
711/*
712 * Hand back a free slot if we changed our mind.
713 */
714
715static void
716via_dmablit_release_slot(drm_via_blitq_t *blitq)
717{
718 unsigned long irqsave;
719
720 spin_lock_irqsave(&blitq->blit_lock, irqsave);
721 blitq->num_free++;
722 spin_unlock_irqrestore(&blitq->blit_lock, irqsave);
723 DRM_WAKEUP( &blitq->busy_queue );
724}
725
726/*
727 * Grab a free slot. Build blit info and queue a blit.
728 */
729
730
731static int
732via_dmablit(struct drm_device *dev, drm_via_dmablit_t *xfer)
733{
734 drm_via_private_t *dev_priv = (drm_via_private_t *)dev->dev_private;
735 drm_via_sg_info_t *vsg;
736 drm_via_blitq_t *blitq;
737 int ret;
738 int engine;
739 unsigned long irqsave;
740
741 if (dev_priv == NULL) {
742 DRM_ERROR("Called without initialization.\n");
743 return -EINVAL;
744 }
745
746 engine = (xfer->to_fb) ? 0 : 1;
747 blitq = dev_priv->blit_queues + engine;
748 if (0 != (ret = via_dmablit_grab_slot(blitq, engine))) {
749 return ret;
750 }
751 if (NULL == (vsg = kmalloc(sizeof(*vsg), GFP_KERNEL))) {
752 via_dmablit_release_slot(blitq);
753 return -ENOMEM;
754 }
755 if (0 != (ret = via_build_sg_info(dev, vsg, xfer))) {
756 via_dmablit_release_slot(blitq);
757 kfree(vsg);
758 return ret;
759 }
760 spin_lock_irqsave(&blitq->blit_lock, irqsave);
761
762 blitq->blits[blitq->head++] = vsg;
763 if (blitq->head >= VIA_NUM_BLIT_SLOTS)
764 blitq->head = 0;
765 blitq->num_outstanding++;
766 xfer->sync.sync_handle = ++blitq->cur_blit_handle;
767
768 spin_unlock_irqrestore(&blitq->blit_lock, irqsave);
769 xfer->sync.engine = engine;
770
771 via_dmablit_handler(dev, engine, 0);
772
773 return 0;
774}
775
776/*
777 * Sync on a previously submitted blit. Note that the X server use signals extensively, and
778 * that there is a very big probability that this IOCTL will be interrupted by a signal. In that
779 * case it returns with -EAGAIN for the signal to be delivered.
780 * The caller should then reissue the IOCTL. This is similar to what is being done for drmGetLock().
781 */
782
783int
784via_dma_blit_sync( struct drm_device *dev, void *data, struct drm_file *file_priv )
785{
786 drm_via_blitsync_t *sync = data;
787 int err;
788
789 if (sync->engine >= VIA_NUM_BLIT_ENGINES)
790 return -EINVAL;
791
792 err = via_dmablit_sync(dev, sync->sync_handle, sync->engine);
793
794 if (-EINTR == err)
795 err = -EAGAIN;
796
797 return err;
798}
799
800
801/*
802 * Queue a blit and hand back a handle to be used for sync. This IOCTL may be interrupted by a signal
803 * while waiting for a free slot in the blit queue. In that case it returns with -EAGAIN and should
804 * be reissued. See the above IOCTL code.
805 */
806
807int
808via_dma_blit( struct drm_device *dev, void *data, struct drm_file *file_priv )
809{
810 drm_via_dmablit_t *xfer = data;
811 int err;
812
813 err = via_dmablit(dev, xfer);
814
815 return err;
816}
diff --git a/drivers/char/drm/via_dmablit.h b/drivers/char/drm/via_dmablit.h
deleted file mode 100644
index 7408a547a036..000000000000
--- a/drivers/char/drm/via_dmablit.h
+++ /dev/null
@@ -1,140 +0,0 @@
1/* via_dmablit.h -- PCI DMA BitBlt support for the VIA Unichrome/Pro
2 *
3 * Copyright 2005 Thomas Hellstrom.
4 * All Rights Reserved.
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sub license,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the
14 * next paragraph) shall be included in all copies or substantial portions
15 * of the Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
20 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
21 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
22 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
23 * USE OR OTHER DEALINGS IN THE SOFTWARE.
24 *
25 * Authors:
26 * Thomas Hellstrom.
27 * Register info from Digeo Inc.
28 */
29
30#ifndef _VIA_DMABLIT_H
31#define _VIA_DMABLIT_H
32
33#include <linux/dma-mapping.h>
34
35#define VIA_NUM_BLIT_ENGINES 2
36#define VIA_NUM_BLIT_SLOTS 8
37
38struct _drm_via_descriptor;
39
40typedef struct _drm_via_sg_info {
41 struct page **pages;
42 unsigned long num_pages;
43 struct _drm_via_descriptor **desc_pages;
44 int num_desc_pages;
45 int num_desc;
46 enum dma_data_direction direction;
47 unsigned char *bounce_buffer;
48 dma_addr_t chain_start;
49 uint32_t free_on_sequence;
50 unsigned int descriptors_per_page;
51 int aborted;
52 enum {
53 dr_via_device_mapped,
54 dr_via_desc_pages_alloc,
55 dr_via_pages_locked,
56 dr_via_pages_alloc,
57 dr_via_sg_init
58 } state;
59} drm_via_sg_info_t;
60
61typedef struct _drm_via_blitq {
62 struct drm_device *dev;
63 uint32_t cur_blit_handle;
64 uint32_t done_blit_handle;
65 unsigned serviced;
66 unsigned head;
67 unsigned cur;
68 unsigned num_free;
69 unsigned num_outstanding;
70 unsigned long end;
71 int aborting;
72 int is_active;
73 drm_via_sg_info_t *blits[VIA_NUM_BLIT_SLOTS];
74 spinlock_t blit_lock;
75 wait_queue_head_t blit_queue[VIA_NUM_BLIT_SLOTS];
76 wait_queue_head_t busy_queue;
77 struct work_struct wq;
78 struct timer_list poll_timer;
79} drm_via_blitq_t;
80
81
82/*
83 * PCI DMA Registers
84 * Channels 2 & 3 don't seem to be implemented in hardware.
85 */
86
87#define VIA_PCI_DMA_MAR0 0xE40 /* Memory Address Register of Channel 0 */
88#define VIA_PCI_DMA_DAR0 0xE44 /* Device Address Register of Channel 0 */
89#define VIA_PCI_DMA_BCR0 0xE48 /* Byte Count Register of Channel 0 */
90#define VIA_PCI_DMA_DPR0 0xE4C /* Descriptor Pointer Register of Channel 0 */
91
92#define VIA_PCI_DMA_MAR1 0xE50 /* Memory Address Register of Channel 1 */
93#define VIA_PCI_DMA_DAR1 0xE54 /* Device Address Register of Channel 1 */
94#define VIA_PCI_DMA_BCR1 0xE58 /* Byte Count Register of Channel 1 */
95#define VIA_PCI_DMA_DPR1 0xE5C /* Descriptor Pointer Register of Channel 1 */
96
97#define VIA_PCI_DMA_MAR2 0xE60 /* Memory Address Register of Channel 2 */
98#define VIA_PCI_DMA_DAR2 0xE64 /* Device Address Register of Channel 2 */
99#define VIA_PCI_DMA_BCR2 0xE68 /* Byte Count Register of Channel 2 */
100#define VIA_PCI_DMA_DPR2 0xE6C /* Descriptor Pointer Register of Channel 2 */
101
102#define VIA_PCI_DMA_MAR3 0xE70 /* Memory Address Register of Channel 3 */
103#define VIA_PCI_DMA_DAR3 0xE74 /* Device Address Register of Channel 3 */
104#define VIA_PCI_DMA_BCR3 0xE78 /* Byte Count Register of Channel 3 */
105#define VIA_PCI_DMA_DPR3 0xE7C /* Descriptor Pointer Register of Channel 3 */
106
107#define VIA_PCI_DMA_MR0 0xE80 /* Mode Register of Channel 0 */
108#define VIA_PCI_DMA_MR1 0xE84 /* Mode Register of Channel 1 */
109#define VIA_PCI_DMA_MR2 0xE88 /* Mode Register of Channel 2 */
110#define VIA_PCI_DMA_MR3 0xE8C /* Mode Register of Channel 3 */
111
112#define VIA_PCI_DMA_CSR0 0xE90 /* Command/Status Register of Channel 0 */
113#define VIA_PCI_DMA_CSR1 0xE94 /* Command/Status Register of Channel 1 */
114#define VIA_PCI_DMA_CSR2 0xE98 /* Command/Status Register of Channel 2 */
115#define VIA_PCI_DMA_CSR3 0xE9C /* Command/Status Register of Channel 3 */
116
117#define VIA_PCI_DMA_PTR 0xEA0 /* Priority Type Register */
118
119/* Define for DMA engine */
120/* DPR */
121#define VIA_DMA_DPR_EC (1<<1) /* end of chain */
122#define VIA_DMA_DPR_DDIE (1<<2) /* descriptor done interrupt enable */
123#define VIA_DMA_DPR_DT (1<<3) /* direction of transfer (RO) */
124
125/* MR */
126#define VIA_DMA_MR_CM (1<<0) /* chaining mode */
127#define VIA_DMA_MR_TDIE (1<<1) /* transfer done interrupt enable */
128#define VIA_DMA_MR_HENDMACMD (1<<7) /* ? */
129
130/* CSR */
131#define VIA_DMA_CSR_DE (1<<0) /* DMA enable */
132#define VIA_DMA_CSR_TS (1<<1) /* transfer start */
133#define VIA_DMA_CSR_TA (1<<2) /* transfer abort */
134#define VIA_DMA_CSR_TD (1<<3) /* transfer done */
135#define VIA_DMA_CSR_DD (1<<4) /* descriptor done */
136#define VIA_DMA_DPR_EC (1<<1) /* end of chain */
137
138
139
140#endif
diff --git a/drivers/char/drm/via_drm.h b/drivers/char/drm/via_drm.h
deleted file mode 100644
index a3b5c102b067..000000000000
--- a/drivers/char/drm/via_drm.h
+++ /dev/null
@@ -1,275 +0,0 @@
1/*
2 * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sub license,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
14 * of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24#ifndef _VIA_DRM_H_
25#define _VIA_DRM_H_
26
27/* WARNING: These defines must be the same as what the Xserver uses.
28 * if you change them, you must change the defines in the Xserver.
29 */
30
31#ifndef _VIA_DEFINES_
32#define _VIA_DEFINES_
33
34#ifndef __KERNEL__
35#include "via_drmclient.h"
36#endif
37
38#define VIA_NR_SAREA_CLIPRECTS 8
39#define VIA_NR_XVMC_PORTS 10
40#define VIA_NR_XVMC_LOCKS 5
41#define VIA_MAX_CACHELINE_SIZE 64
42#define XVMCLOCKPTR(saPriv,lockNo) \
43 ((volatile struct drm_hw_lock *)(((((unsigned long) (saPriv)->XvMCLockArea) + \
44 (VIA_MAX_CACHELINE_SIZE - 1)) & \
45 ~(VIA_MAX_CACHELINE_SIZE - 1)) + \
46 VIA_MAX_CACHELINE_SIZE*(lockNo)))
47
48/* Each region is a minimum of 64k, and there are at most 64 of them.
49 */
50#define VIA_NR_TEX_REGIONS 64
51#define VIA_LOG_MIN_TEX_REGION_SIZE 16
52#endif
53
54#define VIA_UPLOAD_TEX0IMAGE 0x1 /* handled clientside */
55#define VIA_UPLOAD_TEX1IMAGE 0x2 /* handled clientside */
56#define VIA_UPLOAD_CTX 0x4
57#define VIA_UPLOAD_BUFFERS 0x8
58#define VIA_UPLOAD_TEX0 0x10
59#define VIA_UPLOAD_TEX1 0x20
60#define VIA_UPLOAD_CLIPRECTS 0x40
61#define VIA_UPLOAD_ALL 0xff
62
63/* VIA specific ioctls */
64#define DRM_VIA_ALLOCMEM 0x00
65#define DRM_VIA_FREEMEM 0x01
66#define DRM_VIA_AGP_INIT 0x02
67#define DRM_VIA_FB_INIT 0x03
68#define DRM_VIA_MAP_INIT 0x04
69#define DRM_VIA_DEC_FUTEX 0x05
70#define NOT_USED
71#define DRM_VIA_DMA_INIT 0x07
72#define DRM_VIA_CMDBUFFER 0x08
73#define DRM_VIA_FLUSH 0x09
74#define DRM_VIA_PCICMD 0x0a
75#define DRM_VIA_CMDBUF_SIZE 0x0b
76#define NOT_USED
77#define DRM_VIA_WAIT_IRQ 0x0d
78#define DRM_VIA_DMA_BLIT 0x0e
79#define DRM_VIA_BLIT_SYNC 0x0f
80
81#define DRM_IOCTL_VIA_ALLOCMEM DRM_IOWR(DRM_COMMAND_BASE + DRM_VIA_ALLOCMEM, drm_via_mem_t)
82#define DRM_IOCTL_VIA_FREEMEM DRM_IOW( DRM_COMMAND_BASE + DRM_VIA_FREEMEM, drm_via_mem_t)
83#define DRM_IOCTL_VIA_AGP_INIT DRM_IOWR(DRM_COMMAND_BASE + DRM_VIA_AGP_INIT, drm_via_agp_t)
84#define DRM_IOCTL_VIA_FB_INIT DRM_IOWR(DRM_COMMAND_BASE + DRM_VIA_FB_INIT, drm_via_fb_t)
85#define DRM_IOCTL_VIA_MAP_INIT DRM_IOWR(DRM_COMMAND_BASE + DRM_VIA_MAP_INIT, drm_via_init_t)
86#define DRM_IOCTL_VIA_DEC_FUTEX DRM_IOW( DRM_COMMAND_BASE + DRM_VIA_DEC_FUTEX, drm_via_futex_t)
87#define DRM_IOCTL_VIA_DMA_INIT DRM_IOWR(DRM_COMMAND_BASE + DRM_VIA_DMA_INIT, drm_via_dma_init_t)
88#define DRM_IOCTL_VIA_CMDBUFFER DRM_IOW( DRM_COMMAND_BASE + DRM_VIA_CMDBUFFER, drm_via_cmdbuffer_t)
89#define DRM_IOCTL_VIA_FLUSH DRM_IO( DRM_COMMAND_BASE + DRM_VIA_FLUSH)
90#define DRM_IOCTL_VIA_PCICMD DRM_IOW( DRM_COMMAND_BASE + DRM_VIA_PCICMD, drm_via_cmdbuffer_t)
91#define DRM_IOCTL_VIA_CMDBUF_SIZE DRM_IOWR( DRM_COMMAND_BASE + DRM_VIA_CMDBUF_SIZE, \
92 drm_via_cmdbuf_size_t)
93#define DRM_IOCTL_VIA_WAIT_IRQ DRM_IOWR( DRM_COMMAND_BASE + DRM_VIA_WAIT_IRQ, drm_via_irqwait_t)
94#define DRM_IOCTL_VIA_DMA_BLIT DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_DMA_BLIT, drm_via_dmablit_t)
95#define DRM_IOCTL_VIA_BLIT_SYNC DRM_IOW(DRM_COMMAND_BASE + DRM_VIA_BLIT_SYNC, drm_via_blitsync_t)
96
97/* Indices into buf.Setup where various bits of state are mirrored per
98 * context and per buffer. These can be fired at the card as a unit,
99 * or in a piecewise fashion as required.
100 */
101
102#define VIA_TEX_SETUP_SIZE 8
103
104/* Flags for clear ioctl
105 */
106#define VIA_FRONT 0x1
107#define VIA_BACK 0x2
108#define VIA_DEPTH 0x4
109#define VIA_STENCIL 0x8
110#define VIA_MEM_VIDEO 0 /* matches drm constant */
111#define VIA_MEM_AGP 1 /* matches drm constant */
112#define VIA_MEM_SYSTEM 2
113#define VIA_MEM_MIXED 3
114#define VIA_MEM_UNKNOWN 4
115
116typedef struct {
117 uint32_t offset;
118 uint32_t size;
119} drm_via_agp_t;
120
121typedef struct {
122 uint32_t offset;
123 uint32_t size;
124} drm_via_fb_t;
125
126typedef struct {
127 uint32_t context;
128 uint32_t type;
129 uint32_t size;
130 unsigned long index;
131 unsigned long offset;
132} drm_via_mem_t;
133
134typedef struct _drm_via_init {
135 enum {
136 VIA_INIT_MAP = 0x01,
137 VIA_CLEANUP_MAP = 0x02
138 } func;
139
140 unsigned long sarea_priv_offset;
141 unsigned long fb_offset;
142 unsigned long mmio_offset;
143 unsigned long agpAddr;
144} drm_via_init_t;
145
146typedef struct _drm_via_futex {
147 enum {
148 VIA_FUTEX_WAIT = 0x00,
149 VIA_FUTEX_WAKE = 0X01
150 } func;
151 uint32_t ms;
152 uint32_t lock;
153 uint32_t val;
154} drm_via_futex_t;
155
156typedef struct _drm_via_dma_init {
157 enum {
158 VIA_INIT_DMA = 0x01,
159 VIA_CLEANUP_DMA = 0x02,
160 VIA_DMA_INITIALIZED = 0x03
161 } func;
162
163 unsigned long offset;
164 unsigned long size;
165 unsigned long reg_pause_addr;
166} drm_via_dma_init_t;
167
168typedef struct _drm_via_cmdbuffer {
169 char __user *buf;
170 unsigned long size;
171} drm_via_cmdbuffer_t;
172
173/* Warning: If you change the SAREA structure you must change the Xserver
174 * structure as well */
175
176typedef struct _drm_via_tex_region {
177 unsigned char next, prev; /* indices to form a circular LRU */
178 unsigned char inUse; /* owned by a client, or free? */
179 int age; /* tracked by clients to update local LRU's */
180} drm_via_tex_region_t;
181
182typedef struct _drm_via_sarea {
183 unsigned int dirty;
184 unsigned int nbox;
185 struct drm_clip_rect boxes[VIA_NR_SAREA_CLIPRECTS];
186 drm_via_tex_region_t texList[VIA_NR_TEX_REGIONS + 1];
187 int texAge; /* last time texture was uploaded */
188 int ctxOwner; /* last context to upload state */
189 int vertexPrim;
190
191 /*
192 * Below is for XvMC.
193 * We want the lock integers alone on, and aligned to, a cache line.
194 * Therefore this somewhat strange construct.
195 */
196
197 char XvMCLockArea[VIA_MAX_CACHELINE_SIZE * (VIA_NR_XVMC_LOCKS + 1)];
198
199 unsigned int XvMCDisplaying[VIA_NR_XVMC_PORTS];
200 unsigned int XvMCSubPicOn[VIA_NR_XVMC_PORTS];
201 unsigned int XvMCCtxNoGrabbed; /* Last context to hold decoder */
202
203 /* Used by the 3d driver only at this point, for pageflipping:
204 */
205 unsigned int pfCurrentOffset;
206} drm_via_sarea_t;
207
208typedef struct _drm_via_cmdbuf_size {
209 enum {
210 VIA_CMDBUF_SPACE = 0x01,
211 VIA_CMDBUF_LAG = 0x02
212 } func;
213 int wait;
214 uint32_t size;
215} drm_via_cmdbuf_size_t;
216
217typedef enum {
218 VIA_IRQ_ABSOLUTE = 0x0,
219 VIA_IRQ_RELATIVE = 0x1,
220 VIA_IRQ_SIGNAL = 0x10000000,
221 VIA_IRQ_FORCE_SEQUENCE = 0x20000000
222} via_irq_seq_type_t;
223
224#define VIA_IRQ_FLAGS_MASK 0xF0000000
225
226enum drm_via_irqs {
227 drm_via_irq_hqv0 = 0,
228 drm_via_irq_hqv1,
229 drm_via_irq_dma0_dd,
230 drm_via_irq_dma0_td,
231 drm_via_irq_dma1_dd,
232 drm_via_irq_dma1_td,
233 drm_via_irq_num
234};
235
236struct drm_via_wait_irq_request {
237 unsigned irq;
238 via_irq_seq_type_t type;
239 uint32_t sequence;
240 uint32_t signal;
241};
242
243typedef union drm_via_irqwait {
244 struct drm_via_wait_irq_request request;
245 struct drm_wait_vblank_reply reply;
246} drm_via_irqwait_t;
247
248typedef struct drm_via_blitsync {
249 uint32_t sync_handle;
250 unsigned engine;
251} drm_via_blitsync_t;
252
253/* - * Below,"flags" is currently unused but will be used for possible future
254 * extensions like kernel space bounce buffers for bad alignments and
255 * blit engine busy-wait polling for better latency in the absence of
256 * interrupts.
257 */
258
259typedef struct drm_via_dmablit {
260 uint32_t num_lines;
261 uint32_t line_length;
262
263 uint32_t fb_addr;
264 uint32_t fb_stride;
265
266 unsigned char *mem_addr;
267 uint32_t mem_stride;
268
269 uint32_t flags;
270 int to_fb;
271
272 drm_via_blitsync_t sync;
273} drm_via_dmablit_t;
274
275#endif /* _VIA_DRM_H_ */
diff --git a/drivers/char/drm/via_drv.c b/drivers/char/drm/via_drv.c
deleted file mode 100644
index 37870a4a3dc7..000000000000
--- a/drivers/char/drm/via_drv.c
+++ /dev/null
@@ -1,102 +0,0 @@
1/*
2 * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sub license,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
14 * of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24
25#include "drmP.h"
26#include "via_drm.h"
27#include "via_drv.h"
28
29#include "drm_pciids.h"
30
31static int dri_library_name(struct drm_device *dev, char *buf)
32{
33 return snprintf(buf, PAGE_SIZE, "unichrome");
34}
35
36static struct pci_device_id pciidlist[] = {
37 viadrv_PCI_IDS
38};
39
40static struct drm_driver driver = {
41 .driver_features =
42 DRIVER_USE_AGP | DRIVER_USE_MTRR | DRIVER_HAVE_IRQ |
43 DRIVER_IRQ_SHARED,
44 .load = via_driver_load,
45 .unload = via_driver_unload,
46 .context_dtor = via_final_context,
47 .get_vblank_counter = via_get_vblank_counter,
48 .enable_vblank = via_enable_vblank,
49 .disable_vblank = via_disable_vblank,
50 .irq_preinstall = via_driver_irq_preinstall,
51 .irq_postinstall = via_driver_irq_postinstall,
52 .irq_uninstall = via_driver_irq_uninstall,
53 .irq_handler = via_driver_irq_handler,
54 .dma_quiescent = via_driver_dma_quiescent,
55 .dri_library_name = dri_library_name,
56 .reclaim_buffers = drm_core_reclaim_buffers,
57 .reclaim_buffers_locked = NULL,
58 .reclaim_buffers_idlelocked = via_reclaim_buffers_locked,
59 .lastclose = via_lastclose,
60 .get_map_ofs = drm_core_get_map_ofs,
61 .get_reg_ofs = drm_core_get_reg_ofs,
62 .ioctls = via_ioctls,
63 .fops = {
64 .owner = THIS_MODULE,
65 .open = drm_open,
66 .release = drm_release,
67 .ioctl = drm_ioctl,
68 .mmap = drm_mmap,
69 .poll = drm_poll,
70 .fasync = drm_fasync,
71 },
72 .pci_driver = {
73 .name = DRIVER_NAME,
74 .id_table = pciidlist,
75 },
76
77 .name = DRIVER_NAME,
78 .desc = DRIVER_DESC,
79 .date = DRIVER_DATE,
80 .major = DRIVER_MAJOR,
81 .minor = DRIVER_MINOR,
82 .patchlevel = DRIVER_PATCHLEVEL,
83};
84
85static int __init via_init(void)
86{
87 driver.num_ioctls = via_max_ioctl;
88 via_init_command_verifier();
89 return drm_init(&driver);
90}
91
92static void __exit via_exit(void)
93{
94 drm_exit(&driver);
95}
96
97module_init(via_init);
98module_exit(via_exit);
99
100MODULE_AUTHOR(DRIVER_AUTHOR);
101MODULE_DESCRIPTION(DRIVER_DESC);
102MODULE_LICENSE("GPL and additional rights");
diff --git a/drivers/char/drm/via_drv.h b/drivers/char/drm/via_drv.h
deleted file mode 100644
index fe67030e39ac..000000000000
--- a/drivers/char/drm/via_drv.h
+++ /dev/null
@@ -1,156 +0,0 @@
1/*
2 * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sub license,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
14 * of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24#ifndef _VIA_DRV_H_
25#define _VIA_DRV_H_
26
27#include "drm_sman.h"
28#define DRIVER_AUTHOR "Various"
29
30#define DRIVER_NAME "via"
31#define DRIVER_DESC "VIA Unichrome / Pro"
32#define DRIVER_DATE "20070202"
33
34#define DRIVER_MAJOR 2
35#define DRIVER_MINOR 11
36#define DRIVER_PATCHLEVEL 1
37
38#include "via_verifier.h"
39
40#include "via_dmablit.h"
41
42#define VIA_PCI_BUF_SIZE 60000
43#define VIA_FIRE_BUF_SIZE 1024
44#define VIA_NUM_IRQS 4
45
46typedef struct drm_via_ring_buffer {
47 drm_local_map_t map;
48 char *virtual_start;
49} drm_via_ring_buffer_t;
50
51typedef uint32_t maskarray_t[5];
52
53typedef struct drm_via_irq {
54 atomic_t irq_received;
55 uint32_t pending_mask;
56 uint32_t enable_mask;
57 wait_queue_head_t irq_queue;
58} drm_via_irq_t;
59
60typedef struct drm_via_private {
61 drm_via_sarea_t *sarea_priv;
62 drm_local_map_t *sarea;
63 drm_local_map_t *fb;
64 drm_local_map_t *mmio;
65 unsigned long agpAddr;
66 wait_queue_head_t decoder_queue[VIA_NR_XVMC_LOCKS];
67 char *dma_ptr;
68 unsigned int dma_low;
69 unsigned int dma_high;
70 unsigned int dma_offset;
71 uint32_t dma_wrap;
72 volatile uint32_t *last_pause_ptr;
73 volatile uint32_t *hw_addr_ptr;
74 drm_via_ring_buffer_t ring;
75 struct timeval last_vblank;
76 int last_vblank_valid;
77 unsigned usec_per_vblank;
78 atomic_t vbl_received;
79 drm_via_state_t hc_state;
80 char pci_buf[VIA_PCI_BUF_SIZE];
81 const uint32_t *fire_offsets[VIA_FIRE_BUF_SIZE];
82 uint32_t num_fire_offsets;
83 int chipset;
84 drm_via_irq_t via_irqs[VIA_NUM_IRQS];
85 unsigned num_irqs;
86 maskarray_t *irq_masks;
87 uint32_t irq_enable_mask;
88 uint32_t irq_pending_mask;
89 int *irq_map;
90 unsigned int idle_fault;
91 struct drm_sman sman;
92 int vram_initialized;
93 int agp_initialized;
94 unsigned long vram_offset;
95 unsigned long agp_offset;
96 drm_via_blitq_t blit_queues[VIA_NUM_BLIT_ENGINES];
97 uint32_t dma_diff;
98} drm_via_private_t;
99
100enum via_family {
101 VIA_OTHER = 0, /* Baseline */
102 VIA_PRO_GROUP_A, /* Another video engine and DMA commands */
103 VIA_DX9_0 /* Same video as pro_group_a, but 3D is unsupported */
104};
105
106/* VIA MMIO register access */
107#define VIA_BASE ((dev_priv->mmio))
108
109#define VIA_READ(reg) DRM_READ32(VIA_BASE, reg)
110#define VIA_WRITE(reg,val) DRM_WRITE32(VIA_BASE, reg, val)
111#define VIA_READ8(reg) DRM_READ8(VIA_BASE, reg)
112#define VIA_WRITE8(reg,val) DRM_WRITE8(VIA_BASE, reg, val)
113
114extern struct drm_ioctl_desc via_ioctls[];
115extern int via_max_ioctl;
116
117extern int via_fb_init(struct drm_device *dev, void *data, struct drm_file *file_priv);
118extern int via_mem_alloc(struct drm_device *dev, void *data, struct drm_file *file_priv);
119extern int via_mem_free(struct drm_device *dev, void *data, struct drm_file *file_priv);
120extern int via_agp_init(struct drm_device *dev, void *data, struct drm_file *file_priv);
121extern int via_map_init(struct drm_device *dev, void *data, struct drm_file *file_priv);
122extern int via_decoder_futex(struct drm_device *dev, void *data, struct drm_file *file_priv);
123extern int via_wait_irq(struct drm_device *dev, void *data, struct drm_file *file_priv);
124extern int via_dma_blit_sync( struct drm_device *dev, void *data, struct drm_file *file_priv );
125extern int via_dma_blit( struct drm_device *dev, void *data, struct drm_file *file_priv );
126
127extern int via_driver_load(struct drm_device *dev, unsigned long chipset);
128extern int via_driver_unload(struct drm_device *dev);
129
130extern int via_init_context(struct drm_device * dev, int context);
131extern int via_final_context(struct drm_device * dev, int context);
132
133extern int via_do_cleanup_map(struct drm_device * dev);
134extern u32 via_get_vblank_counter(struct drm_device *dev, int crtc);
135extern int via_enable_vblank(struct drm_device *dev, int crtc);
136extern void via_disable_vblank(struct drm_device *dev, int crtc);
137
138extern irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS);
139extern void via_driver_irq_preinstall(struct drm_device * dev);
140extern int via_driver_irq_postinstall(struct drm_device * dev);
141extern void via_driver_irq_uninstall(struct drm_device * dev);
142
143extern int via_dma_cleanup(struct drm_device * dev);
144extern void via_init_command_verifier(void);
145extern int via_driver_dma_quiescent(struct drm_device * dev);
146extern void via_init_futex(drm_via_private_t * dev_priv);
147extern void via_cleanup_futex(drm_via_private_t * dev_priv);
148extern void via_release_futex(drm_via_private_t * dev_priv, int context);
149
150extern void via_reclaim_buffers_locked(struct drm_device *dev, struct drm_file *file_priv);
151extern void via_lastclose(struct drm_device *dev);
152
153extern void via_dmablit_handler(struct drm_device *dev, int engine, int from_irq);
154extern void via_init_dmablit(struct drm_device *dev);
155
156#endif
diff --git a/drivers/char/drm/via_irq.c b/drivers/char/drm/via_irq.c
deleted file mode 100644
index f1ab6fc7c07e..000000000000
--- a/drivers/char/drm/via_irq.c
+++ /dev/null
@@ -1,390 +0,0 @@
1/* via_irq.c
2 *
3 * Copyright 2004 BEAM Ltd.
4 * Copyright 2002 Tungsten Graphics, Inc.
5 * Copyright 2005 Thomas Hellstrom.
6 * All Rights Reserved.
7 *
8 * Permission is hereby granted, free of charge, to any person obtaining a
9 * copy of this software and associated documentation files (the "Software"),
10 * to deal in the Software without restriction, including without limitation
11 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12 * and/or sell copies of the Software, and to permit persons to whom the
13 * Software is furnished to do so, subject to the following conditions:
14 *
15 * The above copyright notice and this permission notice (including the next
16 * paragraph) shall be included in all copies or substantial portions of the
17 * Software.
18 *
19 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
22 * BEAM LTD, TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
23 * DAMAGES OR
24 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
25 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26 * DEALINGS IN THE SOFTWARE.
27 *
28 * Authors:
29 * Terry Barnaby <terry1@beam.ltd.uk>
30 * Keith Whitwell <keith@tungstengraphics.com>
31 * Thomas Hellstrom <unichrome@shipmail.org>
32 *
33 * This code provides standard DRM access to the Via Unichrome / Pro Vertical blank
34 * interrupt, as well as an infrastructure to handle other interrupts of the chip.
35 * The refresh rate is also calculated for video playback sync purposes.
36 */
37
38#include "drmP.h"
39#include "drm.h"
40#include "via_drm.h"
41#include "via_drv.h"
42
43#define VIA_REG_INTERRUPT 0x200
44
45/* VIA_REG_INTERRUPT */
46#define VIA_IRQ_GLOBAL (1 << 31)
47#define VIA_IRQ_VBLANK_ENABLE (1 << 19)
48#define VIA_IRQ_VBLANK_PENDING (1 << 3)
49#define VIA_IRQ_HQV0_ENABLE (1 << 11)
50#define VIA_IRQ_HQV1_ENABLE (1 << 25)
51#define VIA_IRQ_HQV0_PENDING (1 << 9)
52#define VIA_IRQ_HQV1_PENDING (1 << 10)
53#define VIA_IRQ_DMA0_DD_ENABLE (1 << 20)
54#define VIA_IRQ_DMA0_TD_ENABLE (1 << 21)
55#define VIA_IRQ_DMA1_DD_ENABLE (1 << 22)
56#define VIA_IRQ_DMA1_TD_ENABLE (1 << 23)
57#define VIA_IRQ_DMA0_DD_PENDING (1 << 4)
58#define VIA_IRQ_DMA0_TD_PENDING (1 << 5)
59#define VIA_IRQ_DMA1_DD_PENDING (1 << 6)
60#define VIA_IRQ_DMA1_TD_PENDING (1 << 7)
61
62
63/*
64 * Device-specific IRQs go here. This type might need to be extended with
65 * the register if there are multiple IRQ control registers.
66 * Currently we activate the HQV interrupts of Unichrome Pro group A.
67 */
68
69static maskarray_t via_pro_group_a_irqs[] = {
70 {VIA_IRQ_HQV0_ENABLE, VIA_IRQ_HQV0_PENDING, 0x000003D0, 0x00008010,
71 0x00000000},
72 {VIA_IRQ_HQV1_ENABLE, VIA_IRQ_HQV1_PENDING, 0x000013D0, 0x00008010,
73 0x00000000},
74 {VIA_IRQ_DMA0_TD_ENABLE, VIA_IRQ_DMA0_TD_PENDING, VIA_PCI_DMA_CSR0,
75 VIA_DMA_CSR_TA | VIA_DMA_CSR_TD, 0x00000008},
76 {VIA_IRQ_DMA1_TD_ENABLE, VIA_IRQ_DMA1_TD_PENDING, VIA_PCI_DMA_CSR1,
77 VIA_DMA_CSR_TA | VIA_DMA_CSR_TD, 0x00000008},
78};
79static int via_num_pro_group_a =
80 sizeof(via_pro_group_a_irqs) / sizeof(maskarray_t);
81static int via_irqmap_pro_group_a[] = {0, 1, -1, 2, -1, 3};
82
83static maskarray_t via_unichrome_irqs[] = {
84 {VIA_IRQ_DMA0_TD_ENABLE, VIA_IRQ_DMA0_TD_PENDING, VIA_PCI_DMA_CSR0,
85 VIA_DMA_CSR_TA | VIA_DMA_CSR_TD, 0x00000008},
86 {VIA_IRQ_DMA1_TD_ENABLE, VIA_IRQ_DMA1_TD_PENDING, VIA_PCI_DMA_CSR1,
87 VIA_DMA_CSR_TA | VIA_DMA_CSR_TD, 0x00000008}
88};
89static int via_num_unichrome = sizeof(via_unichrome_irqs) / sizeof(maskarray_t);
90static int via_irqmap_unichrome[] = {-1, -1, -1, 0, -1, 1};
91
92static unsigned time_diff(struct timeval *now, struct timeval *then)
93{
94 return (now->tv_usec >= then->tv_usec) ?
95 now->tv_usec - then->tv_usec :
96 1000000 - (then->tv_usec - now->tv_usec);
97}
98
99u32 via_get_vblank_counter(struct drm_device *dev, int crtc)
100{
101 drm_via_private_t *dev_priv = dev->dev_private;
102 if (crtc != 0)
103 return 0;
104
105 return atomic_read(&dev_priv->vbl_received);
106}
107
108irqreturn_t via_driver_irq_handler(DRM_IRQ_ARGS)
109{
110 struct drm_device *dev = (struct drm_device *) arg;
111 drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
112 u32 status;
113 int handled = 0;
114 struct timeval cur_vblank;
115 drm_via_irq_t *cur_irq = dev_priv->via_irqs;
116 int i;
117
118 status = VIA_READ(VIA_REG_INTERRUPT);
119 if (status & VIA_IRQ_VBLANK_PENDING) {
120 atomic_inc(&dev_priv->vbl_received);
121 if (!(atomic_read(&dev_priv->vbl_received) & 0x0F)) {
122 do_gettimeofday(&cur_vblank);
123 if (dev_priv->last_vblank_valid) {
124 dev_priv->usec_per_vblank =
125 time_diff(&cur_vblank,
126 &dev_priv->last_vblank) >> 4;
127 }
128 dev_priv->last_vblank = cur_vblank;
129 dev_priv->last_vblank_valid = 1;
130 }
131 if (!(atomic_read(&dev_priv->vbl_received) & 0xFF)) {
132 DRM_DEBUG("US per vblank is: %u\n",
133 dev_priv->usec_per_vblank);
134 }
135 drm_handle_vblank(dev, 0);
136 handled = 1;
137 }
138
139 for (i = 0; i < dev_priv->num_irqs; ++i) {
140 if (status & cur_irq->pending_mask) {
141 atomic_inc(&cur_irq->irq_received);
142 DRM_WAKEUP(&cur_irq->irq_queue);
143 handled = 1;
144 if (dev_priv->irq_map[drm_via_irq_dma0_td] == i) {
145 via_dmablit_handler(dev, 0, 1);
146 } else if (dev_priv->irq_map[drm_via_irq_dma1_td] == i) {
147 via_dmablit_handler(dev, 1, 1);
148 }
149 }
150 cur_irq++;
151 }
152
153 /* Acknowlege interrupts */
154 VIA_WRITE(VIA_REG_INTERRUPT, status);
155
156 if (handled)
157 return IRQ_HANDLED;
158 else
159 return IRQ_NONE;
160}
161
162static __inline__ void viadrv_acknowledge_irqs(drm_via_private_t * dev_priv)
163{
164 u32 status;
165
166 if (dev_priv) {
167 /* Acknowlege interrupts */
168 status = VIA_READ(VIA_REG_INTERRUPT);
169 VIA_WRITE(VIA_REG_INTERRUPT, status |
170 dev_priv->irq_pending_mask);
171 }
172}
173
174int via_enable_vblank(struct drm_device *dev, int crtc)
175{
176 drm_via_private_t *dev_priv = dev->dev_private;
177 u32 status;
178
179 if (crtc != 0) {
180 DRM_ERROR("%s: bad crtc %d\n", __FUNCTION__, crtc);
181 return -EINVAL;
182 }
183
184 status = VIA_READ(VIA_REG_INTERRUPT);
185 VIA_WRITE(VIA_REG_INTERRUPT, status & VIA_IRQ_VBLANK_ENABLE);
186
187 VIA_WRITE8(0x83d4, 0x11);
188 VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) | 0x30);
189
190 return 0;
191}
192
193void via_disable_vblank(struct drm_device *dev, int crtc)
194{
195 drm_via_private_t *dev_priv = dev->dev_private;
196
197 VIA_WRITE8(0x83d4, 0x11);
198 VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) & ~0x30);
199
200 if (crtc != 0)
201 DRM_ERROR("%s: bad crtc %d\n", __FUNCTION__, crtc);
202}
203
204static int
205via_driver_irq_wait(struct drm_device * dev, unsigned int irq, int force_sequence,
206 unsigned int *sequence)
207{
208 drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
209 unsigned int cur_irq_sequence;
210 drm_via_irq_t *cur_irq;
211 int ret = 0;
212 maskarray_t *masks;
213 int real_irq;
214
215 DRM_DEBUG("\n");
216
217 if (!dev_priv) {
218 DRM_ERROR("called with no initialization\n");
219 return -EINVAL;
220 }
221
222 if (irq >= drm_via_irq_num) {
223 DRM_ERROR("Trying to wait on unknown irq %d\n", irq);
224 return -EINVAL;
225 }
226
227 real_irq = dev_priv->irq_map[irq];
228
229 if (real_irq < 0) {
230 DRM_ERROR("Video IRQ %d not available on this hardware.\n",
231 irq);
232 return -EINVAL;
233 }
234
235 masks = dev_priv->irq_masks;
236 cur_irq = dev_priv->via_irqs + real_irq;
237
238 if (masks[real_irq][2] && !force_sequence) {
239 DRM_WAIT_ON(ret, cur_irq->irq_queue, 3 * DRM_HZ,
240 ((VIA_READ(masks[irq][2]) & masks[irq][3]) ==
241 masks[irq][4]));
242 cur_irq_sequence = atomic_read(&cur_irq->irq_received);
243 } else {
244 DRM_WAIT_ON(ret, cur_irq->irq_queue, 3 * DRM_HZ,
245 (((cur_irq_sequence =
246 atomic_read(&cur_irq->irq_received)) -
247 *sequence) <= (1 << 23)));
248 }
249 *sequence = cur_irq_sequence;
250 return ret;
251}
252
253/*
254 * drm_dma.h hooks
255 */
256
257void via_driver_irq_preinstall(struct drm_device * dev)
258{
259 drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
260 u32 status;
261 drm_via_irq_t *cur_irq;
262 int i;
263
264 DRM_DEBUG("dev_priv: %p\n", dev_priv);
265 if (dev_priv) {
266 cur_irq = dev_priv->via_irqs;
267
268 dev_priv->irq_enable_mask = VIA_IRQ_VBLANK_ENABLE;
269 dev_priv->irq_pending_mask = VIA_IRQ_VBLANK_PENDING;
270
271 if (dev_priv->chipset == VIA_PRO_GROUP_A ||
272 dev_priv->chipset == VIA_DX9_0) {
273 dev_priv->irq_masks = via_pro_group_a_irqs;
274 dev_priv->num_irqs = via_num_pro_group_a;
275 dev_priv->irq_map = via_irqmap_pro_group_a;
276 } else {
277 dev_priv->irq_masks = via_unichrome_irqs;
278 dev_priv->num_irqs = via_num_unichrome;
279 dev_priv->irq_map = via_irqmap_unichrome;
280 }
281
282 for (i = 0; i < dev_priv->num_irqs; ++i) {
283 atomic_set(&cur_irq->irq_received, 0);
284 cur_irq->enable_mask = dev_priv->irq_masks[i][0];
285 cur_irq->pending_mask = dev_priv->irq_masks[i][1];
286 DRM_INIT_WAITQUEUE(&cur_irq->irq_queue);
287 dev_priv->irq_enable_mask |= cur_irq->enable_mask;
288 dev_priv->irq_pending_mask |= cur_irq->pending_mask;
289 cur_irq++;
290
291 DRM_DEBUG("Initializing IRQ %d\n", i);
292 }
293
294 dev_priv->last_vblank_valid = 0;
295
296 /* Clear VSync interrupt regs */
297 status = VIA_READ(VIA_REG_INTERRUPT);
298 VIA_WRITE(VIA_REG_INTERRUPT, status &
299 ~(dev_priv->irq_enable_mask));
300
301 /* Clear bits if they're already high */
302 viadrv_acknowledge_irqs(dev_priv);
303 }
304}
305
306int via_driver_irq_postinstall(struct drm_device * dev)
307{
308 drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
309 u32 status;
310
311 DRM_DEBUG("via_driver_irq_postinstall\n");
312 if (!dev_priv)
313 return -EINVAL;
314
315 drm_vblank_init(dev, 1);
316 status = VIA_READ(VIA_REG_INTERRUPT);
317 VIA_WRITE(VIA_REG_INTERRUPT, status | VIA_IRQ_GLOBAL
318 | dev_priv->irq_enable_mask);
319
320 /* Some magic, oh for some data sheets ! */
321 VIA_WRITE8(0x83d4, 0x11);
322 VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) | 0x30);
323
324 return 0;
325}
326
327void via_driver_irq_uninstall(struct drm_device * dev)
328{
329 drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
330 u32 status;
331
332 DRM_DEBUG("\n");
333 if (dev_priv) {
334
335 /* Some more magic, oh for some data sheets ! */
336
337 VIA_WRITE8(0x83d4, 0x11);
338 VIA_WRITE8(0x83d5, VIA_READ8(0x83d5) & ~0x30);
339
340 status = VIA_READ(VIA_REG_INTERRUPT);
341 VIA_WRITE(VIA_REG_INTERRUPT, status &
342 ~(VIA_IRQ_VBLANK_ENABLE | dev_priv->irq_enable_mask));
343 }
344}
345
346int via_wait_irq(struct drm_device *dev, void *data, struct drm_file *file_priv)
347{
348 drm_via_irqwait_t *irqwait = data;
349 struct timeval now;
350 int ret = 0;
351 drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
352 drm_via_irq_t *cur_irq = dev_priv->via_irqs;
353 int force_sequence;
354
355 if (!dev->irq)
356 return -EINVAL;
357
358 if (irqwait->request.irq >= dev_priv->num_irqs) {
359 DRM_ERROR("Trying to wait on unknown irq %d\n",
360 irqwait->request.irq);
361 return -EINVAL;
362 }
363
364 cur_irq += irqwait->request.irq;
365
366 switch (irqwait->request.type & ~VIA_IRQ_FLAGS_MASK) {
367 case VIA_IRQ_RELATIVE:
368 irqwait->request.sequence += atomic_read(&cur_irq->irq_received);
369 irqwait->request.type &= ~_DRM_VBLANK_RELATIVE;
370 case VIA_IRQ_ABSOLUTE:
371 break;
372 default:
373 return -EINVAL;
374 }
375
376 if (irqwait->request.type & VIA_IRQ_SIGNAL) {
377 DRM_ERROR("Signals on Via IRQs not implemented yet.\n");
378 return -EINVAL;
379 }
380
381 force_sequence = (irqwait->request.type & VIA_IRQ_FORCE_SEQUENCE);
382
383 ret = via_driver_irq_wait(dev, irqwait->request.irq, force_sequence,
384 &irqwait->request.sequence);
385 do_gettimeofday(&now);
386 irqwait->reply.tval_sec = now.tv_sec;
387 irqwait->reply.tval_usec = now.tv_usec;
388
389 return ret;
390}
diff --git a/drivers/char/drm/via_map.c b/drivers/char/drm/via_map.c
deleted file mode 100644
index a967556be014..000000000000
--- a/drivers/char/drm/via_map.c
+++ /dev/null
@@ -1,123 +0,0 @@
1/*
2 * Copyright 1998-2003 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2003 S3 Graphics, Inc. All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sub license,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
14 * of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24#include "drmP.h"
25#include "via_drm.h"
26#include "via_drv.h"
27
28static int via_do_init_map(struct drm_device * dev, drm_via_init_t * init)
29{
30 drm_via_private_t *dev_priv = dev->dev_private;
31
32 DRM_DEBUG("\n");
33
34 dev_priv->sarea = drm_getsarea(dev);
35 if (!dev_priv->sarea) {
36 DRM_ERROR("could not find sarea!\n");
37 dev->dev_private = (void *)dev_priv;
38 via_do_cleanup_map(dev);
39 return -EINVAL;
40 }
41
42 dev_priv->fb = drm_core_findmap(dev, init->fb_offset);
43 if (!dev_priv->fb) {
44 DRM_ERROR("could not find framebuffer!\n");
45 dev->dev_private = (void *)dev_priv;
46 via_do_cleanup_map(dev);
47 return -EINVAL;
48 }
49 dev_priv->mmio = drm_core_findmap(dev, init->mmio_offset);
50 if (!dev_priv->mmio) {
51 DRM_ERROR("could not find mmio region!\n");
52 dev->dev_private = (void *)dev_priv;
53 via_do_cleanup_map(dev);
54 return -EINVAL;
55 }
56
57 dev_priv->sarea_priv =
58 (drm_via_sarea_t *) ((u8 *) dev_priv->sarea->handle +
59 init->sarea_priv_offset);
60
61 dev_priv->agpAddr = init->agpAddr;
62
63 via_init_futex(dev_priv);
64
65 via_init_dmablit(dev);
66
67 dev->dev_private = (void *)dev_priv;
68 return 0;
69}
70
71int via_do_cleanup_map(struct drm_device * dev)
72{
73 via_dma_cleanup(dev);
74
75 return 0;
76}
77
78int via_map_init(struct drm_device *dev, void *data, struct drm_file *file_priv)
79{
80 drm_via_init_t *init = data;
81
82 DRM_DEBUG("\n");
83
84 switch (init->func) {
85 case VIA_INIT_MAP:
86 return via_do_init_map(dev, init);
87 case VIA_CLEANUP_MAP:
88 return via_do_cleanup_map(dev);
89 }
90
91 return -EINVAL;
92}
93
94int via_driver_load(struct drm_device *dev, unsigned long chipset)
95{
96 drm_via_private_t *dev_priv;
97 int ret = 0;
98
99 dev_priv = drm_calloc(1, sizeof(drm_via_private_t), DRM_MEM_DRIVER);
100 if (dev_priv == NULL)
101 return -ENOMEM;
102
103 dev->dev_private = (void *)dev_priv;
104
105 dev_priv->chipset = chipset;
106
107 ret = drm_sman_init(&dev_priv->sman, 2, 12, 8);
108 if (ret) {
109 drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER);
110 }
111 return ret;
112}
113
114int via_driver_unload(struct drm_device *dev)
115{
116 drm_via_private_t *dev_priv = dev->dev_private;
117
118 drm_sman_takedown(&dev_priv->sman);
119
120 drm_free(dev_priv, sizeof(drm_via_private_t), DRM_MEM_DRIVER);
121
122 return 0;
123}
diff --git a/drivers/char/drm/via_mm.c b/drivers/char/drm/via_mm.c
deleted file mode 100644
index e64094916e4f..000000000000
--- a/drivers/char/drm/via_mm.c
+++ /dev/null
@@ -1,194 +0,0 @@
1/*
2 * Copyright 2006 Tungsten Graphics Inc., Bismarck, ND., USA.
3 * All rights reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sub license,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
14 * of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHORS OR COPYRIGHT HOLDERS AND/OR THEIR SUPPLIERS BE LIABLE FOR ANY CLAIM,
20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 */
24/*
25 * Authors: Thomas Hellström <thomas-at-tungstengraphics-dot-com>
26 */
27
28#include "drmP.h"
29#include "via_drm.h"
30#include "via_drv.h"
31#include "drm_sman.h"
32
33#define VIA_MM_ALIGN_SHIFT 4
34#define VIA_MM_ALIGN_MASK ( (1 << VIA_MM_ALIGN_SHIFT) - 1)
35
36int via_agp_init(struct drm_device *dev, void *data, struct drm_file *file_priv)
37{
38 drm_via_agp_t *agp = data;
39 drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
40 int ret;
41
42 mutex_lock(&dev->struct_mutex);
43 ret = drm_sman_set_range(&dev_priv->sman, VIA_MEM_AGP, 0,
44 agp->size >> VIA_MM_ALIGN_SHIFT);
45
46 if (ret) {
47 DRM_ERROR("AGP memory manager initialisation error\n");
48 mutex_unlock(&dev->struct_mutex);
49 return ret;
50 }
51
52 dev_priv->agp_initialized = 1;
53 dev_priv->agp_offset = agp->offset;
54 mutex_unlock(&dev->struct_mutex);
55
56 DRM_DEBUG("offset = %u, size = %u\n", agp->offset, agp->size);
57 return 0;
58}
59
60int via_fb_init(struct drm_device *dev, void *data, struct drm_file *file_priv)
61{
62 drm_via_fb_t *fb = data;
63 drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
64 int ret;
65
66 mutex_lock(&dev->struct_mutex);
67 ret = drm_sman_set_range(&dev_priv->sman, VIA_MEM_VIDEO, 0,
68 fb->size >> VIA_MM_ALIGN_SHIFT);
69
70 if (ret) {
71 DRM_ERROR("VRAM memory manager initialisation error\n");
72 mutex_unlock(&dev->struct_mutex);
73 return ret;
74 }
75
76 dev_priv->vram_initialized = 1;
77 dev_priv->vram_offset = fb->offset;
78
79 mutex_unlock(&dev->struct_mutex);
80 DRM_DEBUG("offset = %u, size = %u\n", fb->offset, fb->size);
81
82 return 0;
83
84}
85
86int via_final_context(struct drm_device *dev, int context)
87{
88 drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
89
90 via_release_futex(dev_priv, context);
91
92 /* Linux specific until context tracking code gets ported to BSD */
93 /* Last context, perform cleanup */
94 if (dev->ctx_count == 1 && dev->dev_private) {
95 DRM_DEBUG("Last Context\n");
96 if (dev->irq)
97 drm_irq_uninstall(dev);
98 via_cleanup_futex(dev_priv);
99 via_do_cleanup_map(dev);
100 }
101 return 1;
102}
103
104void via_lastclose(struct drm_device *dev)
105{
106 drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
107
108 if (!dev_priv)
109 return;
110
111 mutex_lock(&dev->struct_mutex);
112 drm_sman_cleanup(&dev_priv->sman);
113 dev_priv->vram_initialized = 0;
114 dev_priv->agp_initialized = 0;
115 mutex_unlock(&dev->struct_mutex);
116}
117
118int via_mem_alloc(struct drm_device *dev, void *data,
119 struct drm_file *file_priv)
120{
121 drm_via_mem_t *mem = data;
122 int retval = 0;
123 struct drm_memblock_item *item;
124 drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
125 unsigned long tmpSize;
126
127 if (mem->type > VIA_MEM_AGP) {
128 DRM_ERROR("Unknown memory type allocation\n");
129 return -EINVAL;
130 }
131 mutex_lock(&dev->struct_mutex);
132 if (0 == ((mem->type == VIA_MEM_VIDEO) ? dev_priv->vram_initialized :
133 dev_priv->agp_initialized)) {
134 DRM_ERROR
135 ("Attempt to allocate from uninitialized memory manager.\n");
136 mutex_unlock(&dev->struct_mutex);
137 return -EINVAL;
138 }
139
140 tmpSize = (mem->size + VIA_MM_ALIGN_MASK) >> VIA_MM_ALIGN_SHIFT;
141 item = drm_sman_alloc(&dev_priv->sman, mem->type, tmpSize, 0,
142 (unsigned long)file_priv);
143 mutex_unlock(&dev->struct_mutex);
144 if (item) {
145 mem->offset = ((mem->type == VIA_MEM_VIDEO) ?
146 dev_priv->vram_offset : dev_priv->agp_offset) +
147 (item->mm->
148 offset(item->mm, item->mm_info) << VIA_MM_ALIGN_SHIFT);
149 mem->index = item->user_hash.key;
150 } else {
151 mem->offset = 0;
152 mem->size = 0;
153 mem->index = 0;
154 DRM_DEBUG("Video memory allocation failed\n");
155 retval = -ENOMEM;
156 }
157
158 return retval;
159}
160
161int via_mem_free(struct drm_device *dev, void *data, struct drm_file *file_priv)
162{
163 drm_via_private_t *dev_priv = dev->dev_private;
164 drm_via_mem_t *mem = data;
165 int ret;
166
167 mutex_lock(&dev->struct_mutex);
168 ret = drm_sman_free_key(&dev_priv->sman, mem->index);
169 mutex_unlock(&dev->struct_mutex);
170 DRM_DEBUG("free = 0x%lx\n", mem->index);
171
172 return ret;
173}
174
175
176void via_reclaim_buffers_locked(struct drm_device * dev,
177 struct drm_file *file_priv)
178{
179 drm_via_private_t *dev_priv = dev->dev_private;
180
181 mutex_lock(&dev->struct_mutex);
182 if (drm_sman_owner_clean(&dev_priv->sman, (unsigned long)file_priv)) {
183 mutex_unlock(&dev->struct_mutex);
184 return;
185 }
186
187 if (dev->driver->dma_quiescent) {
188 dev->driver->dma_quiescent(dev);
189 }
190
191 drm_sman_owner_cleanup(&dev_priv->sman, (unsigned long)file_priv);
192 mutex_unlock(&dev->struct_mutex);
193 return;
194}
diff --git a/drivers/char/drm/via_verifier.c b/drivers/char/drm/via_verifier.c
deleted file mode 100644
index 46a579198747..000000000000
--- a/drivers/char/drm/via_verifier.c
+++ /dev/null
@@ -1,1116 +0,0 @@
1/*
2 * Copyright 2004 The Unichrome Project. All Rights Reserved.
3 * Copyright 2005 Thomas Hellstrom. All Rights Reserved.
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a
6 * copy of this software and associated documentation files (the "Software"),
7 * to deal in the Software without restriction, including without limitation
8 * the rights to use, copy, modify, merge, publish, distribute, sub license,
9 * and/or sell copies of the Software, and to permit persons to whom the
10 * Software is furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the
13 * next paragraph) shall be included in all copies or substantial portions
14 * of the Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
19 * THE AUTHOR(S), AND/OR THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
20 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
21 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22 * DEALINGS IN THE SOFTWARE.
23 *
24 * Author: Thomas Hellstrom 2004, 2005.
25 * This code was written using docs obtained under NDA from VIA Inc.
26 *
27 * Don't run this code directly on an AGP buffer. Due to cache problems it will
28 * be very slow.
29 */
30
31#include "via_3d_reg.h"
32#include "drmP.h"
33#include "drm.h"
34#include "via_drm.h"
35#include "via_verifier.h"
36#include "via_drv.h"
37
38typedef enum {
39 state_command,
40 state_header2,
41 state_header1,
42 state_vheader5,
43 state_vheader6,
44 state_error
45} verifier_state_t;
46
47typedef enum {
48 no_check = 0,
49 check_for_header2,
50 check_for_header1,
51 check_for_header2_err,
52 check_for_header1_err,
53 check_for_fire,
54 check_z_buffer_addr0,
55 check_z_buffer_addr1,
56 check_z_buffer_addr_mode,
57 check_destination_addr0,
58 check_destination_addr1,
59 check_destination_addr_mode,
60 check_for_dummy,
61 check_for_dd,
62 check_texture_addr0,
63 check_texture_addr1,
64 check_texture_addr2,
65 check_texture_addr3,
66 check_texture_addr4,
67 check_texture_addr5,
68 check_texture_addr6,
69 check_texture_addr7,
70 check_texture_addr8,
71 check_texture_addr_mode,
72 check_for_vertex_count,
73 check_number_texunits,
74 forbidden_command
75} hazard_t;
76
77/*
78 * Associates each hazard above with a possible multi-command
79 * sequence. For example an address that is split over multiple
80 * commands and that needs to be checked at the first command
81 * that does not include any part of the address.
82 */
83
84static drm_via_sequence_t seqs[] = {
85 no_sequence,
86 no_sequence,
87 no_sequence,
88 no_sequence,
89 no_sequence,
90 no_sequence,
91 z_address,
92 z_address,
93 z_address,
94 dest_address,
95 dest_address,
96 dest_address,
97 no_sequence,
98 no_sequence,
99 tex_address,
100 tex_address,
101 tex_address,
102 tex_address,
103 tex_address,
104 tex_address,
105 tex_address,
106 tex_address,
107 tex_address,
108 tex_address,
109 no_sequence
110};
111
112typedef struct {
113 unsigned int code;
114 hazard_t hz;
115} hz_init_t;
116
117static hz_init_t init_table1[] = {
118 {0xf2, check_for_header2_err},
119 {0xf0, check_for_header1_err},
120 {0xee, check_for_fire},
121 {0xcc, check_for_dummy},
122 {0xdd, check_for_dd},
123 {0x00, no_check},
124 {0x10, check_z_buffer_addr0},
125 {0x11, check_z_buffer_addr1},
126 {0x12, check_z_buffer_addr_mode},
127 {0x13, no_check},
128 {0x14, no_check},
129 {0x15, no_check},
130 {0x23, no_check},
131 {0x24, no_check},
132 {0x33, no_check},
133 {0x34, no_check},
134 {0x35, no_check},
135 {0x36, no_check},
136 {0x37, no_check},
137 {0x38, no_check},
138 {0x39, no_check},
139 {0x3A, no_check},
140 {0x3B, no_check},
141 {0x3C, no_check},
142 {0x3D, no_check},
143 {0x3E, no_check},
144 {0x40, check_destination_addr0},
145 {0x41, check_destination_addr1},
146 {0x42, check_destination_addr_mode},
147 {0x43, no_check},
148 {0x44, no_check},
149 {0x50, no_check},
150 {0x51, no_check},
151 {0x52, no_check},
152 {0x53, no_check},
153 {0x54, no_check},
154 {0x55, no_check},
155 {0x56, no_check},
156 {0x57, no_check},
157 {0x58, no_check},
158 {0x70, no_check},
159 {0x71, no_check},
160 {0x78, no_check},
161 {0x79, no_check},
162 {0x7A, no_check},
163 {0x7B, no_check},
164 {0x7C, no_check},
165 {0x7D, check_for_vertex_count}
166};
167
168static hz_init_t init_table2[] = {
169 {0xf2, check_for_header2_err},
170 {0xf0, check_for_header1_err},
171 {0xee, check_for_fire},
172 {0xcc, check_for_dummy},
173 {0x00, check_texture_addr0},
174 {0x01, check_texture_addr0},
175 {0x02, check_texture_addr0},
176 {0x03, check_texture_addr0},
177 {0x04, check_texture_addr0},
178 {0x05, check_texture_addr0},
179 {0x06, check_texture_addr0},
180 {0x07, check_texture_addr0},
181 {0x08, check_texture_addr0},
182 {0x09, check_texture_addr0},
183 {0x20, check_texture_addr1},
184 {0x21, check_texture_addr1},
185 {0x22, check_texture_addr1},
186 {0x23, check_texture_addr4},
187 {0x2B, check_texture_addr3},
188 {0x2C, check_texture_addr3},
189 {0x2D, check_texture_addr3},
190 {0x2E, check_texture_addr3},
191 {0x2F, check_texture_addr3},
192 {0x30, check_texture_addr3},
193 {0x31, check_texture_addr3},
194 {0x32, check_texture_addr3},
195 {0x33, check_texture_addr3},
196 {0x34, check_texture_addr3},
197 {0x4B, check_texture_addr5},
198 {0x4C, check_texture_addr6},
199 {0x51, check_texture_addr7},
200 {0x52, check_texture_addr8},
201 {0x77, check_texture_addr2},
202 {0x78, no_check},
203 {0x79, no_check},
204 {0x7A, no_check},
205 {0x7B, check_texture_addr_mode},
206 {0x7C, no_check},
207 {0x7D, no_check},
208 {0x7E, no_check},
209 {0x7F, no_check},
210 {0x80, no_check},
211 {0x81, no_check},
212 {0x82, no_check},
213 {0x83, no_check},
214 {0x85, no_check},
215 {0x86, no_check},
216 {0x87, no_check},
217 {0x88, no_check},
218 {0x89, no_check},
219 {0x8A, no_check},
220 {0x90, no_check},
221 {0x91, no_check},
222 {0x92, no_check},
223 {0x93, no_check}
224};
225
226static hz_init_t init_table3[] = {
227 {0xf2, check_for_header2_err},
228 {0xf0, check_for_header1_err},
229 {0xcc, check_for_dummy},
230 {0x00, check_number_texunits}
231};
232
233static hazard_t table1[256];
234static hazard_t table2[256];
235static hazard_t table3[256];
236
237static __inline__ int
238eat_words(const uint32_t ** buf, const uint32_t * buf_end, unsigned num_words)
239{
240 if ((buf_end - *buf) >= num_words) {
241 *buf += num_words;
242 return 0;
243 }
244 DRM_ERROR("Illegal termination of DMA command buffer\n");
245 return 1;
246}
247
248/*
249 * Partially stolen from drm_memory.h
250 */
251
252static __inline__ drm_local_map_t *via_drm_lookup_agp_map(drm_via_state_t *seq,
253 unsigned long offset,
254 unsigned long size,
255 struct drm_device * dev)
256{
257 struct drm_map_list *r_list;
258 drm_local_map_t *map = seq->map_cache;
259
260 if (map && map->offset <= offset
261 && (offset + size) <= (map->offset + map->size)) {
262 return map;
263 }
264
265 list_for_each_entry(r_list, &dev->maplist, head) {
266 map = r_list->map;
267 if (!map)
268 continue;
269 if (map->offset <= offset
270 && (offset + size) <= (map->offset + map->size)
271 && !(map->flags & _DRM_RESTRICTED)
272 && (map->type == _DRM_AGP)) {
273 seq->map_cache = map;
274 return map;
275 }
276 }
277 return NULL;
278}
279
280/*
281 * Require that all AGP texture levels reside in the same AGP map which should
282 * be mappable by the client. This is not a big restriction.
283 * FIXME: To actually enforce this security policy strictly, drm_rmmap
284 * would have to wait for dma quiescent before removing an AGP map.
285 * The via_drm_lookup_agp_map call in reality seems to take
286 * very little CPU time.
287 */
288
289static __inline__ int finish_current_sequence(drm_via_state_t * cur_seq)
290{
291 switch (cur_seq->unfinished) {
292 case z_address:
293 DRM_DEBUG("Z Buffer start address is 0x%x\n", cur_seq->z_addr);
294 break;
295 case dest_address:
296 DRM_DEBUG("Destination start address is 0x%x\n",
297 cur_seq->d_addr);
298 break;
299 case tex_address:
300 if (cur_seq->agp_texture) {
301 unsigned start =
302 cur_seq->tex_level_lo[cur_seq->texture];
303 unsigned end = cur_seq->tex_level_hi[cur_seq->texture];
304 unsigned long lo = ~0, hi = 0, tmp;
305 uint32_t *addr, *pitch, *height, tex;
306 unsigned i;
307 int npot;
308
309 if (end > 9)
310 end = 9;
311 if (start > 9)
312 start = 9;
313
314 addr =
315 &(cur_seq->t_addr[tex = cur_seq->texture][start]);
316 pitch = &(cur_seq->pitch[tex][start]);
317 height = &(cur_seq->height[tex][start]);
318 npot = cur_seq->tex_npot[tex];
319 for (i = start; i <= end; ++i) {
320 tmp = *addr++;
321 if (tmp < lo)
322 lo = tmp;
323 if (i == 0 && npot)
324 tmp += (*height++ * *pitch++);
325 else
326 tmp += (*height++ << *pitch++);
327 if (tmp > hi)
328 hi = tmp;
329 }
330
331 if (!via_drm_lookup_agp_map
332 (cur_seq, lo, hi - lo, cur_seq->dev)) {
333 DRM_ERROR
334 ("AGP texture is not in allowed map\n");
335 return 2;
336 }
337 }
338 break;
339 default:
340 break;
341 }
342 cur_seq->unfinished = no_sequence;
343 return 0;
344}
345
346static __inline__ int
347investigate_hazard(uint32_t cmd, hazard_t hz, drm_via_state_t * cur_seq)
348{
349 register uint32_t tmp, *tmp_addr;
350
351 if (cur_seq->unfinished && (cur_seq->unfinished != seqs[hz])) {
352 int ret;
353 if ((ret = finish_current_sequence(cur_seq)))
354 return ret;
355 }
356
357 switch (hz) {
358 case check_for_header2:
359 if (cmd == HALCYON_HEADER2)
360 return 1;
361 return 0;
362 case check_for_header1:
363 if ((cmd & HALCYON_HEADER1MASK) == HALCYON_HEADER1)
364 return 1;
365 return 0;
366 case check_for_header2_err:
367 if (cmd == HALCYON_HEADER2)
368 return 1;
369 DRM_ERROR("Illegal DMA HALCYON_HEADER2 command\n");
370 break;
371 case check_for_header1_err:
372 if ((cmd & HALCYON_HEADER1MASK) == HALCYON_HEADER1)
373 return 1;
374 DRM_ERROR("Illegal DMA HALCYON_HEADER1 command\n");
375 break;
376 case check_for_fire:
377 if ((cmd & HALCYON_FIREMASK) == HALCYON_FIRECMD)
378 return 1;
379 DRM_ERROR("Illegal DMA HALCYON_FIRECMD command\n");
380 break;
381 case check_for_dummy:
382 if (HC_DUMMY == cmd)
383 return 0;
384 DRM_ERROR("Illegal DMA HC_DUMMY command\n");
385 break;
386 case check_for_dd:
387 if (0xdddddddd == cmd)
388 return 0;
389 DRM_ERROR("Illegal DMA 0xdddddddd command\n");
390 break;
391 case check_z_buffer_addr0:
392 cur_seq->unfinished = z_address;
393 cur_seq->z_addr = (cur_seq->z_addr & 0xFF000000) |
394 (cmd & 0x00FFFFFF);
395 return 0;
396 case check_z_buffer_addr1:
397 cur_seq->unfinished = z_address;
398 cur_seq->z_addr = (cur_seq->z_addr & 0x00FFFFFF) |
399 ((cmd & 0xFF) << 24);
400 return 0;
401 case check_z_buffer_addr_mode:
402 cur_seq->unfinished = z_address;
403 if ((cmd & 0x0000C000) == 0)
404 return 0;
405 DRM_ERROR("Attempt to place Z buffer in system memory\n");
406 return 2;
407 case check_destination_addr0:
408 cur_seq->unfinished = dest_address;
409 cur_seq->d_addr = (cur_seq->d_addr & 0xFF000000) |
410 (cmd & 0x00FFFFFF);
411 return 0;
412 case check_destination_addr1:
413 cur_seq->unfinished = dest_address;
414 cur_seq->d_addr = (cur_seq->d_addr & 0x00FFFFFF) |
415 ((cmd & 0xFF) << 24);
416 return 0;
417 case check_destination_addr_mode:
418 cur_seq->unfinished = dest_address;
419 if ((cmd & 0x0000C000) == 0)
420 return 0;
421 DRM_ERROR
422 ("Attempt to place 3D drawing buffer in system memory\n");
423 return 2;
424 case check_texture_addr0:
425 cur_seq->unfinished = tex_address;
426 tmp = (cmd >> 24);
427 tmp_addr = &cur_seq->t_addr[cur_seq->texture][tmp];
428 *tmp_addr = (*tmp_addr & 0xFF000000) | (cmd & 0x00FFFFFF);
429 return 0;
430 case check_texture_addr1:
431 cur_seq->unfinished = tex_address;
432 tmp = ((cmd >> 24) - 0x20);
433 tmp += tmp << 1;
434 tmp_addr = &cur_seq->t_addr[cur_seq->texture][tmp];
435 *tmp_addr = (*tmp_addr & 0x00FFFFFF) | ((cmd & 0xFF) << 24);
436 tmp_addr++;
437 *tmp_addr = (*tmp_addr & 0x00FFFFFF) | ((cmd & 0xFF00) << 16);
438 tmp_addr++;
439 *tmp_addr = (*tmp_addr & 0x00FFFFFF) | ((cmd & 0xFF0000) << 8);
440 return 0;
441 case check_texture_addr2:
442 cur_seq->unfinished = tex_address;
443 cur_seq->tex_level_lo[tmp = cur_seq->texture] = cmd & 0x3F;
444 cur_seq->tex_level_hi[tmp] = (cmd & 0xFC0) >> 6;
445 return 0;
446 case check_texture_addr3:
447 cur_seq->unfinished = tex_address;
448 tmp = ((cmd >> 24) - HC_SubA_HTXnL0Pit);
449 if (tmp == 0 &&
450 (cmd & HC_HTXnEnPit_MASK)) {
451 cur_seq->pitch[cur_seq->texture][tmp] =
452 (cmd & HC_HTXnLnPit_MASK);
453 cur_seq->tex_npot[cur_seq->texture] = 1;
454 } else {
455 cur_seq->pitch[cur_seq->texture][tmp] =
456 (cmd & HC_HTXnLnPitE_MASK) >> HC_HTXnLnPitE_SHIFT;
457 cur_seq->tex_npot[cur_seq->texture] = 0;
458 if (cmd & 0x000FFFFF) {
459 DRM_ERROR
460 ("Unimplemented texture level 0 pitch mode.\n");
461 return 2;
462 }
463 }
464 return 0;
465 case check_texture_addr4:
466 cur_seq->unfinished = tex_address;
467 tmp_addr = &cur_seq->t_addr[cur_seq->texture][9];
468 *tmp_addr = (*tmp_addr & 0x00FFFFFF) | ((cmd & 0xFF) << 24);
469 return 0;
470 case check_texture_addr5:
471 case check_texture_addr6:
472 cur_seq->unfinished = tex_address;
473 /*
474 * Texture width. We don't care since we have the pitch.
475 */
476 return 0;
477 case check_texture_addr7:
478 cur_seq->unfinished = tex_address;
479 tmp_addr = &(cur_seq->height[cur_seq->texture][0]);
480 tmp_addr[5] = 1 << ((cmd & 0x00F00000) >> 20);
481 tmp_addr[4] = 1 << ((cmd & 0x000F0000) >> 16);
482 tmp_addr[3] = 1 << ((cmd & 0x0000F000) >> 12);
483 tmp_addr[2] = 1 << ((cmd & 0x00000F00) >> 8);
484 tmp_addr[1] = 1 << ((cmd & 0x000000F0) >> 4);
485 tmp_addr[0] = 1 << (cmd & 0x0000000F);
486 return 0;
487 case check_texture_addr8:
488 cur_seq->unfinished = tex_address;
489 tmp_addr = &(cur_seq->height[cur_seq->texture][0]);
490 tmp_addr[9] = 1 << ((cmd & 0x0000F000) >> 12);
491 tmp_addr[8] = 1 << ((cmd & 0x00000F00) >> 8);
492 tmp_addr[7] = 1 << ((cmd & 0x000000F0) >> 4);
493 tmp_addr[6] = 1 << (cmd & 0x0000000F);
494 return 0;
495 case check_texture_addr_mode:
496 cur_seq->unfinished = tex_address;
497 if (2 == (tmp = cmd & 0x00000003)) {
498 DRM_ERROR
499 ("Attempt to fetch texture from system memory.\n");
500 return 2;
501 }
502 cur_seq->agp_texture = (tmp == 3);
503 cur_seq->tex_palette_size[cur_seq->texture] =
504 (cmd >> 16) & 0x000000007;
505 return 0;
506 case check_for_vertex_count:
507 cur_seq->vertex_count = cmd & 0x0000FFFF;
508 return 0;
509 case check_number_texunits:
510 cur_seq->multitex = (cmd >> 3) & 1;
511 return 0;
512 default:
513 DRM_ERROR("Illegal DMA data: 0x%x\n", cmd);
514 return 2;
515 }
516 return 2;
517}
518
519static __inline__ int
520via_check_prim_list(uint32_t const **buffer, const uint32_t * buf_end,
521 drm_via_state_t * cur_seq)
522{
523 drm_via_private_t *dev_priv =
524 (drm_via_private_t *) cur_seq->dev->dev_private;
525 uint32_t a_fire, bcmd, dw_count;
526 int ret = 0;
527 int have_fire;
528 const uint32_t *buf = *buffer;
529
530 while (buf < buf_end) {
531 have_fire = 0;
532 if ((buf_end - buf) < 2) {
533 DRM_ERROR
534 ("Unexpected termination of primitive list.\n");
535 ret = 1;
536 break;
537 }
538 if ((*buf & HC_ACMD_MASK) != HC_ACMD_HCmdB)
539 break;
540 bcmd = *buf++;
541 if ((*buf & HC_ACMD_MASK) != HC_ACMD_HCmdA) {
542 DRM_ERROR("Expected Vertex List A command, got 0x%x\n",
543 *buf);
544 ret = 1;
545 break;
546 }
547 a_fire =
548 *buf++ | HC_HPLEND_MASK | HC_HPMValidN_MASK |
549 HC_HE3Fire_MASK;
550
551 /*
552 * How many dwords per vertex ?
553 */
554
555 if (cur_seq->agp && ((bcmd & (0xF << 11)) == 0)) {
556 DRM_ERROR("Illegal B command vertex data for AGP.\n");
557 ret = 1;
558 break;
559 }
560
561 dw_count = 0;
562 if (bcmd & (1 << 7))
563 dw_count += (cur_seq->multitex) ? 2 : 1;
564 if (bcmd & (1 << 8))
565 dw_count += (cur_seq->multitex) ? 2 : 1;
566 if (bcmd & (1 << 9))
567 dw_count++;
568 if (bcmd & (1 << 10))
569 dw_count++;
570 if (bcmd & (1 << 11))
571 dw_count++;
572 if (bcmd & (1 << 12))
573 dw_count++;
574 if (bcmd & (1 << 13))
575 dw_count++;
576 if (bcmd & (1 << 14))
577 dw_count++;
578
579 while (buf < buf_end) {
580 if (*buf == a_fire) {
581 if (dev_priv->num_fire_offsets >=
582 VIA_FIRE_BUF_SIZE) {
583 DRM_ERROR("Fire offset buffer full.\n");
584 ret = 1;
585 break;
586 }
587 dev_priv->fire_offsets[dev_priv->
588 num_fire_offsets++] =
589 buf;
590 have_fire = 1;
591 buf++;
592 if (buf < buf_end && *buf == a_fire)
593 buf++;
594 break;
595 }
596 if ((*buf == HALCYON_HEADER2) ||
597 ((*buf & HALCYON_FIREMASK) == HALCYON_FIRECMD)) {
598 DRM_ERROR("Missing Vertex Fire command, "
599 "Stray Vertex Fire command or verifier "
600 "lost sync.\n");
601 ret = 1;
602 break;
603 }
604 if ((ret = eat_words(&buf, buf_end, dw_count)))
605 break;
606 }
607 if (buf >= buf_end && !have_fire) {
608 DRM_ERROR("Missing Vertex Fire command or verifier "
609 "lost sync.\n");
610 ret = 1;
611 break;
612 }
613 if (cur_seq->agp && ((buf - cur_seq->buf_start) & 0x01)) {
614 DRM_ERROR("AGP Primitive list end misaligned.\n");
615 ret = 1;
616 break;
617 }
618 }
619 *buffer = buf;
620 return ret;
621}
622
623static __inline__ verifier_state_t
624via_check_header2(uint32_t const **buffer, const uint32_t * buf_end,
625 drm_via_state_t * hc_state)
626{
627 uint32_t cmd;
628 int hz_mode;
629 hazard_t hz;
630 const uint32_t *buf = *buffer;
631 const hazard_t *hz_table;
632
633 if ((buf_end - buf) < 2) {
634 DRM_ERROR
635 ("Illegal termination of DMA HALCYON_HEADER2 sequence.\n");
636 return state_error;
637 }
638 buf++;
639 cmd = (*buf++ & 0xFFFF0000) >> 16;
640
641 switch (cmd) {
642 case HC_ParaType_CmdVdata:
643 if (via_check_prim_list(&buf, buf_end, hc_state))
644 return state_error;
645 *buffer = buf;
646 return state_command;
647 case HC_ParaType_NotTex:
648 hz_table = table1;
649 break;
650 case HC_ParaType_Tex:
651 hc_state->texture = 0;
652 hz_table = table2;
653 break;
654 case (HC_ParaType_Tex | (HC_SubType_Tex1 << 8)):
655 hc_state->texture = 1;
656 hz_table = table2;
657 break;
658 case (HC_ParaType_Tex | (HC_SubType_TexGeneral << 8)):
659 hz_table = table3;
660 break;
661 case HC_ParaType_Auto:
662 if (eat_words(&buf, buf_end, 2))
663 return state_error;
664 *buffer = buf;
665 return state_command;
666 case (HC_ParaType_Palette | (HC_SubType_Stipple << 8)):
667 if (eat_words(&buf, buf_end, 32))
668 return state_error;
669 *buffer = buf;
670 return state_command;
671 case (HC_ParaType_Palette | (HC_SubType_TexPalette0 << 8)):
672 case (HC_ParaType_Palette | (HC_SubType_TexPalette1 << 8)):
673 DRM_ERROR("Texture palettes are rejected because of "
674 "lack of info how to determine their size.\n");
675 return state_error;
676 case (HC_ParaType_Palette | (HC_SubType_FogTable << 8)):
677 DRM_ERROR("Fog factor palettes are rejected because of "
678 "lack of info how to determine their size.\n");
679 return state_error;
680 default:
681
682 /*
683 * There are some unimplemented HC_ParaTypes here, that
684 * need to be implemented if the Mesa driver is extended.
685 */
686
687 DRM_ERROR("Invalid or unimplemented HALCYON_HEADER2 "
688 "DMA subcommand: 0x%x. Previous dword: 0x%x\n",
689 cmd, *(buf - 2));
690 *buffer = buf;
691 return state_error;
692 }
693
694 while (buf < buf_end) {
695 cmd = *buf++;
696 if ((hz = hz_table[cmd >> 24])) {
697 if ((hz_mode = investigate_hazard(cmd, hz, hc_state))) {
698 if (hz_mode == 1) {
699 buf--;
700 break;
701 }
702 return state_error;
703 }
704 } else if (hc_state->unfinished &&
705 finish_current_sequence(hc_state)) {
706 return state_error;
707 }
708 }
709 if (hc_state->unfinished && finish_current_sequence(hc_state)) {
710 return state_error;
711 }
712 *buffer = buf;
713 return state_command;
714}
715
716static __inline__ verifier_state_t
717via_parse_header2(drm_via_private_t * dev_priv, uint32_t const **buffer,
718 const uint32_t * buf_end, int *fire_count)
719{
720 uint32_t cmd;
721 const uint32_t *buf = *buffer;
722 const uint32_t *next_fire;
723 int burst = 0;
724
725 next_fire = dev_priv->fire_offsets[*fire_count];
726 buf++;
727 cmd = (*buf & 0xFFFF0000) >> 16;
728 VIA_WRITE(HC_REG_TRANS_SET + HC_REG_BASE, *buf++);
729 switch (cmd) {
730 case HC_ParaType_CmdVdata:
731 while ((buf < buf_end) &&
732 (*fire_count < dev_priv->num_fire_offsets) &&
733 (*buf & HC_ACMD_MASK) == HC_ACMD_HCmdB) {
734 while (buf <= next_fire) {
735 VIA_WRITE(HC_REG_TRANS_SPACE + HC_REG_BASE +
736 (burst & 63), *buf++);
737 burst += 4;
738 }
739 if ((buf < buf_end)
740 && ((*buf & HALCYON_FIREMASK) == HALCYON_FIRECMD))
741 buf++;
742
743 if (++(*fire_count) < dev_priv->num_fire_offsets)
744 next_fire = dev_priv->fire_offsets[*fire_count];
745 }
746 break;
747 default:
748 while (buf < buf_end) {
749
750 if (*buf == HC_HEADER2 ||
751 (*buf & HALCYON_HEADER1MASK) == HALCYON_HEADER1 ||
752 (*buf & VIA_VIDEOMASK) == VIA_VIDEO_HEADER5 ||
753 (*buf & VIA_VIDEOMASK) == VIA_VIDEO_HEADER6)
754 break;
755
756 VIA_WRITE(HC_REG_TRANS_SPACE + HC_REG_BASE +
757 (burst & 63), *buf++);
758 burst += 4;
759 }
760 }
761 *buffer = buf;
762 return state_command;
763}
764
765static __inline__ int verify_mmio_address(uint32_t address)
766{
767 if ((address > 0x3FF) && (address < 0xC00)) {
768 DRM_ERROR("Invalid VIDEO DMA command. "
769 "Attempt to access 3D- or command burst area.\n");
770 return 1;
771 } else if ((address > 0xCFF) && (address < 0x1300)) {
772 DRM_ERROR("Invalid VIDEO DMA command. "
773 "Attempt to access PCI DMA area.\n");
774 return 1;
775 } else if (address > 0x13FF) {
776 DRM_ERROR("Invalid VIDEO DMA command. "
777 "Attempt to access VGA registers.\n");
778 return 1;
779 }
780 return 0;
781}
782
783static __inline__ int
784verify_video_tail(uint32_t const **buffer, const uint32_t * buf_end,
785 uint32_t dwords)
786{
787 const uint32_t *buf = *buffer;
788
789 if (buf_end - buf < dwords) {
790 DRM_ERROR("Illegal termination of video command.\n");
791 return 1;
792 }
793 while (dwords--) {
794 if (*buf++) {
795 DRM_ERROR("Illegal video command tail.\n");
796 return 1;
797 }
798 }
799 *buffer = buf;
800 return 0;
801}
802
803static __inline__ verifier_state_t
804via_check_header1(uint32_t const **buffer, const uint32_t * buf_end)
805{
806 uint32_t cmd;
807 const uint32_t *buf = *buffer;
808 verifier_state_t ret = state_command;
809
810 while (buf < buf_end) {
811 cmd = *buf;
812 if ((cmd > ((0x3FF >> 2) | HALCYON_HEADER1)) &&
813 (cmd < ((0xC00 >> 2) | HALCYON_HEADER1))) {
814 if ((cmd & HALCYON_HEADER1MASK) != HALCYON_HEADER1)
815 break;
816 DRM_ERROR("Invalid HALCYON_HEADER1 command. "
817 "Attempt to access 3D- or command burst area.\n");
818 ret = state_error;
819 break;
820 } else if (cmd > ((0xCFF >> 2) | HALCYON_HEADER1)) {
821 if ((cmd & HALCYON_HEADER1MASK) != HALCYON_HEADER1)
822 break;
823 DRM_ERROR("Invalid HALCYON_HEADER1 command. "
824 "Attempt to access VGA registers.\n");
825 ret = state_error;
826 break;
827 } else {
828 buf += 2;
829 }
830 }
831 *buffer = buf;
832 return ret;
833}
834
835static __inline__ verifier_state_t
836via_parse_header1(drm_via_private_t * dev_priv, uint32_t const **buffer,
837 const uint32_t * buf_end)
838{
839 register uint32_t cmd;
840 const uint32_t *buf = *buffer;
841
842 while (buf < buf_end) {
843 cmd = *buf;
844 if ((cmd & HALCYON_HEADER1MASK) != HALCYON_HEADER1)
845 break;
846 VIA_WRITE((cmd & ~HALCYON_HEADER1MASK) << 2, *++buf);
847 buf++;
848 }
849 *buffer = buf;
850 return state_command;
851}
852
853static __inline__ verifier_state_t
854via_check_vheader5(uint32_t const **buffer, const uint32_t * buf_end)
855{
856 uint32_t data;
857 const uint32_t *buf = *buffer;
858
859 if (buf_end - buf < 4) {
860 DRM_ERROR("Illegal termination of video header5 command\n");
861 return state_error;
862 }
863
864 data = *buf++ & ~VIA_VIDEOMASK;
865 if (verify_mmio_address(data))
866 return state_error;
867
868 data = *buf++;
869 if (*buf++ != 0x00F50000) {
870 DRM_ERROR("Illegal header5 header data\n");
871 return state_error;
872 }
873 if (*buf++ != 0x00000000) {
874 DRM_ERROR("Illegal header5 header data\n");
875 return state_error;
876 }
877 if (eat_words(&buf, buf_end, data))
878 return state_error;
879 if ((data & 3) && verify_video_tail(&buf, buf_end, 4 - (data & 3)))
880 return state_error;
881 *buffer = buf;
882 return state_command;
883
884}
885
886static __inline__ verifier_state_t
887via_parse_vheader5(drm_via_private_t * dev_priv, uint32_t const **buffer,
888 const uint32_t * buf_end)
889{
890 uint32_t addr, count, i;
891 const uint32_t *buf = *buffer;
892
893 addr = *buf++ & ~VIA_VIDEOMASK;
894 i = count = *buf;
895 buf += 3;
896 while (i--) {
897 VIA_WRITE(addr, *buf++);
898 }
899 if (count & 3)
900 buf += 4 - (count & 3);
901 *buffer = buf;
902 return state_command;
903}
904
905static __inline__ verifier_state_t
906via_check_vheader6(uint32_t const **buffer, const uint32_t * buf_end)
907{
908 uint32_t data;
909 const uint32_t *buf = *buffer;
910 uint32_t i;
911
912 if (buf_end - buf < 4) {
913 DRM_ERROR("Illegal termination of video header6 command\n");
914 return state_error;
915 }
916 buf++;
917 data = *buf++;
918 if (*buf++ != 0x00F60000) {
919 DRM_ERROR("Illegal header6 header data\n");
920 return state_error;
921 }
922 if (*buf++ != 0x00000000) {
923 DRM_ERROR("Illegal header6 header data\n");
924 return state_error;
925 }
926 if ((buf_end - buf) < (data << 1)) {
927 DRM_ERROR("Illegal termination of video header6 command\n");
928 return state_error;
929 }
930 for (i = 0; i < data; ++i) {
931 if (verify_mmio_address(*buf++))
932 return state_error;
933 buf++;
934 }
935 data <<= 1;
936 if ((data & 3) && verify_video_tail(&buf, buf_end, 4 - (data & 3)))
937 return state_error;
938 *buffer = buf;
939 return state_command;
940}
941
942static __inline__ verifier_state_t
943via_parse_vheader6(drm_via_private_t * dev_priv, uint32_t const **buffer,
944 const uint32_t * buf_end)
945{
946
947 uint32_t addr, count, i;
948 const uint32_t *buf = *buffer;
949
950 i = count = *++buf;
951 buf += 3;
952 while (i--) {
953 addr = *buf++;
954 VIA_WRITE(addr, *buf++);
955 }
956 count <<= 1;
957 if (count & 3)
958 buf += 4 - (count & 3);
959 *buffer = buf;
960 return state_command;
961}
962
963int
964via_verify_command_stream(const uint32_t * buf, unsigned int size,
965 struct drm_device * dev, int agp)
966{
967
968 drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
969 drm_via_state_t *hc_state = &dev_priv->hc_state;
970 drm_via_state_t saved_state = *hc_state;
971 uint32_t cmd;
972 const uint32_t *buf_end = buf + (size >> 2);
973 verifier_state_t state = state_command;
974 int cme_video;
975 int supported_3d;
976
977 cme_video = (dev_priv->chipset == VIA_PRO_GROUP_A ||
978 dev_priv->chipset == VIA_DX9_0);
979
980 supported_3d = dev_priv->chipset != VIA_DX9_0;
981
982 hc_state->dev = dev;
983 hc_state->unfinished = no_sequence;
984 hc_state->map_cache = NULL;
985 hc_state->agp = agp;
986 hc_state->buf_start = buf;
987 dev_priv->num_fire_offsets = 0;
988
989 while (buf < buf_end) {
990
991 switch (state) {
992 case state_header2:
993 state = via_check_header2(&buf, buf_end, hc_state);
994 break;
995 case state_header1:
996 state = via_check_header1(&buf, buf_end);
997 break;
998 case state_vheader5:
999 state = via_check_vheader5(&buf, buf_end);
1000 break;
1001 case state_vheader6:
1002 state = via_check_vheader6(&buf, buf_end);
1003 break;
1004 case state_command:
1005 if ((HALCYON_HEADER2 == (cmd = *buf)) &&
1006 supported_3d)
1007 state = state_header2;
1008 else if ((cmd & HALCYON_HEADER1MASK) == HALCYON_HEADER1)
1009 state = state_header1;
1010 else if (cme_video
1011 && (cmd & VIA_VIDEOMASK) == VIA_VIDEO_HEADER5)
1012 state = state_vheader5;
1013 else if (cme_video
1014 && (cmd & VIA_VIDEOMASK) == VIA_VIDEO_HEADER6)
1015 state = state_vheader6;
1016 else if ((cmd == HALCYON_HEADER2) && !supported_3d) {
1017 DRM_ERROR("Accelerated 3D is not supported on this chipset yet.\n");
1018 state = state_error;
1019 } else {
1020 DRM_ERROR
1021 ("Invalid / Unimplemented DMA HEADER command. 0x%x\n",
1022 cmd);
1023 state = state_error;
1024 }
1025 break;
1026 case state_error:
1027 default:
1028 *hc_state = saved_state;
1029 return -EINVAL;
1030 }
1031 }
1032 if (state == state_error) {
1033 *hc_state = saved_state;
1034 return -EINVAL;
1035 }
1036 return 0;
1037}
1038
1039int
1040via_parse_command_stream(struct drm_device * dev, const uint32_t * buf,
1041 unsigned int size)
1042{
1043
1044 drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
1045 uint32_t cmd;
1046 const uint32_t *buf_end = buf + (size >> 2);
1047 verifier_state_t state = state_command;
1048 int fire_count = 0;
1049
1050 while (buf < buf_end) {
1051
1052 switch (state) {
1053 case state_header2:
1054 state =
1055 via_parse_header2(dev_priv, &buf, buf_end,
1056 &fire_count);
1057 break;
1058 case state_header1:
1059 state = via_parse_header1(dev_priv, &buf, buf_end);
1060 break;
1061 case state_vheader5:
1062 state = via_parse_vheader5(dev_priv, &buf, buf_end);
1063 break;
1064 case state_vheader6:
1065 state = via_parse_vheader6(dev_priv, &buf, buf_end);
1066 break;
1067 case state_command:
1068 if (HALCYON_HEADER2 == (cmd = *buf))
1069 state = state_header2;
1070 else if ((cmd & HALCYON_HEADER1MASK) == HALCYON_HEADER1)
1071 state = state_header1;
1072 else if ((cmd & VIA_VIDEOMASK) == VIA_VIDEO_HEADER5)
1073 state = state_vheader5;
1074 else if ((cmd & VIA_VIDEOMASK) == VIA_VIDEO_HEADER6)
1075 state = state_vheader6;
1076 else {
1077 DRM_ERROR
1078 ("Invalid / Unimplemented DMA HEADER command. 0x%x\n",
1079 cmd);
1080 state = state_error;
1081 }
1082 break;
1083 case state_error:
1084 default:
1085 return -EINVAL;
1086 }
1087 }
1088 if (state == state_error) {
1089 return -EINVAL;
1090 }
1091 return 0;
1092}
1093
1094static void
1095setup_hazard_table(hz_init_t init_table[], hazard_t table[], int size)
1096{
1097 int i;
1098
1099 for (i = 0; i < 256; ++i) {
1100 table[i] = forbidden_command;
1101 }
1102
1103 for (i = 0; i < size; ++i) {
1104 table[init_table[i].code] = init_table[i].hz;
1105 }
1106}
1107
1108void via_init_command_verifier(void)
1109{
1110 setup_hazard_table(init_table1, table1,
1111 sizeof(init_table1) / sizeof(hz_init_t));
1112 setup_hazard_table(init_table2, table2,
1113 sizeof(init_table2) / sizeof(hz_init_t));
1114 setup_hazard_table(init_table3, table3,
1115 sizeof(init_table3) / sizeof(hz_init_t));
1116}
diff --git a/drivers/char/drm/via_verifier.h b/drivers/char/drm/via_verifier.h
deleted file mode 100644
index d6f8214b69f5..000000000000
--- a/drivers/char/drm/via_verifier.h
+++ /dev/null
@@ -1,62 +0,0 @@
1/*
2 * Copyright 2004 The Unichrome Project. All Rights Reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sub license,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the
12 * next paragraph) shall be included in all copies or substantial portions
13 * of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18 * THE UNICHROME PROJECT, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 *
23 * Author: Thomas Hellström 2004.
24 */
25
26#ifndef _VIA_VERIFIER_H_
27#define _VIA_VERIFIER_H_
28
29typedef enum {
30 no_sequence = 0,
31 z_address,
32 dest_address,
33 tex_address
34} drm_via_sequence_t;
35
36typedef struct {
37 unsigned texture;
38 uint32_t z_addr;
39 uint32_t d_addr;
40 uint32_t t_addr[2][10];
41 uint32_t pitch[2][10];
42 uint32_t height[2][10];
43 uint32_t tex_level_lo[2];
44 uint32_t tex_level_hi[2];
45 uint32_t tex_palette_size[2];
46 uint32_t tex_npot[2];
47 drm_via_sequence_t unfinished;
48 int agp_texture;
49 int multitex;
50 struct drm_device *dev;
51 drm_local_map_t *map_cache;
52 uint32_t vertex_count;
53 int agp;
54 const uint32_t *buf_start;
55} drm_via_state_t;
56
57extern int via_verify_command_stream(const uint32_t * buf, unsigned int size,
58 struct drm_device * dev, int agp);
59extern int via_parse_command_stream(struct drm_device *dev, const uint32_t *buf,
60 unsigned int size);
61
62#endif
diff --git a/drivers/char/drm/via_video.c b/drivers/char/drm/via_video.c
deleted file mode 100644
index 6ec04ac12459..000000000000
--- a/drivers/char/drm/via_video.c
+++ /dev/null
@@ -1,93 +0,0 @@
1/*
2 * Copyright 2005 Thomas Hellstrom. All Rights Reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sub license,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the
12 * next paragraph) shall be included in all copies or substantial portions
13 * of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHOR(S), AND/OR THE COPYRIGHT HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 *
23 * Author: Thomas Hellstrom 2005.
24 *
25 * Video and XvMC related functions.
26 */
27
28#include "drmP.h"
29#include "via_drm.h"
30#include "via_drv.h"
31
32void via_init_futex(drm_via_private_t * dev_priv)
33{
34 unsigned int i;
35
36 DRM_DEBUG("\n");
37
38 for (i = 0; i < VIA_NR_XVMC_LOCKS; ++i) {
39 DRM_INIT_WAITQUEUE(&(dev_priv->decoder_queue[i]));
40 XVMCLOCKPTR(dev_priv->sarea_priv, i)->lock = 0;
41 }
42}
43
44void via_cleanup_futex(drm_via_private_t * dev_priv)
45{
46}
47
48void via_release_futex(drm_via_private_t * dev_priv, int context)
49{
50 unsigned int i;
51 volatile int *lock;
52
53 if (!dev_priv->sarea_priv)
54 return;
55
56 for (i = 0; i < VIA_NR_XVMC_LOCKS; ++i) {
57 lock = (volatile int *)XVMCLOCKPTR(dev_priv->sarea_priv, i);
58 if ((_DRM_LOCKING_CONTEXT(*lock) == context)) {
59 if (_DRM_LOCK_IS_HELD(*lock)
60 && (*lock & _DRM_LOCK_CONT)) {
61 DRM_WAKEUP(&(dev_priv->decoder_queue[i]));
62 }
63 *lock = 0;
64 }
65 }
66}
67
68int via_decoder_futex(struct drm_device *dev, void *data, struct drm_file *file_priv)
69{
70 drm_via_futex_t *fx = data;
71 volatile int *lock;
72 drm_via_private_t *dev_priv = (drm_via_private_t *) dev->dev_private;
73 drm_via_sarea_t *sAPriv = dev_priv->sarea_priv;
74 int ret = 0;
75
76 DRM_DEBUG("\n");
77
78 if (fx->lock > VIA_NR_XVMC_LOCKS)
79 return -EFAULT;
80
81 lock = (volatile int *)XVMCLOCKPTR(sAPriv, fx->lock);
82
83 switch (fx->func) {
84 case VIA_FUTEX_WAIT:
85 DRM_WAIT_ON(ret, dev_priv->decoder_queue[fx->lock],
86 (fx->ms / 10) * (DRM_HZ / 100), *lock != fx->val);
87 return ret;
88 case VIA_FUTEX_WAKE:
89 DRM_WAKEUP(&(dev_priv->decoder_queue[fx->lock]));
90 return 0;
91 }
92 return 0;
93}
diff --git a/drivers/char/ds1286.c b/drivers/char/ds1286.c
index ea35ab2c9909..fb584938c9c3 100644
--- a/drivers/char/ds1286.c
+++ b/drivers/char/ds1286.c
@@ -27,6 +27,7 @@
27 * option) any later version. 27 * option) any later version.
28 */ 28 */
29#include <linux/ds1286.h> 29#include <linux/ds1286.h>
30#include <linux/smp_lock.h>
30#include <linux/types.h> 31#include <linux/types.h>
31#include <linux/errno.h> 32#include <linux/errno.h>
32#include <linux/miscdevice.h> 33#include <linux/miscdevice.h>
@@ -252,6 +253,7 @@ static int ds1286_ioctl(struct inode *inode, struct file *file,
252 253
253static int ds1286_open(struct inode *inode, struct file *file) 254static int ds1286_open(struct inode *inode, struct file *file)
254{ 255{
256 lock_kernel();
255 spin_lock_irq(&ds1286_lock); 257 spin_lock_irq(&ds1286_lock);
256 258
257 if (ds1286_status & RTC_IS_OPEN) 259 if (ds1286_status & RTC_IS_OPEN)
@@ -260,10 +262,12 @@ static int ds1286_open(struct inode *inode, struct file *file)
260 ds1286_status |= RTC_IS_OPEN; 262 ds1286_status |= RTC_IS_OPEN;
261 263
262 spin_unlock_irq(&ds1286_lock); 264 spin_unlock_irq(&ds1286_lock);
265 unlock_kernel();
263 return 0; 266 return 0;
264 267
265out_busy: 268out_busy:
266 spin_lock_irq(&ds1286_lock); 269 spin_lock_irq(&ds1286_lock);
270 unlock_kernel();
267 return -EBUSY; 271 return -EBUSY;
268} 272}
269 273
diff --git a/drivers/char/ds1620.c b/drivers/char/ds1620.c
index 334ad5bbe6b6..34275c6f1da2 100644
--- a/drivers/char/ds1620.c
+++ b/drivers/char/ds1620.c
@@ -8,6 +8,7 @@
8#include <linux/proc_fs.h> 8#include <linux/proc_fs.h>
9#include <linux/capability.h> 9#include <linux/capability.h>
10#include <linux/init.h> 10#include <linux/init.h>
11#include <linux/smp_lock.h>
11 12
12#include <asm/hardware.h> 13#include <asm/hardware.h>
13#include <asm/mach-types.h> 14#include <asm/mach-types.h>
@@ -208,6 +209,12 @@ static void ds1620_read_state(struct therm *therm)
208 therm->hi = cvt_9_to_int(ds1620_in(THERM_READ_TH, 9)); 209 therm->hi = cvt_9_to_int(ds1620_in(THERM_READ_TH, 9));
209} 210}
210 211
212static int ds1620_open(struct inode *inode, struct file *file)
213{
214 cycle_kernel_lock();
215 return nonseekable_open(inode, file);
216}
217
211static ssize_t 218static ssize_t
212ds1620_read(struct file *file, char __user *buf, size_t count, loff_t *ptr) 219ds1620_read(struct file *file, char __user *buf, size_t count, loff_t *ptr)
213{ 220{
@@ -336,7 +343,7 @@ static struct proc_dir_entry *proc_therm_ds1620;
336 343
337static const struct file_operations ds1620_fops = { 344static const struct file_operations ds1620_fops = {
338 .owner = THIS_MODULE, 345 .owner = THIS_MODULE,
339 .open = nonseekable_open, 346 .open = ds1620_open,
340 .read = ds1620_read, 347 .read = ds1620_read,
341 .ioctl = ds1620_ioctl, 348 .ioctl = ds1620_ioctl,
342}; 349};
diff --git a/drivers/char/dsp56k.c b/drivers/char/dsp56k.c
index a69c65283260..b9a30c30e2b8 100644
--- a/drivers/char/dsp56k.c
+++ b/drivers/char/dsp56k.c
@@ -33,6 +33,9 @@
33#include <linux/mm.h> 33#include <linux/mm.h>
34#include <linux/init.h> 34#include <linux/init.h>
35#include <linux/device.h> 35#include <linux/device.h>
36#include <linux/smp_lock.h>
37#include <linux/firmware.h>
38#include <linux/platform_device.h>
36 39
37#include <asm/atarihw.h> 40#include <asm/atarihw.h>
38#include <asm/traps.h> 41#include <asm/traps.h>
@@ -92,49 +95,6 @@
92 } \ 95 } \
93} 96}
94 97
95/* DSP56001 bootstrap code */
96static char bootstrap[] = {
97 0x0c, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
98 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
99 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
100 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
101 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
102 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
103 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
104 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
105 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
106 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
107 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
108 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
109 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
110 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
111 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
112 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
113 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
114 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
115 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
116 0x00, 0x00, 0x60, 0xf4, 0x00, 0x00, 0x00, 0x4f, 0x61, 0xf4,
117 0x00, 0x00, 0x7e, 0xa9, 0x06, 0x2e, 0x80, 0x00, 0x00, 0x47,
118 0x07, 0xd8, 0x84, 0x07, 0x59, 0x84, 0x08, 0xf4, 0xa8, 0x00,
119 0x00, 0x04, 0x08, 0xf4, 0xbf, 0x00, 0x0c, 0x00, 0x00, 0xfe,
120 0xb8, 0x0a, 0xf0, 0x80, 0x00, 0x7e, 0xa9, 0x08, 0xf4, 0xa0,
121 0x00, 0x00, 0x01, 0x08, 0xf4, 0xbe, 0x00, 0x00, 0x00, 0x0a,
122 0xa9, 0x80, 0x00, 0x7e, 0xad, 0x08, 0x4e, 0x2b, 0x44, 0xf4,
123 0x00, 0x00, 0x00, 0x03, 0x44, 0xf4, 0x45, 0x00, 0x00, 0x01,
124 0x0e, 0xa0, 0x00, 0x0a, 0xa9, 0x80, 0x00, 0x7e, 0xb5, 0x08,
125 0x50, 0x2b, 0x0a, 0xa9, 0x80, 0x00, 0x7e, 0xb8, 0x08, 0x46,
126 0x2b, 0x44, 0xf4, 0x45, 0x00, 0x00, 0x02, 0x0a, 0xf0, 0xaa,
127 0x00, 0x7e, 0xc9, 0x20, 0x00, 0x45, 0x0a, 0xf0, 0xaa, 0x00,
128 0x7e, 0xd0, 0x06, 0xc6, 0x00, 0x00, 0x7e, 0xc6, 0x0a, 0xa9,
129 0x80, 0x00, 0x7e, 0xc4, 0x08, 0x58, 0x6b, 0x0a, 0xf0, 0x80,
130 0x00, 0x7e, 0xad, 0x06, 0xc6, 0x00, 0x00, 0x7e, 0xcd, 0x0a,
131 0xa9, 0x80, 0x00, 0x7e, 0xcb, 0x08, 0x58, 0xab, 0x0a, 0xf0,
132 0x80, 0x00, 0x7e, 0xad, 0x06, 0xc6, 0x00, 0x00, 0x7e, 0xd4,
133 0x0a, 0xa9, 0x80, 0x00, 0x7e, 0xd2, 0x08, 0x58, 0xeb, 0x0a,
134 0xf0, 0x80, 0x00, 0x7e, 0xad};
135static int sizeof_bootstrap = 375;
136
137
138static struct dsp56k_device { 98static struct dsp56k_device {
139 unsigned long in_use; 99 unsigned long in_use;
140 long maxio, timeout; 100 long maxio, timeout;
@@ -164,18 +124,40 @@ static int dsp56k_reset(void)
164 124
165static int dsp56k_upload(u_char __user *bin, int len) 125static int dsp56k_upload(u_char __user *bin, int len)
166{ 126{
127 struct platform_device *pdev;
128 const struct firmware *fw;
129 const char fw_name[] = "dsp56k/bootstrap.bin";
130 int err;
167 int i; 131 int i;
168 u_char *p; 132
169
170 dsp56k_reset(); 133 dsp56k_reset();
171 134
172 p = bootstrap; 135 pdev = platform_device_register_simple("dsp56k", 0, NULL, 0);
173 for (i = 0; i < sizeof_bootstrap/3; i++) { 136 if (IS_ERR(pdev)) {
137 printk(KERN_ERR "Failed to register device for \"%s\"\n",
138 fw_name);
139 return -EINVAL;
140 }
141 err = request_firmware(&fw, fw_name, &pdev->dev);
142 platform_device_unregister(pdev);
143 if (err) {
144 printk(KERN_ERR "Failed to load image \"%s\" err %d\n",
145 fw_name, err);
146 return err;
147 }
148 if (fw->size % 3) {
149 printk(KERN_ERR "Bogus length %d in image \"%s\"\n",
150 fw->size, fw_name);
151 release_firmware(fw);
152 return -EINVAL;
153 }
154 for (i = 0; i < fw->size; i = i + 3) {
174 /* tx_wait(10); */ 155 /* tx_wait(10); */
175 dsp56k_host_interface.data.b[1] = *p++; 156 dsp56k_host_interface.data.b[1] = fw->data[i];
176 dsp56k_host_interface.data.b[2] = *p++; 157 dsp56k_host_interface.data.b[2] = fw->data[i + 1];
177 dsp56k_host_interface.data.b[3] = *p++; 158 dsp56k_host_interface.data.b[3] = fw->data[i + 2];
178 } 159 }
160 release_firmware(fw);
179 for (; i < 512; i++) { 161 for (; i < 512; i++) {
180 /* tx_wait(10); */ 162 /* tx_wait(10); */
181 dsp56k_host_interface.data.b[1] = 0; 163 dsp56k_host_interface.data.b[1] = 0;
@@ -436,13 +418,17 @@ static unsigned int dsp56k_poll(struct file *file, poll_table *wait)
436static int dsp56k_open(struct inode *inode, struct file *file) 418static int dsp56k_open(struct inode *inode, struct file *file)
437{ 419{
438 int dev = iminor(inode) & 0x0f; 420 int dev = iminor(inode) & 0x0f;
421 int ret = 0;
439 422
423 lock_kernel();
440 switch(dev) 424 switch(dev)
441 { 425 {
442 case DSP56K_DEV_56001: 426 case DSP56K_DEV_56001:
443 427
444 if (test_and_set_bit(0, &dsp56k.in_use)) 428 if (test_and_set_bit(0, &dsp56k.in_use)) {
445 return -EBUSY; 429 ret = -EBUSY;
430 goto out;
431 }
446 432
447 dsp56k.timeout = TIMEOUT; 433 dsp56k.timeout = TIMEOUT;
448 dsp56k.maxio = MAXIO; 434 dsp56k.maxio = MAXIO;
@@ -458,10 +444,11 @@ static int dsp56k_open(struct inode *inode, struct file *file)
458 break; 444 break;
459 445
460 default: 446 default:
461 return -ENODEV; 447 ret = -ENODEV;
462 } 448 }
463 449out:
464 return 0; 450 unlock_kernel();
451 return ret;
465} 452}
466 453
467static int dsp56k_release(struct inode *inode, struct file *file) 454static int dsp56k_release(struct inode *inode, struct file *file)
@@ -534,3 +521,4 @@ static void __exit dsp56k_cleanup_driver(void)
534module_exit(dsp56k_cleanup_driver); 521module_exit(dsp56k_cleanup_driver);
535 522
536MODULE_LICENSE("GPL"); 523MODULE_LICENSE("GPL");
524MODULE_FIRMWARE("dsp56k/bootstrap.bin");
diff --git a/drivers/char/dtlk.c b/drivers/char/dtlk.c
index abde6ddefe69..6b900b297cc6 100644
--- a/drivers/char/dtlk.c
+++ b/drivers/char/dtlk.c
@@ -56,6 +56,7 @@
56#include <linux/errno.h> /* for -EBUSY */ 56#include <linux/errno.h> /* for -EBUSY */
57#include <linux/ioport.h> /* for request_region */ 57#include <linux/ioport.h> /* for request_region */
58#include <linux/delay.h> /* for loops_per_jiffy */ 58#include <linux/delay.h> /* for loops_per_jiffy */
59#include <linux/smp_lock.h> /* cycle_kernel_lock() */
59#include <asm/io.h> /* for inb_p, outb_p, inb, outb, etc. */ 60#include <asm/io.h> /* for inb_p, outb_p, inb, outb, etc. */
60#include <asm/uaccess.h> /* for get_user, etc. */ 61#include <asm/uaccess.h> /* for get_user, etc. */
61#include <linux/wait.h> /* for wait_queue */ 62#include <linux/wait.h> /* for wait_queue */
@@ -288,10 +289,12 @@ static int dtlk_ioctl(struct inode *inode,
288 } 289 }
289} 290}
290 291
292/* Note that nobody ever sets dtlk_busy... */
291static int dtlk_open(struct inode *inode, struct file *file) 293static int dtlk_open(struct inode *inode, struct file *file)
292{ 294{
293 TRACE_TEXT("(dtlk_open"); 295 TRACE_TEXT("(dtlk_open");
294 296
297 cycle_kernel_lock();
295 nonseekable_open(inode, file); 298 nonseekable_open(inode, file);
296 switch (iminor(inode)) { 299 switch (iminor(inode)) {
297 case DTLK_MINOR: 300 case DTLK_MINOR:
diff --git a/drivers/char/efirtc.c b/drivers/char/efirtc.c
index 49233f589874..d57ca3e4e534 100644
--- a/drivers/char/efirtc.c
+++ b/drivers/char/efirtc.c
@@ -28,6 +28,7 @@
28 */ 28 */
29 29
30 30
31#include <linux/smp_lock.h>
31#include <linux/types.h> 32#include <linux/types.h>
32#include <linux/errno.h> 33#include <linux/errno.h>
33#include <linux/miscdevice.h> 34#include <linux/miscdevice.h>
@@ -272,6 +273,7 @@ efi_rtc_open(struct inode *inode, struct file *file)
272 * We do accept multiple open files at the same time as we 273 * We do accept multiple open files at the same time as we
273 * synchronize on the per call operation. 274 * synchronize on the per call operation.
274 */ 275 */
276 cycle_kernel_lock();
275 return 0; 277 return 0;
276} 278}
277 279
diff --git a/drivers/char/epca.c b/drivers/char/epca.c
index 60a4df7dac12..ac9995f6578b 100644
--- a/drivers/char/epca.c
+++ b/drivers/char/epca.c
@@ -432,7 +432,7 @@ static void pc_close(struct tty_struct *tty, struct file *filp)
432 spin_unlock_irqrestore(&epca_lock, flags); 432 spin_unlock_irqrestore(&epca_lock, flags);
433 return; 433 return;
434 } 434 }
435 if (ch->count-- > 1) { 435 if (ch->port.count-- > 1) {
436 /* Begin channel is open more than once */ 436 /* Begin channel is open more than once */
437 /* 437 /*
438 * Return without doing anything. Someone might still 438 * Return without doing anything. Someone might still
@@ -442,19 +442,19 @@ static void pc_close(struct tty_struct *tty, struct file *filp)
442 return; 442 return;
443 } 443 }
444 /* Port open only once go ahead with shutdown & reset */ 444 /* Port open only once go ahead with shutdown & reset */
445 BUG_ON(ch->count < 0); 445 BUG_ON(ch->port.count < 0);
446 446
447 /* 447 /*
448 * Let the rest of the driver know the channel is being closed. 448 * Let the rest of the driver know the channel is being closed.
449 * This becomes important if an open is attempted before close 449 * This becomes important if an open is attempted before close
450 * is finished. 450 * is finished.
451 */ 451 */
452 ch->asyncflags |= ASYNC_CLOSING; 452 ch->port.flags |= ASYNC_CLOSING;
453 tty->closing = 1; 453 tty->closing = 1;
454 454
455 spin_unlock_irqrestore(&epca_lock, flags); 455 spin_unlock_irqrestore(&epca_lock, flags);
456 456
457 if (ch->asyncflags & ASYNC_INITIALIZED) { 457 if (ch->port.flags & ASYNC_INITIALIZED) {
458 /* Setup an event to indicate when the 458 /* Setup an event to indicate when the
459 transmit buffer empties */ 459 transmit buffer empties */
460 setup_empty_event(tty, ch); 460 setup_empty_event(tty, ch);
@@ -469,17 +469,17 @@ static void pc_close(struct tty_struct *tty, struct file *filp)
469 spin_lock_irqsave(&epca_lock, flags); 469 spin_lock_irqsave(&epca_lock, flags);
470 tty->closing = 0; 470 tty->closing = 0;
471 ch->event = 0; 471 ch->event = 0;
472 ch->tty = NULL; 472 ch->port.tty = NULL;
473 spin_unlock_irqrestore(&epca_lock, flags); 473 spin_unlock_irqrestore(&epca_lock, flags);
474 474
475 if (ch->blocked_open) { 475 if (ch->port.blocked_open) {
476 if (ch->close_delay) 476 if (ch->close_delay)
477 msleep_interruptible(jiffies_to_msecs(ch->close_delay)); 477 msleep_interruptible(jiffies_to_msecs(ch->close_delay));
478 wake_up_interruptible(&ch->open_wait); 478 wake_up_interruptible(&ch->port.open_wait);
479 } 479 }
480 ch->asyncflags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_INITIALIZED | 480 ch->port.flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_INITIALIZED |
481 ASYNC_CLOSING); 481 ASYNC_CLOSING);
482 wake_up_interruptible(&ch->close_wait); 482 wake_up_interruptible(&ch->port.close_wait);
483 } 483 }
484} 484}
485 485
@@ -489,7 +489,7 @@ static void shutdown(struct channel *ch)
489 struct tty_struct *tty; 489 struct tty_struct *tty;
490 struct board_chan __iomem *bc; 490 struct board_chan __iomem *bc;
491 491
492 if (!(ch->asyncflags & ASYNC_INITIALIZED)) 492 if (!(ch->port.flags & ASYNC_INITIALIZED))
493 return; 493 return;
494 494
495 spin_lock_irqsave(&epca_lock, flags); 495 spin_lock_irqsave(&epca_lock, flags);
@@ -504,7 +504,7 @@ static void shutdown(struct channel *ch)
504 */ 504 */
505 if (bc) 505 if (bc)
506 writeb(0, &bc->idata); 506 writeb(0, &bc->idata);
507 tty = ch->tty; 507 tty = ch->port.tty;
508 508
509 /* If we're a modem control device and HUPCL is on, drop RTS & DTR. */ 509 /* If we're a modem control device and HUPCL is on, drop RTS & DTR. */
510 if (tty->termios->c_cflag & HUPCL) { 510 if (tty->termios->c_cflag & HUPCL) {
@@ -518,7 +518,7 @@ static void shutdown(struct channel *ch)
518 * will have to reinitialized. Set a flag to indicate this. 518 * will have to reinitialized. Set a flag to indicate this.
519 */ 519 */
520 /* Prevent future Digi programmed interrupts from coming active */ 520 /* Prevent future Digi programmed interrupts from coming active */
521 ch->asyncflags &= ~ASYNC_INITIALIZED; 521 ch->port.flags &= ~ASYNC_INITIALIZED;
522 spin_unlock_irqrestore(&epca_lock, flags); 522 spin_unlock_irqrestore(&epca_lock, flags);
523} 523}
524 524
@@ -538,12 +538,12 @@ static void pc_hangup(struct tty_struct *tty)
538 shutdown(ch); 538 shutdown(ch);
539 539
540 spin_lock_irqsave(&epca_lock, flags); 540 spin_lock_irqsave(&epca_lock, flags);
541 ch->tty = NULL; 541 ch->port.tty = NULL;
542 ch->event = 0; 542 ch->event = 0;
543 ch->count = 0; 543 ch->port.count = 0;
544 ch->asyncflags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_INITIALIZED); 544 ch->port.flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_INITIALIZED);
545 spin_unlock_irqrestore(&epca_lock, flags); 545 spin_unlock_irqrestore(&epca_lock, flags);
546 wake_up_interruptible(&ch->open_wait); 546 wake_up_interruptible(&ch->port.open_wait);
547 } 547 }
548} 548}
549 549
@@ -795,7 +795,7 @@ static int block_til_ready(struct tty_struct *tty,
795 unsigned long flags; 795 unsigned long flags;
796 796
797 if (tty_hung_up_p(filp)) { 797 if (tty_hung_up_p(filp)) {
798 if (ch->asyncflags & ASYNC_HUP_NOTIFY) 798 if (ch->port.flags & ASYNC_HUP_NOTIFY)
799 retval = -EAGAIN; 799 retval = -EAGAIN;
800 else 800 else
801 retval = -ERESTARTSYS; 801 retval = -ERESTARTSYS;
@@ -806,10 +806,10 @@ static int block_til_ready(struct tty_struct *tty,
806 * If the device is in the middle of being closed, then block until 806 * If the device is in the middle of being closed, then block until
807 * it's done, and then try again. 807 * it's done, and then try again.
808 */ 808 */
809 if (ch->asyncflags & ASYNC_CLOSING) { 809 if (ch->port.flags & ASYNC_CLOSING) {
810 interruptible_sleep_on(&ch->close_wait); 810 interruptible_sleep_on(&ch->port.close_wait);
811 811
812 if (ch->asyncflags & ASYNC_HUP_NOTIFY) 812 if (ch->port.flags & ASYNC_HUP_NOTIFY)
813 return -EAGAIN; 813 return -EAGAIN;
814 else 814 else
815 return -ERESTARTSYS; 815 return -ERESTARTSYS;
@@ -820,7 +820,7 @@ static int block_til_ready(struct tty_struct *tty,
820 * If non-blocking mode is set, then make the check up front 820 * If non-blocking mode is set, then make the check up front
821 * and then exit. 821 * and then exit.
822 */ 822 */
823 ch->asyncflags |= ASYNC_NORMAL_ACTIVE; 823 ch->port.flags |= ASYNC_NORMAL_ACTIVE;
824 return 0; 824 return 0;
825 } 825 }
826 if (tty->termios->c_cflag & CLOCAL) 826 if (tty->termios->c_cflag & CLOCAL)
@@ -828,24 +828,24 @@ static int block_til_ready(struct tty_struct *tty,
828 /* Block waiting for the carrier detect and the line to become free */ 828 /* Block waiting for the carrier detect and the line to become free */
829 829
830 retval = 0; 830 retval = 0;
831 add_wait_queue(&ch->open_wait, &wait); 831 add_wait_queue(&ch->port.open_wait, &wait);
832 832
833 spin_lock_irqsave(&epca_lock, flags); 833 spin_lock_irqsave(&epca_lock, flags);
834 /* We dec count so that pc_close will know when to free things */ 834 /* We dec count so that pc_close will know when to free things */
835 if (!tty_hung_up_p(filp)) 835 if (!tty_hung_up_p(filp))
836 ch->count--; 836 ch->port.count--;
837 ch->blocked_open++; 837 ch->port.blocked_open++;
838 while (1) { 838 while (1) {
839 set_current_state(TASK_INTERRUPTIBLE); 839 set_current_state(TASK_INTERRUPTIBLE);
840 if (tty_hung_up_p(filp) || 840 if (tty_hung_up_p(filp) ||
841 !(ch->asyncflags & ASYNC_INITIALIZED)) { 841 !(ch->port.flags & ASYNC_INITIALIZED)) {
842 if (ch->asyncflags & ASYNC_HUP_NOTIFY) 842 if (ch->port.flags & ASYNC_HUP_NOTIFY)
843 retval = -EAGAIN; 843 retval = -EAGAIN;
844 else 844 else
845 retval = -ERESTARTSYS; 845 retval = -ERESTARTSYS;
846 break; 846 break;
847 } 847 }
848 if (!(ch->asyncflags & ASYNC_CLOSING) && 848 if (!(ch->port.flags & ASYNC_CLOSING) &&
849 (do_clocal || (ch->imodem & ch->dcd))) 849 (do_clocal || (ch->imodem & ch->dcd)))
850 break; 850 break;
851 if (signal_pending(current)) { 851 if (signal_pending(current)) {
@@ -864,17 +864,17 @@ static int block_til_ready(struct tty_struct *tty,
864 } 864 }
865 865
866 __set_current_state(TASK_RUNNING); 866 __set_current_state(TASK_RUNNING);
867 remove_wait_queue(&ch->open_wait, &wait); 867 remove_wait_queue(&ch->port.open_wait, &wait);
868 if (!tty_hung_up_p(filp)) 868 if (!tty_hung_up_p(filp))
869 ch->count++; 869 ch->port.count++;
870 ch->blocked_open--; 870 ch->port.blocked_open--;
871 871
872 spin_unlock_irqrestore(&epca_lock, flags); 872 spin_unlock_irqrestore(&epca_lock, flags);
873 873
874 if (retval) 874 if (retval)
875 return retval; 875 return retval;
876 876
877 ch->asyncflags |= ASYNC_NORMAL_ACTIVE; 877 ch->port.flags |= ASYNC_NORMAL_ACTIVE;
878 return 0; 878 return 0;
879} 879}
880 880
@@ -933,7 +933,7 @@ static int pc_open(struct tty_struct *tty, struct file *filp)
933 * necessary because we do not wish to flush and shutdown the channel 933 * necessary because we do not wish to flush and shutdown the channel
934 * until the last app holding the channel open, closes it. 934 * until the last app holding the channel open, closes it.
935 */ 935 */
936 ch->count++; 936 ch->port.count++;
937 /* 937 /*
938 * Set a kernel structures pointer to our local channel structure. This 938 * Set a kernel structures pointer to our local channel structure. This
939 * way we can get to it when passed only a tty struct. 939 * way we can get to it when passed only a tty struct.
@@ -957,14 +957,14 @@ static int pc_open(struct tty_struct *tty, struct file *filp)
957 writew(head, &bc->rout); 957 writew(head, &bc->rout);
958 958
959 /* Set the channels associated tty structure */ 959 /* Set the channels associated tty structure */
960 ch->tty = tty; 960 ch->port.tty = tty;
961 961
962 /* 962 /*
963 * The below routine generally sets up parity, baud, flow control 963 * The below routine generally sets up parity, baud, flow control
964 * issues, etc.... It effect both control flags and input flags. 964 * issues, etc.... It effect both control flags and input flags.
965 */ 965 */
966 epcaparam(tty, ch); 966 epcaparam(tty, ch);
967 ch->asyncflags |= ASYNC_INITIALIZED; 967 ch->port.flags |= ASYNC_INITIALIZED;
968 memoff(ch); 968 memoff(ch);
969 spin_unlock_irqrestore(&epca_lock, flags); 969 spin_unlock_irqrestore(&epca_lock, flags);
970 970
@@ -976,7 +976,7 @@ static int pc_open(struct tty_struct *tty, struct file *filp)
976 * waiting for the line... 976 * waiting for the line...
977 */ 977 */
978 spin_lock_irqsave(&epca_lock, flags); 978 spin_lock_irqsave(&epca_lock, flags);
979 ch->tty = tty; 979 ch->port.tty = tty;
980 globalwinon(ch); 980 globalwinon(ch);
981 /* Enable Digi Data events */ 981 /* Enable Digi Data events */
982 writeb(1, &bc->idata); 982 writeb(1, &bc->idata);
@@ -1017,8 +1017,8 @@ static void __exit epca_module_exit(void)
1017 } 1017 }
1018 ch = card_ptr[crd]; 1018 ch = card_ptr[crd];
1019 for (count = 0; count < bd->numports; count++, ch++) { 1019 for (count = 0; count < bd->numports; count++, ch++) {
1020 if (ch && ch->tty) 1020 if (ch && ch->port.tty)
1021 tty_hangup(ch->tty); 1021 tty_hangup(ch->port.tty);
1022 } 1022 }
1023 } 1023 }
1024 pci_unregister_driver(&epca_driver); 1024 pci_unregister_driver(&epca_driver);
@@ -1427,7 +1427,7 @@ static void post_fep_init(unsigned int crd)
1427 ch->boardnum = crd; 1427 ch->boardnum = crd;
1428 ch->channelnum = i; 1428 ch->channelnum = i;
1429 ch->magic = EPCA_MAGIC; 1429 ch->magic = EPCA_MAGIC;
1430 ch->tty = NULL; 1430 ch->port.tty = NULL;
1431 1431
1432 if (shrinkmem) { 1432 if (shrinkmem) {
1433 fepcmd(ch, SETBUFFER, 32, 0, 0, 0); 1433 fepcmd(ch, SETBUFFER, 32, 0, 0, 0);
@@ -1510,10 +1510,10 @@ static void post_fep_init(unsigned int crd)
1510 ch->fepstopca = 0; 1510 ch->fepstopca = 0;
1511 1511
1512 ch->close_delay = 50; 1512 ch->close_delay = 50;
1513 ch->count = 0; 1513 ch->port.count = 0;
1514 ch->blocked_open = 0; 1514 ch->port.blocked_open = 0;
1515 init_waitqueue_head(&ch->open_wait); 1515 init_waitqueue_head(&ch->port.open_wait);
1516 init_waitqueue_head(&ch->close_wait); 1516 init_waitqueue_head(&ch->port.close_wait);
1517 1517
1518 spin_unlock_irqrestore(&epca_lock, flags); 1518 spin_unlock_irqrestore(&epca_lock, flags);
1519 } 1519 }
@@ -1633,15 +1633,15 @@ static void doevent(int crd)
1633 if (event & MODEMCHG_IND) { 1633 if (event & MODEMCHG_IND) {
1634 /* A modem signal change has been indicated */ 1634 /* A modem signal change has been indicated */
1635 ch->imodem = mstat; 1635 ch->imodem = mstat;
1636 if (ch->asyncflags & ASYNC_CHECK_CD) { 1636 if (ch->port.flags & ASYNC_CHECK_CD) {
1637 /* We are now receiving dcd */ 1637 /* We are now receiving dcd */
1638 if (mstat & ch->dcd) 1638 if (mstat & ch->dcd)
1639 wake_up_interruptible(&ch->open_wait); 1639 wake_up_interruptible(&ch->port.open_wait);
1640 else /* No dcd; hangup */ 1640 else /* No dcd; hangup */
1641 pc_sched_event(ch, EPCA_EVENT_HANGUP); 1641 pc_sched_event(ch, EPCA_EVENT_HANGUP);
1642 } 1642 }
1643 } 1643 }
1644 tty = ch->tty; 1644 tty = ch->port.tty;
1645 if (tty) { 1645 if (tty) {
1646 if (event & BREAK_IND) { 1646 if (event & BREAK_IND) {
1647 /* A break has been indicated */ 1647 /* A break has been indicated */
@@ -1880,9 +1880,9 @@ static void epcaparam(struct tty_struct *tty, struct channel *ch)
1880 * that the driver will wait on carrier detect. 1880 * that the driver will wait on carrier detect.
1881 */ 1881 */
1882 if (ts->c_cflag & CLOCAL) 1882 if (ts->c_cflag & CLOCAL)
1883 ch->asyncflags &= ~ASYNC_CHECK_CD; 1883 ch->port.flags &= ~ASYNC_CHECK_CD;
1884 else 1884 else
1885 ch->asyncflags |= ASYNC_CHECK_CD; 1885 ch->port.flags |= ASYNC_CHECK_CD;
1886 mval = ch->m_dtr | ch->m_rts; 1886 mval = ch->m_dtr | ch->m_rts;
1887 } /* End CBAUD not detected */ 1887 } /* End CBAUD not detected */
1888 iflag = termios2digi_i(ch, ts->c_iflag); 1888 iflag = termios2digi_i(ch, ts->c_iflag);
@@ -1972,7 +1972,7 @@ static void receive_data(struct channel *ch)
1972 globalwinon(ch); 1972 globalwinon(ch);
1973 if (ch->statusflags & RXSTOPPED) 1973 if (ch->statusflags & RXSTOPPED)
1974 return; 1974 return;
1975 tty = ch->tty; 1975 tty = ch->port.tty;
1976 if (tty) 1976 if (tty)
1977 ts = tty->termios; 1977 ts = tty->termios;
1978 bc = ch->brdchan; 1978 bc = ch->brdchan;
@@ -2032,7 +2032,7 @@ static void receive_data(struct channel *ch)
2032 globalwinon(ch); 2032 globalwinon(ch);
2033 writew(tail, &bc->rout); 2033 writew(tail, &bc->rout);
2034 /* Must be called with global data */ 2034 /* Must be called with global data */
2035 tty_schedule_flip(ch->tty); 2035 tty_schedule_flip(ch->port.tty);
2036} 2036}
2037 2037
2038static int info_ioctl(struct tty_struct *tty, struct file *file, 2038static int info_ioctl(struct tty_struct *tty, struct file *file,
@@ -2262,8 +2262,8 @@ static int pc_ioctl(struct tty_struct *tty, struct file *file,
2262 tty_wait_until_sent(tty, 0); 2262 tty_wait_until_sent(tty, 0);
2263 } else { 2263 } else {
2264 /* ldisc lock already held in ioctl */ 2264 /* ldisc lock already held in ioctl */
2265 if (tty->ldisc.flush_buffer) 2265 if (tty->ldisc.ops->flush_buffer)
2266 tty->ldisc.flush_buffer(tty); 2266 tty->ldisc.ops->flush_buffer(tty);
2267 } 2267 }
2268 unlock_kernel(); 2268 unlock_kernel();
2269 /* Fall Thru */ 2269 /* Fall Thru */
@@ -2376,7 +2376,7 @@ static void pc_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
2376 2376
2377 if (!(old_termios->c_cflag & CLOCAL) && 2377 if (!(old_termios->c_cflag & CLOCAL) &&
2378 (tty->termios->c_cflag & CLOCAL)) 2378 (tty->termios->c_cflag & CLOCAL))
2379 wake_up_interruptible(&ch->open_wait); 2379 wake_up_interruptible(&ch->port.open_wait);
2380 2380
2381 } /* End if channel valid */ 2381 } /* End if channel valid */
2382} 2382}
@@ -2386,13 +2386,13 @@ static void do_softint(struct work_struct *work)
2386 struct channel *ch = container_of(work, struct channel, tqueue); 2386 struct channel *ch = container_of(work, struct channel, tqueue);
2387 /* Called in response to a modem change event */ 2387 /* Called in response to a modem change event */
2388 if (ch && ch->magic == EPCA_MAGIC) { 2388 if (ch && ch->magic == EPCA_MAGIC) {
2389 struct tty_struct *tty = ch->tty; 2389 struct tty_struct *tty = ch->port.tty;
2390 2390
2391 if (tty && tty->driver_data) { 2391 if (tty && tty->driver_data) {
2392 if (test_and_clear_bit(EPCA_EVENT_HANGUP, &ch->event)) { 2392 if (test_and_clear_bit(EPCA_EVENT_HANGUP, &ch->event)) {
2393 tty_hangup(tty); 2393 tty_hangup(tty);
2394 wake_up_interruptible(&ch->open_wait); 2394 wake_up_interruptible(&ch->port.open_wait);
2395 ch->asyncflags &= ~ASYNC_NORMAL_ACTIVE; 2395 ch->port.flags &= ~ASYNC_NORMAL_ACTIVE;
2396 } 2396 }
2397 } 2397 }
2398 } 2398 }
diff --git a/drivers/char/epca.h b/drivers/char/epca.h
index 3c77c02b5d65..d414bf2dbf7c 100644
--- a/drivers/char/epca.h
+++ b/drivers/char/epca.h
@@ -84,6 +84,7 @@ static char *board_desc[] =
84struct channel 84struct channel
85{ 85{
86 long magic; 86 long magic;
87 struct tty_port port;
87 unsigned char boardnum; 88 unsigned char boardnum;
88 unsigned char channelnum; 89 unsigned char channelnum;
89 unsigned char omodem; /* FEP output modem status */ 90 unsigned char omodem; /* FEP output modem status */
@@ -117,10 +118,7 @@ struct channel
117 unsigned short rxbufhead; 118 unsigned short rxbufhead;
118 unsigned short rxbufsize; 119 unsigned short rxbufsize;
119 int close_delay; 120 int close_delay;
120 int count;
121 int blocked_open;
122 unsigned long event; 121 unsigned long event;
123 int asyncflags;
124 uint dev; 122 uint dev;
125 unsigned long statusflags; 123 unsigned long statusflags;
126 unsigned long c_iflag; 124 unsigned long c_iflag;
@@ -132,9 +130,6 @@ struct channel
132 struct board_info *board; 130 struct board_info *board;
133 struct board_chan __iomem *brdchan; 131 struct board_chan __iomem *brdchan;
134 struct digi_struct digiext; 132 struct digi_struct digiext;
135 struct tty_struct *tty;
136 wait_queue_head_t open_wait;
137 wait_queue_head_t close_wait;
138 struct work_struct tqueue; 133 struct work_struct tqueue;
139 struct global_data __iomem *mailbox; 134 struct global_data __iomem *mailbox;
140}; 135};
diff --git a/drivers/char/esp.c b/drivers/char/esp.c
index 84840ba13ff0..2eaf09f93e3d 100644
--- a/drivers/char/esp.c
+++ b/drivers/char/esp.c
@@ -128,9 +128,9 @@ static struct tty_driver *esp_driver;
128 128
129#if defined(MODULE) && defined(SERIAL_DEBUG_MCOUNT) 129#if defined(MODULE) && defined(SERIAL_DEBUG_MCOUNT)
130#define DBG_CNT(s) printk(KERN_DEBUG "(%s): [%x] refc=%d, serc=%d, ttyc=%d -> %s\n", \ 130#define DBG_CNT(s) printk(KERN_DEBUG "(%s): [%x] refc=%d, serc=%d, ttyc=%d -> %s\n", \
131 tty->name, info->flags, \ 131 tty->name, info->port.flags, \
132 serial_driver.refcount, \ 132 serial_driver.refcount, \
133 info->count, tty->count, s) 133 info->port.count, tty->count, s)
134#else 134#else
135#define DBG_CNT(s) 135#define DBG_CNT(s)
136#endif 136#endif
@@ -172,13 +172,13 @@ static inline int serial_paranoia_check(struct esp_struct *info,
172 172
173static inline unsigned int serial_in(struct esp_struct *info, int offset) 173static inline unsigned int serial_in(struct esp_struct *info, int offset)
174{ 174{
175 return inb(info->port + offset); 175 return inb(info->io_port + offset);
176} 176}
177 177
178static inline void serial_out(struct esp_struct *info, int offset, 178static inline void serial_out(struct esp_struct *info, int offset,
179 unsigned char value) 179 unsigned char value)
180{ 180{
181 outb(value, info->port+offset); 181 outb(value, info->io_port+offset);
182} 182}
183 183
184/* 184/*
@@ -273,7 +273,7 @@ static inline void release_pio_buffer(struct esp_pio_buffer *buf)
273 273
274static inline void receive_chars_pio(struct esp_struct *info, int num_bytes) 274static inline void receive_chars_pio(struct esp_struct *info, int num_bytes)
275{ 275{
276 struct tty_struct *tty = info->tty; 276 struct tty_struct *tty = info->port.tty;
277 int i; 277 int i;
278 struct esp_pio_buffer *pio_buf; 278 struct esp_pio_buffer *pio_buf;
279 struct esp_pio_buffer *err_buf; 279 struct esp_pio_buffer *err_buf;
@@ -295,7 +295,7 @@ static inline void receive_chars_pio(struct esp_struct *info, int num_bytes)
295 295
296 for (i = 0; i < num_bytes - 1; i += 2) { 296 for (i = 0; i < num_bytes - 1; i += 2) {
297 *((unsigned short *)(pio_buf->data + i)) = 297 *((unsigned short *)(pio_buf->data + i)) =
298 inw(info->port + UART_ESI_RX); 298 inw(info->io_port + UART_ESI_RX);
299 err_buf->data[i] = serial_in(info, UART_ESI_RWS); 299 err_buf->data[i] = serial_in(info, UART_ESI_RWS);
300 err_buf->data[i + 1] = (err_buf->data[i] >> 3) & status_mask; 300 err_buf->data[i + 1] = (err_buf->data[i] >> 3) & status_mask;
301 err_buf->data[i] &= status_mask; 301 err_buf->data[i] &= status_mask;
@@ -308,7 +308,7 @@ static inline void receive_chars_pio(struct esp_struct *info, int num_bytes)
308 } 308 }
309 309
310 /* make sure everything is still ok since interrupts were enabled */ 310 /* make sure everything is still ok since interrupts were enabled */
311 tty = info->tty; 311 tty = info->port.tty;
312 312
313 if (!tty) { 313 if (!tty) {
314 release_pio_buffer(pio_buf); 314 release_pio_buffer(pio_buf);
@@ -325,7 +325,7 @@ static inline void receive_chars_pio(struct esp_struct *info, int num_bytes)
325 325
326 if (err_buf->data[i] & 0x04) { 326 if (err_buf->data[i] & 0x04) {
327 flag = TTY_BREAK; 327 flag = TTY_BREAK;
328 if (info->flags & ASYNC_SAK) 328 if (info->port.flags & ASYNC_SAK)
329 do_SAK(tty); 329 do_SAK(tty);
330 } else if (err_buf->data[i] & 0x02) 330 } else if (err_buf->data[i] & 0x02)
331 flag = TTY_FRAME; 331 flag = TTY_FRAME;
@@ -370,7 +370,7 @@ static void receive_chars_dma(struct esp_struct *info, int num_bytes)
370static inline void receive_chars_dma_done(struct esp_struct *info, 370static inline void receive_chars_dma_done(struct esp_struct *info,
371 int status) 371 int status)
372{ 372{
373 struct tty_struct *tty = info->tty; 373 struct tty_struct *tty = info->port.tty;
374 int num_bytes; 374 int num_bytes;
375 unsigned long flags; 375 unsigned long flags;
376 376
@@ -396,7 +396,7 @@ static inline void receive_chars_dma_done(struct esp_struct *info,
396 if (status & 0x10) { 396 if (status & 0x10) {
397 statflag = TTY_BREAK; 397 statflag = TTY_BREAK;
398 (info->icount.brk)++; 398 (info->icount.brk)++;
399 if (info->flags & ASYNC_SAK) 399 if (info->port.flags & ASYNC_SAK)
400 do_SAK(tty); 400 do_SAK(tty);
401 } else if (status & 0x08) { 401 } else if (status & 0x08) {
402 statflag = TTY_FRAME; 402 statflag = TTY_FRAME;
@@ -451,7 +451,7 @@ static inline void transmit_chars_pio(struct esp_struct *info,
451 451
452 for (i = 0; i < space_avail - 1; i += 2) { 452 for (i = 0; i < space_avail - 1; i += 2) {
453 outw(*((unsigned short *)(pio_buf->data + i)), 453 outw(*((unsigned short *)(pio_buf->data + i)),
454 info->port + UART_ESI_TX); 454 info->io_port + UART_ESI_TX);
455 } 455 }
456 456
457 if (space_avail & 0x0001) 457 if (space_avail & 0x0001)
@@ -470,8 +470,8 @@ static inline void transmit_chars_pio(struct esp_struct *info,
470 } 470 }
471 471
472 if (info->xmit_cnt < WAKEUP_CHARS) { 472 if (info->xmit_cnt < WAKEUP_CHARS) {
473 if (info->tty) 473 if (info->port.tty)
474 tty_wakeup(info->tty); 474 tty_wakeup(info->port.tty);
475 475
476#ifdef SERIAL_DEBUG_INTR 476#ifdef SERIAL_DEBUG_INTR
477 printk("THRE..."); 477 printk("THRE...");
@@ -507,8 +507,8 @@ static inline void transmit_chars_dma(struct esp_struct *info, int num_bytes)
507 info->xmit_tail = (info->xmit_tail + dma_bytes) & (ESP_XMIT_SIZE - 1); 507 info->xmit_tail = (info->xmit_tail + dma_bytes) & (ESP_XMIT_SIZE - 1);
508 508
509 if (info->xmit_cnt < WAKEUP_CHARS) { 509 if (info->xmit_cnt < WAKEUP_CHARS) {
510 if (info->tty) 510 if (info->port.tty)
511 tty_wakeup(info->tty); 511 tty_wakeup(info->port.tty);
512 512
513#ifdef SERIAL_DEBUG_INTR 513#ifdef SERIAL_DEBUG_INTR
514 printk("THRE..."); 514 printk("THRE...");
@@ -575,18 +575,18 @@ static void check_modem_status(struct esp_struct *info)
575 wake_up_interruptible(&info->delta_msr_wait); 575 wake_up_interruptible(&info->delta_msr_wait);
576 } 576 }
577 577
578 if ((info->flags & ASYNC_CHECK_CD) && (status & UART_MSR_DDCD)) { 578 if ((info->port.flags & ASYNC_CHECK_CD) && (status & UART_MSR_DDCD)) {
579#if (defined(SERIAL_DEBUG_OPEN) || defined(SERIAL_DEBUG_INTR)) 579#if (defined(SERIAL_DEBUG_OPEN) || defined(SERIAL_DEBUG_INTR))
580 printk("ttys%d CD now %s...", info->line, 580 printk("ttys%d CD now %s...", info->line,
581 (status & UART_MSR_DCD) ? "on" : "off"); 581 (status & UART_MSR_DCD) ? "on" : "off");
582#endif 582#endif
583 if (status & UART_MSR_DCD) 583 if (status & UART_MSR_DCD)
584 wake_up_interruptible(&info->open_wait); 584 wake_up_interruptible(&info->port.open_wait);
585 else { 585 else {
586#ifdef SERIAL_DEBUG_OPEN 586#ifdef SERIAL_DEBUG_OPEN
587 printk("scheduling hangup..."); 587 printk("scheduling hangup...");
588#endif 588#endif
589 tty_hangup(info->tty); 589 tty_hangup(info->port.tty);
590 } 590 }
591 } 591 }
592} 592}
@@ -609,7 +609,7 @@ static irqreturn_t rs_interrupt_single(int irq, void *dev_id)
609 609
610 spin_lock(&info->lock); 610 spin_lock(&info->lock);
611 611
612 if (!info->tty) { 612 if (!info->port.tty) {
613 spin_unlock(&info->lock); 613 spin_unlock(&info->lock);
614 return IRQ_NONE; 614 return IRQ_NONE;
615 } 615 }
@@ -647,7 +647,7 @@ static irqreturn_t rs_interrupt_single(int irq, void *dev_id)
647 num_bytes = serial_in(info, UART_ESI_STAT1) << 8; 647 num_bytes = serial_in(info, UART_ESI_STAT1) << 8;
648 num_bytes |= serial_in(info, UART_ESI_STAT2); 648 num_bytes |= serial_in(info, UART_ESI_STAT2);
649 649
650 num_bytes = tty_buffer_request_room(info->tty, num_bytes); 650 num_bytes = tty_buffer_request_room(info->port.tty, num_bytes);
651 651
652 if (num_bytes) { 652 if (num_bytes) {
653 if (dma_bytes || 653 if (dma_bytes ||
@@ -661,7 +661,7 @@ static irqreturn_t rs_interrupt_single(int irq, void *dev_id)
661 661
662 if (!(info->stat_flags & (ESP_STAT_DMA_RX | ESP_STAT_DMA_TX)) && 662 if (!(info->stat_flags & (ESP_STAT_DMA_RX | ESP_STAT_DMA_TX)) &&
663 (scratch & 0x02) && (info->IER & UART_IER_THRI)) { 663 (scratch & 0x02) && (info->IER & UART_IER_THRI)) {
664 if ((info->xmit_cnt <= 0) || info->tty->stopped) { 664 if ((info->xmit_cnt <= 0) || info->port.tty->stopped) {
665 info->IER &= ~UART_IER_THRI; 665 info->IER &= ~UART_IER_THRI;
666 serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK); 666 serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK);
667 serial_out(info, UART_ESI_CMD2, info->IER); 667 serial_out(info, UART_ESI_CMD2, info->IER);
@@ -782,7 +782,7 @@ static int startup(struct esp_struct *info)
782 782
783 spin_lock_irqsave(&info->lock, flags); 783 spin_lock_irqsave(&info->lock, flags);
784 784
785 if (info->flags & ASYNC_INITIALIZED) 785 if (info->port.flags & ASYNC_INITIALIZED)
786 goto out; 786 goto out;
787 787
788 if (!info->xmit_buf) { 788 if (!info->xmit_buf) {
@@ -806,7 +806,7 @@ static int startup(struct esp_struct *info)
806 num_chars |= serial_in(info, UART_ESI_STAT2); 806 num_chars |= serial_in(info, UART_ESI_STAT2);
807 807
808 while (num_chars > 1) { 808 while (num_chars > 1) {
809 inw(info->port + UART_ESI_RX); 809 inw(info->io_port + UART_ESI_RX);
810 num_chars -= 2; 810 num_chars -= 2;
811 } 811 }
812 812
@@ -834,9 +834,9 @@ static int startup(struct esp_struct *info)
834 834
835 if (retval) { 835 if (retval) {
836 if (capable(CAP_SYS_ADMIN)) { 836 if (capable(CAP_SYS_ADMIN)) {
837 if (info->tty) 837 if (info->port.tty)
838 set_bit(TTY_IO_ERROR, 838 set_bit(TTY_IO_ERROR,
839 &info->tty->flags); 839 &info->port.tty->flags);
840 retval = 0; 840 retval = 0;
841 } 841 }
842 goto out_unlocked; 842 goto out_unlocked;
@@ -874,30 +874,30 @@ static int startup(struct esp_struct *info)
874 serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK); 874 serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK);
875 serial_out(info, UART_ESI_CMD2, info->IER); 875 serial_out(info, UART_ESI_CMD2, info->IER);
876 876
877 if (info->tty) 877 if (info->port.tty)
878 clear_bit(TTY_IO_ERROR, &info->tty->flags); 878 clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
879 info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; 879 info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
880 spin_unlock_irqrestore(&info->lock, flags); 880 spin_unlock_irqrestore(&info->lock, flags);
881 881
882 /* 882 /*
883 * Set up the tty->alt_speed kludge 883 * Set up the tty->alt_speed kludge
884 */ 884 */
885 if (info->tty) { 885 if (info->port.tty) {
886 if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) 886 if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
887 info->tty->alt_speed = 57600; 887 info->port.tty->alt_speed = 57600;
888 if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) 888 if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
889 info->tty->alt_speed = 115200; 889 info->port.tty->alt_speed = 115200;
890 if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) 890 if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
891 info->tty->alt_speed = 230400; 891 info->port.tty->alt_speed = 230400;
892 if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) 892 if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
893 info->tty->alt_speed = 460800; 893 info->port.tty->alt_speed = 460800;
894 } 894 }
895 895
896 /* 896 /*
897 * set the speed of the serial port 897 * set the speed of the serial port
898 */ 898 */
899 change_speed(info); 899 change_speed(info);
900 info->flags |= ASYNC_INITIALIZED; 900 info->port.flags |= ASYNC_INITIALIZED;
901 return 0; 901 return 0;
902 902
903out: 903out:
@@ -914,7 +914,7 @@ static void shutdown(struct esp_struct *info)
914{ 914{
915 unsigned long flags, f; 915 unsigned long flags, f;
916 916
917 if (!(info->flags & ASYNC_INITIALIZED)) 917 if (!(info->port.flags & ASYNC_INITIALIZED))
918 return; 918 return;
919 919
920#ifdef SERIAL_DEBUG_OPEN 920#ifdef SERIAL_DEBUG_OPEN
@@ -951,7 +951,7 @@ static void shutdown(struct esp_struct *info)
951 951
952 while (current_port) { 952 while (current_port) {
953 if ((current_port != info) && 953 if ((current_port != info) &&
954 (current_port->flags & ASYNC_INITIALIZED)) 954 (current_port->port.flags & ASYNC_INITIALIZED))
955 break; 955 break;
956 956
957 current_port = current_port->next_port; 957 current_port = current_port->next_port;
@@ -974,7 +974,7 @@ static void shutdown(struct esp_struct *info)
974 serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK); 974 serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK);
975 serial_out(info, UART_ESI_CMD2, 0x00); 975 serial_out(info, UART_ESI_CMD2, 0x00);
976 976
977 if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) 977 if (!info->port.tty || (info->port.tty->termios->c_cflag & HUPCL))
978 info->MCR &= ~(UART_MCR_DTR|UART_MCR_RTS); 978 info->MCR &= ~(UART_MCR_DTR|UART_MCR_RTS);
979 979
980 info->MCR &= ~UART_MCR_OUT2; 980 info->MCR &= ~UART_MCR_OUT2;
@@ -982,10 +982,10 @@ static void shutdown(struct esp_struct *info)
982 serial_out(info, UART_ESI_CMD2, UART_MCR); 982 serial_out(info, UART_ESI_CMD2, UART_MCR);
983 serial_out(info, UART_ESI_CMD2, info->MCR); 983 serial_out(info, UART_ESI_CMD2, info->MCR);
984 984
985 if (info->tty) 985 if (info->port.tty)
986 set_bit(TTY_IO_ERROR, &info->tty->flags); 986 set_bit(TTY_IO_ERROR, &info->port.tty->flags);
987 987
988 info->flags &= ~ASYNC_INITIALIZED; 988 info->port.flags &= ~ASYNC_INITIALIZED;
989 spin_unlock_irqrestore(&info->lock, flags); 989 spin_unlock_irqrestore(&info->lock, flags);
990} 990}
991 991
@@ -1002,10 +1002,10 @@ static void change_speed(struct esp_struct *info)
1002 unsigned char flow1 = 0, flow2 = 0; 1002 unsigned char flow1 = 0, flow2 = 0;
1003 unsigned long flags; 1003 unsigned long flags;
1004 1004
1005 if (!info->tty || !info->tty->termios) 1005 if (!info->port.tty || !info->port.tty->termios)
1006 return; 1006 return;
1007 cflag = info->tty->termios->c_cflag; 1007 cflag = info->port.tty->termios->c_cflag;
1008 port = info->port; 1008 port = info->io_port;
1009 1009
1010 /* byte size and parity */ 1010 /* byte size and parity */
1011 switch (cflag & CSIZE) { 1011 switch (cflag & CSIZE) {
@@ -1029,9 +1029,9 @@ static void change_speed(struct esp_struct *info)
1029 if (cflag & CMSPAR) 1029 if (cflag & CMSPAR)
1030 cval |= UART_LCR_SPAR; 1030 cval |= UART_LCR_SPAR;
1031#endif 1031#endif
1032 baud = tty_get_baud_rate(info->tty); 1032 baud = tty_get_baud_rate(info->port.tty);
1033 if (baud == 38400 && 1033 if (baud == 38400 &&
1034 ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)) 1034 ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST))
1035 quot = info->custom_divisor; 1035 quot = info->custom_divisor;
1036 else { 1036 else {
1037 if (baud == 134) /* Special case since 134 is really 134.5 */ 1037 if (baud == 134) /* Special case since 134 is really 134.5 */
@@ -1046,49 +1046,49 @@ static void change_speed(struct esp_struct *info)
1046 if (baud) { 1046 if (baud) {
1047 /* Actual rate */ 1047 /* Actual rate */
1048 baud = BASE_BAUD/quot; 1048 baud = BASE_BAUD/quot;
1049 tty_encode_baud_rate(info->tty, baud, baud); 1049 tty_encode_baud_rate(info->port.tty, baud, baud);
1050 } 1050 }
1051 info->timeout = ((1024 * HZ * bits * quot) / BASE_BAUD) + (HZ / 50); 1051 info->timeout = ((1024 * HZ * bits * quot) / BASE_BAUD) + (HZ / 50);
1052 1052
1053 /* CTS flow control flag and modem status interrupts */ 1053 /* CTS flow control flag and modem status interrupts */
1054 /* info->IER &= ~UART_IER_MSI; */ 1054 /* info->IER &= ~UART_IER_MSI; */
1055 if (cflag & CRTSCTS) { 1055 if (cflag & CRTSCTS) {
1056 info->flags |= ASYNC_CTS_FLOW; 1056 info->port.flags |= ASYNC_CTS_FLOW;
1057 /* info->IER |= UART_IER_MSI; */ 1057 /* info->IER |= UART_IER_MSI; */
1058 flow1 = 0x04; 1058 flow1 = 0x04;
1059 flow2 = 0x10; 1059 flow2 = 0x10;
1060 } else 1060 } else
1061 info->flags &= ~ASYNC_CTS_FLOW; 1061 info->port.flags &= ~ASYNC_CTS_FLOW;
1062 if (cflag & CLOCAL) 1062 if (cflag & CLOCAL)
1063 info->flags &= ~ASYNC_CHECK_CD; 1063 info->port.flags &= ~ASYNC_CHECK_CD;
1064 else 1064 else
1065 info->flags |= ASYNC_CHECK_CD; 1065 info->port.flags |= ASYNC_CHECK_CD;
1066 1066
1067 /* 1067 /*
1068 * Set up parity check flag 1068 * Set up parity check flag
1069 */ 1069 */
1070 info->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR; 1070 info->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR;
1071 if (I_INPCK(info->tty)) 1071 if (I_INPCK(info->port.tty))
1072 info->read_status_mask |= UART_LSR_FE | UART_LSR_PE; 1072 info->read_status_mask |= UART_LSR_FE | UART_LSR_PE;
1073 if (I_BRKINT(info->tty) || I_PARMRK(info->tty)) 1073 if (I_BRKINT(info->port.tty) || I_PARMRK(info->port.tty))
1074 info->read_status_mask |= UART_LSR_BI; 1074 info->read_status_mask |= UART_LSR_BI;
1075 1075
1076 info->ignore_status_mask = 0; 1076 info->ignore_status_mask = 0;
1077#if 0 1077#if 0
1078 /* This should be safe, but for some broken bits of hardware... */ 1078 /* This should be safe, but for some broken bits of hardware... */
1079 if (I_IGNPAR(info->tty)) { 1079 if (I_IGNPAR(info->port.tty)) {
1080 info->ignore_status_mask |= UART_LSR_PE | UART_LSR_FE; 1080 info->ignore_status_mask |= UART_LSR_PE | UART_LSR_FE;
1081 info->read_status_mask |= UART_LSR_PE | UART_LSR_FE; 1081 info->read_status_mask |= UART_LSR_PE | UART_LSR_FE;
1082 } 1082 }
1083#endif 1083#endif
1084 if (I_IGNBRK(info->tty)) { 1084 if (I_IGNBRK(info->port.tty)) {
1085 info->ignore_status_mask |= UART_LSR_BI; 1085 info->ignore_status_mask |= UART_LSR_BI;
1086 info->read_status_mask |= UART_LSR_BI; 1086 info->read_status_mask |= UART_LSR_BI;
1087 /* 1087 /*
1088 * If we're ignore parity and break indicators, ignore 1088 * If we're ignore parity and break indicators, ignore
1089 * overruns too. (For real raw support). 1089 * overruns too. (For real raw support).
1090 */ 1090 */
1091 if (I_IGNPAR(info->tty)) { 1091 if (I_IGNPAR(info->port.tty)) {
1092 info->ignore_status_mask |= UART_LSR_OE | \ 1092 info->ignore_status_mask |= UART_LSR_OE | \
1093 UART_LSR_PE | UART_LSR_FE; 1093 UART_LSR_PE | UART_LSR_FE;
1094 info->read_status_mask |= UART_LSR_OE | \ 1094 info->read_status_mask |= UART_LSR_OE | \
@@ -1096,7 +1096,7 @@ static void change_speed(struct esp_struct *info)
1096 } 1096 }
1097 } 1097 }
1098 1098
1099 if (I_IXOFF(info->tty)) 1099 if (I_IXOFF(info->port.tty))
1100 flow1 |= 0x81; 1100 flow1 |= 0x81;
1101 1101
1102 spin_lock_irqsave(&info->lock, flags); 1102 spin_lock_irqsave(&info->lock, flags);
@@ -1116,10 +1116,10 @@ static void change_speed(struct esp_struct *info)
1116 serial_out(info, UART_ESI_CMD2, flow2); 1116 serial_out(info, UART_ESI_CMD2, flow2);
1117 1117
1118 /* set flow control characters (XON/XOFF only) */ 1118 /* set flow control characters (XON/XOFF only) */
1119 if (I_IXOFF(info->tty)) { 1119 if (I_IXOFF(info->port.tty)) {
1120 serial_out(info, UART_ESI_CMD1, ESI_SET_FLOW_CHARS); 1120 serial_out(info, UART_ESI_CMD1, ESI_SET_FLOW_CHARS);
1121 serial_out(info, UART_ESI_CMD2, START_CHAR(info->tty)); 1121 serial_out(info, UART_ESI_CMD2, START_CHAR(info->port.tty));
1122 serial_out(info, UART_ESI_CMD2, STOP_CHAR(info->tty)); 1122 serial_out(info, UART_ESI_CMD2, STOP_CHAR(info->port.tty));
1123 serial_out(info, UART_ESI_CMD2, 0x10); 1123 serial_out(info, UART_ESI_CMD2, 0x10);
1124 serial_out(info, UART_ESI_CMD2, 0x21); 1124 serial_out(info, UART_ESI_CMD2, 0x21);
1125 switch (cflag & CSIZE) { 1125 switch (cflag & CSIZE) {
@@ -1355,9 +1355,9 @@ static int get_serial_info(struct esp_struct *info,
1355 memset(&tmp, 0, sizeof(tmp)); 1355 memset(&tmp, 0, sizeof(tmp));
1356 tmp.type = PORT_16550A; 1356 tmp.type = PORT_16550A;
1357 tmp.line = info->line; 1357 tmp.line = info->line;
1358 tmp.port = info->port; 1358 tmp.port = info->io_port;
1359 tmp.irq = info->irq; 1359 tmp.irq = info->irq;
1360 tmp.flags = info->flags; 1360 tmp.flags = info->port.flags;
1361 tmp.xmit_fifo_size = 1024; 1361 tmp.xmit_fifo_size = 1024;
1362 tmp.baud_base = BASE_BAUD; 1362 tmp.baud_base = BASE_BAUD;
1363 tmp.close_delay = info->close_delay; 1363 tmp.close_delay = info->close_delay;
@@ -1407,7 +1407,7 @@ static int set_serial_info(struct esp_struct *info,
1407 1407
1408 if ((new_serial.type != PORT_16550A) || 1408 if ((new_serial.type != PORT_16550A) ||
1409 (new_serial.hub6) || 1409 (new_serial.hub6) ||
1410 (info->port != new_serial.port) || 1410 (info->io_port != new_serial.port) ||
1411 (new_serial.baud_base != BASE_BAUD) || 1411 (new_serial.baud_base != BASE_BAUD) ||
1412 (new_serial.irq > 15) || 1412 (new_serial.irq > 15) ||
1413 (new_serial.irq < 2) || 1413 (new_serial.irq < 2) ||
@@ -1425,9 +1425,9 @@ static int set_serial_info(struct esp_struct *info,
1425 if (change_irq || 1425 if (change_irq ||
1426 (new_serial.close_delay != info->close_delay) || 1426 (new_serial.close_delay != info->close_delay) ||
1427 ((new_serial.flags & ~ASYNC_USR_MASK) != 1427 ((new_serial.flags & ~ASYNC_USR_MASK) !=
1428 (info->flags & ~ASYNC_USR_MASK))) 1428 (info->port.flags & ~ASYNC_USR_MASK)))
1429 return -EPERM; 1429 return -EPERM;
1430 info->flags = ((info->flags & ~ASYNC_USR_MASK) | 1430 info->port.flags = ((info->port.flags & ~ASYNC_USR_MASK) |
1431 (new_serial.flags & ASYNC_USR_MASK)); 1431 (new_serial.flags & ASYNC_USR_MASK));
1432 info->custom_divisor = new_serial.custom_divisor; 1432 info->custom_divisor = new_serial.custom_divisor;
1433 } else { 1433 } else {
@@ -1441,9 +1441,9 @@ static int set_serial_info(struct esp_struct *info,
1441 if ((current_async->line >= info->line) && 1441 if ((current_async->line >= info->line) &&
1442 (current_async->line < (info->line + 8))) { 1442 (current_async->line < (info->line + 8))) {
1443 if (current_async == info) { 1443 if (current_async == info) {
1444 if (current_async->count > 1) 1444 if (current_async->port.count > 1)
1445 return -EBUSY; 1445 return -EBUSY;
1446 } else if (current_async->count) 1446 } else if (current_async->port.count)
1447 return -EBUSY; 1447 return -EBUSY;
1448 } 1448 }
1449 1449
@@ -1456,7 +1456,7 @@ static int set_serial_info(struct esp_struct *info,
1456 * At this point, we start making changes..... 1456 * At this point, we start making changes.....
1457 */ 1457 */
1458 1458
1459 info->flags = ((info->flags & ~ASYNC_FLAGS) | 1459 info->port.flags = ((info->port.flags & ~ASYNC_FLAGS) |
1460 (new_serial.flags & ASYNC_FLAGS)); 1460 (new_serial.flags & ASYNC_FLAGS));
1461 info->custom_divisor = new_serial.custom_divisor; 1461 info->custom_divisor = new_serial.custom_divisor;
1462 info->close_delay = new_serial.close_delay * HZ/100; 1462 info->close_delay = new_serial.close_delay * HZ/100;
@@ -1487,18 +1487,18 @@ static int set_serial_info(struct esp_struct *info,
1487 } 1487 }
1488 } 1488 }
1489 1489
1490 if (info->flags & ASYNC_INITIALIZED) { 1490 if (info->port.flags & ASYNC_INITIALIZED) {
1491 if (((old_info.flags & ASYNC_SPD_MASK) != 1491 if (((old_info.port.flags & ASYNC_SPD_MASK) !=
1492 (info->flags & ASYNC_SPD_MASK)) || 1492 (info->port.flags & ASYNC_SPD_MASK)) ||
1493 (old_info.custom_divisor != info->custom_divisor)) { 1493 (old_info.custom_divisor != info->custom_divisor)) {
1494 if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) 1494 if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
1495 info->tty->alt_speed = 57600; 1495 info->port.tty->alt_speed = 57600;
1496 if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) 1496 if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
1497 info->tty->alt_speed = 115200; 1497 info->port.tty->alt_speed = 115200;
1498 if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) 1498 if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
1499 info->tty->alt_speed = 230400; 1499 info->port.tty->alt_speed = 230400;
1500 if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) 1500 if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
1501 info->tty->alt_speed = 460800; 1501 info->port.tty->alt_speed = 460800;
1502 change_speed(info); 1502 change_speed(info);
1503 } 1503 }
1504 } else 1504 } else
@@ -1554,9 +1554,9 @@ static int set_esp_config(struct esp_struct *info,
1554 1554
1555 while (current_async) { 1555 while (current_async) {
1556 if (current_async == info) { 1556 if (current_async == info) {
1557 if (current_async->count > 1) 1557 if (current_async->port.count > 1)
1558 return -EBUSY; 1558 return -EBUSY;
1559 } else if (current_async->count) 1559 } else if (current_async->port.count)
1560 return -EBUSY; 1560 return -EBUSY;
1561 1561
1562 current_async = current_async->next_port; 1562 current_async = current_async->next_port;
@@ -1578,7 +1578,7 @@ static int set_esp_config(struct esp_struct *info,
1578 spin_unlock_irqrestore(&info->lock, flags); 1578 spin_unlock_irqrestore(&info->lock, flags);
1579 } else { 1579 } else {
1580 /* DMA mode to PIO mode only */ 1580 /* DMA mode to PIO mode only */
1581 if (info->count > 1) 1581 if (info->port.count > 1)
1582 return -EBUSY; 1582 return -EBUSY;
1583 1583
1584 shutdown(info); 1584 shutdown(info);
@@ -1634,7 +1634,7 @@ static int set_esp_config(struct esp_struct *info,
1634 spin_unlock_irqrestore(&info->lock, flags); 1634 spin_unlock_irqrestore(&info->lock, flags);
1635 } 1635 }
1636 1636
1637 if (!(info->flags & ASYNC_INITIALIZED)) 1637 if (!(info->port.flags & ASYNC_INITIALIZED))
1638 retval = startup(info); 1638 retval = startup(info);
1639 1639
1640 return retval; 1640 return retval;
@@ -1917,9 +1917,9 @@ static void rs_close(struct tty_struct *tty, struct file *filp)
1917 1917
1918#ifdef SERIAL_DEBUG_OPEN 1918#ifdef SERIAL_DEBUG_OPEN
1919 printk(KERN_DEBUG "rs_close ttys%d, count = %d\n", 1919 printk(KERN_DEBUG "rs_close ttys%d, count = %d\n",
1920 info->line, info->count); 1920 info->line, info->port.count);
1921#endif 1921#endif
1922 if (tty->count == 1 && info->count != 1) { 1922 if (tty->count == 1 && info->port.count != 1) {
1923 /* 1923 /*
1924 * Uh, oh. tty->count is 1, which means that the tty 1924 * Uh, oh. tty->count is 1, which means that the tty
1925 * structure will be freed. Info->count should always 1925 * structure will be freed. Info->count should always
@@ -1927,19 +1927,19 @@ static void rs_close(struct tty_struct *tty, struct file *filp)
1927 * one, we've got real problems, since it means the 1927 * one, we've got real problems, since it means the
1928 * serial port won't be shutdown. 1928 * serial port won't be shutdown.
1929 */ 1929 */
1930 printk(KERN_DEBUG "rs_close: bad serial port count; tty->count is 1, info->count is %d\n", info->count); 1930 printk(KERN_DEBUG "rs_close: bad serial port count; tty->count is 1, info->port.count is %d\n", info->port.count);
1931 info->count = 1; 1931 info->port.count = 1;
1932 } 1932 }
1933 if (--info->count < 0) { 1933 if (--info->port.count < 0) {
1934 printk(KERN_ERR "rs_close: bad serial port count for ttys%d: %d\n", 1934 printk(KERN_ERR "rs_close: bad serial port count for ttys%d: %d\n",
1935 info->line, info->count); 1935 info->line, info->port.count);
1936 info->count = 0; 1936 info->port.count = 0;
1937 } 1937 }
1938 if (info->count) { 1938 if (info->port.count) {
1939 DBG_CNT("before DEC-2"); 1939 DBG_CNT("before DEC-2");
1940 goto out; 1940 goto out;
1941 } 1941 }
1942 info->flags |= ASYNC_CLOSING; 1942 info->port.flags |= ASYNC_CLOSING;
1943 1943
1944 spin_unlock_irqrestore(&info->lock, flags); 1944 spin_unlock_irqrestore(&info->lock, flags);
1945 /* 1945 /*
@@ -1958,7 +1958,7 @@ static void rs_close(struct tty_struct *tty, struct file *filp)
1958 /* info->IER &= ~UART_IER_RLSI; */ 1958 /* info->IER &= ~UART_IER_RLSI; */
1959 info->IER &= ~UART_IER_RDI; 1959 info->IER &= ~UART_IER_RDI;
1960 info->read_status_mask &= ~UART_LSR_DR; 1960 info->read_status_mask &= ~UART_LSR_DR;
1961 if (info->flags & ASYNC_INITIALIZED) { 1961 if (info->port.flags & ASYNC_INITIALIZED) {
1962 1962
1963 spin_lock_irqsave(&info->lock, flags); 1963 spin_lock_irqsave(&info->lock, flags);
1964 serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK); 1964 serial_out(info, UART_ESI_CMD1, ESI_SET_SRV_MASK);
@@ -1981,15 +1981,15 @@ static void rs_close(struct tty_struct *tty, struct file *filp)
1981 rs_flush_buffer(tty); 1981 rs_flush_buffer(tty);
1982 tty_ldisc_flush(tty); 1982 tty_ldisc_flush(tty);
1983 tty->closing = 0; 1983 tty->closing = 0;
1984 info->tty = NULL; 1984 info->port.tty = NULL;
1985 1985
1986 if (info->blocked_open) { 1986 if (info->port.blocked_open) {
1987 if (info->close_delay) 1987 if (info->close_delay)
1988 msleep_interruptible(jiffies_to_msecs(info->close_delay)); 1988 msleep_interruptible(jiffies_to_msecs(info->close_delay));
1989 wake_up_interruptible(&info->open_wait); 1989 wake_up_interruptible(&info->port.open_wait);
1990 } 1990 }
1991 info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); 1991 info->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
1992 wake_up_interruptible(&info->close_wait); 1992 wake_up_interruptible(&info->port.close_wait);
1993 return; 1993 return;
1994 1994
1995out: 1995out:
@@ -2047,10 +2047,10 @@ static void esp_hangup(struct tty_struct *tty)
2047 2047
2048 rs_flush_buffer(tty); 2048 rs_flush_buffer(tty);
2049 shutdown(info); 2049 shutdown(info);
2050 info->count = 0; 2050 info->port.count = 0;
2051 info->flags &= ~ASYNC_NORMAL_ACTIVE; 2051 info->port.flags &= ~ASYNC_NORMAL_ACTIVE;
2052 info->tty = NULL; 2052 info->port.tty = NULL;
2053 wake_up_interruptible(&info->open_wait); 2053 wake_up_interruptible(&info->port.open_wait);
2054} 2054}
2055 2055
2056/* 2056/*
@@ -2071,11 +2071,11 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
2071 * until it's done, and then try again. 2071 * until it's done, and then try again.
2072 */ 2072 */
2073 if (tty_hung_up_p(filp) || 2073 if (tty_hung_up_p(filp) ||
2074 (info->flags & ASYNC_CLOSING)) { 2074 (info->port.flags & ASYNC_CLOSING)) {
2075 if (info->flags & ASYNC_CLOSING) 2075 if (info->port.flags & ASYNC_CLOSING)
2076 interruptible_sleep_on(&info->close_wait); 2076 interruptible_sleep_on(&info->port.close_wait);
2077#ifdef SERIAL_DO_RESTART 2077#ifdef SERIAL_DO_RESTART
2078 if (info->flags & ASYNC_HUP_NOTIFY) 2078 if (info->port.flags & ASYNC_HUP_NOTIFY)
2079 return -EAGAIN; 2079 return -EAGAIN;
2080 else 2080 else
2081 return -ERESTARTSYS; 2081 return -ERESTARTSYS;
@@ -2090,7 +2090,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
2090 */ 2090 */
2091 if ((filp->f_flags & O_NONBLOCK) || 2091 if ((filp->f_flags & O_NONBLOCK) ||
2092 (tty->flags & (1 << TTY_IO_ERROR))) { 2092 (tty->flags & (1 << TTY_IO_ERROR))) {
2093 info->flags |= ASYNC_NORMAL_ACTIVE; 2093 info->port.flags |= ASYNC_NORMAL_ACTIVE;
2094 return 0; 2094 return 0;
2095 } 2095 }
2096 2096
@@ -2100,20 +2100,20 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
2100 /* 2100 /*
2101 * Block waiting for the carrier detect and the line to become 2101 * Block waiting for the carrier detect and the line to become
2102 * free (i.e., not in use by the callout). While we are in 2102 * free (i.e., not in use by the callout). While we are in
2103 * this loop, info->count is dropped by one, so that 2103 * this loop, info->port.count is dropped by one, so that
2104 * rs_close() knows when to free things. We restore it upon 2104 * rs_close() knows when to free things. We restore it upon
2105 * exit, either normal or abnormal. 2105 * exit, either normal or abnormal.
2106 */ 2106 */
2107 retval = 0; 2107 retval = 0;
2108 add_wait_queue(&info->open_wait, &wait); 2108 add_wait_queue(&info->port.open_wait, &wait);
2109#ifdef SERIAL_DEBUG_OPEN 2109#ifdef SERIAL_DEBUG_OPEN
2110 printk(KERN_DEBUG "block_til_ready before block: ttys%d, count = %d\n", 2110 printk(KERN_DEBUG "block_til_ready before block: ttys%d, count = %d\n",
2111 info->line, info->count); 2111 info->line, info->port.count);
2112#endif 2112#endif
2113 spin_lock_irqsave(&info->lock, flags); 2113 spin_lock_irqsave(&info->lock, flags);
2114 if (!tty_hung_up_p(filp)) 2114 if (!tty_hung_up_p(filp))
2115 info->count--; 2115 info->port.count--;
2116 info->blocked_open++; 2116 info->port.blocked_open++;
2117 while (1) { 2117 while (1) {
2118 if ((tty->termios->c_cflag & CBAUD)) { 2118 if ((tty->termios->c_cflag & CBAUD)) {
2119 unsigned int scratch; 2119 unsigned int scratch;
@@ -2128,9 +2128,9 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
2128 } 2128 }
2129 set_current_state(TASK_INTERRUPTIBLE); 2129 set_current_state(TASK_INTERRUPTIBLE);
2130 if (tty_hung_up_p(filp) || 2130 if (tty_hung_up_p(filp) ||
2131 !(info->flags & ASYNC_INITIALIZED)) { 2131 !(info->port.flags & ASYNC_INITIALIZED)) {
2132#ifdef SERIAL_DO_RESTART 2132#ifdef SERIAL_DO_RESTART
2133 if (info->flags & ASYNC_HUP_NOTIFY) 2133 if (info->port.flags & ASYNC_HUP_NOTIFY)
2134 retval = -EAGAIN; 2134 retval = -EAGAIN;
2135 else 2135 else
2136 retval = -ERESTARTSYS; 2136 retval = -ERESTARTSYS;
@@ -2144,7 +2144,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
2144 if (serial_in(info, UART_ESI_STAT2) & UART_MSR_DCD) 2144 if (serial_in(info, UART_ESI_STAT2) & UART_MSR_DCD)
2145 do_clocal = 1; 2145 do_clocal = 1;
2146 2146
2147 if (!(info->flags & ASYNC_CLOSING) && 2147 if (!(info->port.flags & ASYNC_CLOSING) &&
2148 (do_clocal)) 2148 (do_clocal))
2149 break; 2149 break;
2150 if (signal_pending(current)) { 2150 if (signal_pending(current)) {
@@ -2153,25 +2153,25 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
2153 } 2153 }
2154#ifdef SERIAL_DEBUG_OPEN 2154#ifdef SERIAL_DEBUG_OPEN
2155 printk(KERN_DEBUG "block_til_ready blocking: ttys%d, count = %d\n", 2155 printk(KERN_DEBUG "block_til_ready blocking: ttys%d, count = %d\n",
2156 info->line, info->count); 2156 info->line, info->port.count);
2157#endif 2157#endif
2158 spin_unlock_irqrestore(&info->lock, flags); 2158 spin_unlock_irqrestore(&info->lock, flags);
2159 schedule(); 2159 schedule();
2160 spin_lock_irqsave(&info->lock, flags); 2160 spin_lock_irqsave(&info->lock, flags);
2161 } 2161 }
2162 set_current_state(TASK_RUNNING); 2162 set_current_state(TASK_RUNNING);
2163 remove_wait_queue(&info->open_wait, &wait); 2163 remove_wait_queue(&info->port.open_wait, &wait);
2164 if (!tty_hung_up_p(filp)) 2164 if (!tty_hung_up_p(filp))
2165 info->count++; 2165 info->port.count++;
2166 info->blocked_open--; 2166 info->port.blocked_open--;
2167 spin_unlock_irqrestore(&info->lock, flags); 2167 spin_unlock_irqrestore(&info->lock, flags);
2168#ifdef SERIAL_DEBUG_OPEN 2168#ifdef SERIAL_DEBUG_OPEN
2169 printk(KERN_DEBUG "block_til_ready after blocking: ttys%d, count = %d\n", 2169 printk(KERN_DEBUG "block_til_ready after blocking: ttys%d, count = %d\n",
2170 info->line, info->count); 2170 info->line, info->port.count);
2171#endif 2171#endif
2172 if (retval) 2172 if (retval)
2173 return retval; 2173 return retval;
2174 info->flags |= ASYNC_NORMAL_ACTIVE; 2174 info->port.flags |= ASYNC_NORMAL_ACTIVE;
2175 return 0; 2175 return 0;
2176} 2176}
2177 2177
@@ -2204,12 +2204,12 @@ static int esp_open(struct tty_struct *tty, struct file *filp)
2204 } 2204 }
2205 2205
2206#ifdef SERIAL_DEBUG_OPEN 2206#ifdef SERIAL_DEBUG_OPEN
2207 printk(KERN_DEBUG "esp_open %s, count = %d\n", tty->name, info->count); 2207 printk(KERN_DEBUG "esp_open %s, count = %d\n", tty->name, info->port.count);
2208#endif 2208#endif
2209 spin_lock_irqsave(&info->lock, flags); 2209 spin_lock_irqsave(&info->lock, flags);
2210 info->count++; 2210 info->port.count++;
2211 tty->driver_data = info; 2211 tty->driver_data = info;
2212 info->tty = tty; 2212 info->port.tty = tty;
2213 2213
2214 spin_unlock_irqrestore(&info->lock, flags); 2214 spin_unlock_irqrestore(&info->lock, flags);
2215 2215
@@ -2263,7 +2263,7 @@ static int autoconfig(struct esp_struct *info)
2263 int port_detected = 0; 2263 int port_detected = 0;
2264 unsigned long flags; 2264 unsigned long flags;
2265 2265
2266 if (!request_region(info->port, REGION_SIZE, "esp serial")) 2266 if (!request_region(info->io_port, REGION_SIZE, "esp serial"))
2267 return -EIO; 2267 return -EIO;
2268 2268
2269 spin_lock_irqsave(&info->lock, flags); 2269 spin_lock_irqsave(&info->lock, flags);
@@ -2300,7 +2300,7 @@ static int autoconfig(struct esp_struct *info)
2300 } 2300 }
2301 } 2301 }
2302 if (!port_detected) 2302 if (!port_detected)
2303 release_region(info->port, REGION_SIZE); 2303 release_region(info->io_port, REGION_SIZE);
2304 2304
2305 spin_unlock_irqrestore(&info->lock, flags); 2305 spin_unlock_irqrestore(&info->lock, flags);
2306 return (port_detected); 2306 return (port_detected);
@@ -2414,7 +2414,7 @@ static int __init espserial_init(void)
2414 offset = 0; 2414 offset = 0;
2415 2415
2416 do { 2416 do {
2417 info->port = esp[i] + offset; 2417 info->io_port = esp[i] + offset;
2418 info->irq = irq[i]; 2418 info->irq = irq[i];
2419 info->line = (i * 8) + (offset / 8); 2419 info->line = (i * 8) + (offset / 8);
2420 2420
@@ -2425,9 +2425,9 @@ static int __init espserial_init(void)
2425 } 2425 }
2426 2426
2427 info->custom_divisor = (divisor[i] >> (offset / 2)) & 0xf; 2427 info->custom_divisor = (divisor[i] >> (offset / 2)) & 0xf;
2428 info->flags = STD_COM_FLAGS; 2428 info->port.flags = STD_COM_FLAGS;
2429 if (info->custom_divisor) 2429 if (info->custom_divisor)
2430 info->flags |= ASYNC_SPD_CUST; 2430 info->port.flags |= ASYNC_SPD_CUST;
2431 info->magic = ESP_MAGIC; 2431 info->magic = ESP_MAGIC;
2432 info->close_delay = 5*HZ/10; 2432 info->close_delay = 5*HZ/10;
2433 info->closing_wait = 30*HZ; 2433 info->closing_wait = 30*HZ;
@@ -2436,13 +2436,13 @@ static int __init espserial_init(void)
2436 info->config.flow_off = flow_off; 2436 info->config.flow_off = flow_off;
2437 info->config.pio_threshold = pio_threshold; 2437 info->config.pio_threshold = pio_threshold;
2438 info->next_port = ports; 2438 info->next_port = ports;
2439 init_waitqueue_head(&info->open_wait); 2439 init_waitqueue_head(&info->port.open_wait);
2440 init_waitqueue_head(&info->close_wait); 2440 init_waitqueue_head(&info->port.close_wait);
2441 init_waitqueue_head(&info->delta_msr_wait); 2441 init_waitqueue_head(&info->delta_msr_wait);
2442 init_waitqueue_head(&info->break_wait); 2442 init_waitqueue_head(&info->break_wait);
2443 ports = info; 2443 ports = info;
2444 printk(KERN_INFO "ttyP%d at 0x%04x (irq = %d) is an ESP ", 2444 printk(KERN_INFO "ttyP%d at 0x%04x (irq = %d) is an ESP ",
2445 info->line, info->port, info->irq); 2445 info->line, info->io_port, info->irq);
2446 2446
2447 if (info->line % 8) { 2447 if (info->line % 8) {
2448 printk("secondary port\n"); 2448 printk("secondary port\n");
@@ -2498,8 +2498,8 @@ static void __exit espserial_exit(void)
2498 put_tty_driver(esp_driver); 2498 put_tty_driver(esp_driver);
2499 2499
2500 while (ports) { 2500 while (ports) {
2501 if (ports->port) 2501 if (ports->io_port)
2502 release_region(ports->port, REGION_SIZE); 2502 release_region(ports->io_port, REGION_SIZE);
2503 temp_async = ports->next_port; 2503 temp_async = ports->next_port;
2504 kfree(ports); 2504 kfree(ports);
2505 ports = temp_async; 2505 ports = temp_async;
diff --git a/drivers/char/generic_nvram.c b/drivers/char/generic_nvram.c
index 2398e864c28d..a00869c650d5 100644
--- a/drivers/char/generic_nvram.c
+++ b/drivers/char/generic_nvram.c
@@ -133,7 +133,7 @@ static struct miscdevice nvram_dev = {
133 133
134int __init nvram_init(void) 134int __init nvram_init(void)
135{ 135{
136 printk(KERN_INFO "Macintosh non-volatile memory driver v%s\n", 136 printk(KERN_INFO "Generic non-volatile memory driver v%s\n",
137 NVRAM_VERSION); 137 NVRAM_VERSION);
138 return misc_register(&nvram_dev); 138 return misc_register(&nvram_dev);
139} 139}
diff --git a/drivers/char/generic_serial.c b/drivers/char/generic_serial.c
index 252f73e48596..19d3afb0e50c 100644
--- a/drivers/char/generic_serial.c
+++ b/drivers/char/generic_serial.c
@@ -60,7 +60,7 @@ int gs_put_char(struct tty_struct * tty, unsigned char ch)
60 60
61 if (!port) return 0; 61 if (!port) return 0;
62 62
63 if (! (port->flags & ASYNC_INITIALIZED)) return 0; 63 if (! (port->port.flags & ASYNC_INITIALIZED)) return 0;
64 64
65 /* Take a lock on the serial tranmit buffer! */ 65 /* Take a lock on the serial tranmit buffer! */
66 mutex_lock(& port->port_write_mutex); 66 mutex_lock(& port->port_write_mutex);
@@ -103,7 +103,7 @@ int gs_write(struct tty_struct * tty,
103 103
104 if (!port) return 0; 104 if (!port) return 0;
105 105
106 if (! (port->flags & ASYNC_INITIALIZED)) 106 if (! (port->port.flags & ASYNC_INITIALIZED))
107 return 0; 107 return 0;
108 108
109 /* get exclusive "write" access to this port (problem 3) */ 109 /* get exclusive "write" access to this port (problem 3) */
@@ -141,13 +141,13 @@ int gs_write(struct tty_struct * tty,
141 mutex_unlock(& port->port_write_mutex); 141 mutex_unlock(& port->port_write_mutex);
142 142
143 gs_dprintk (GS_DEBUG_WRITE, "write: interrupts are %s\n", 143 gs_dprintk (GS_DEBUG_WRITE, "write: interrupts are %s\n",
144 (port->flags & GS_TX_INTEN)?"enabled": "disabled"); 144 (port->port.flags & GS_TX_INTEN)?"enabled": "disabled");
145 145
146 if (port->xmit_cnt && 146 if (port->xmit_cnt &&
147 !tty->stopped && 147 !tty->stopped &&
148 !tty->hw_stopped && 148 !tty->hw_stopped &&
149 !(port->flags & GS_TX_INTEN)) { 149 !(port->port.flags & GS_TX_INTEN)) {
150 port->flags |= GS_TX_INTEN; 150 port->port.flags |= GS_TX_INTEN;
151 port->rd->enable_tx_interrupts (port); 151 port->rd->enable_tx_interrupts (port);
152 } 152 }
153 func_exit (); 153 func_exit ();
@@ -208,7 +208,7 @@ static int gs_wait_tx_flushed (void * ptr, unsigned long timeout)
208 gs_dprintk (GS_DEBUG_FLUSH, "port=%p.\n", port); 208 gs_dprintk (GS_DEBUG_FLUSH, "port=%p.\n", port);
209 if (port) { 209 if (port) {
210 gs_dprintk (GS_DEBUG_FLUSH, "xmit_cnt=%x, xmit_buf=%p, tty=%p.\n", 210 gs_dprintk (GS_DEBUG_FLUSH, "xmit_cnt=%x, xmit_buf=%p, tty=%p.\n",
211 port->xmit_cnt, port->xmit_buf, port->tty); 211 port->xmit_cnt, port->xmit_buf, port->port.tty);
212 } 212 }
213 213
214 if (!port || port->xmit_cnt < 0 || !port->xmit_buf) { 214 if (!port || port->xmit_cnt < 0 || !port->xmit_buf) {
@@ -217,7 +217,7 @@ static int gs_wait_tx_flushed (void * ptr, unsigned long timeout)
217 return -EINVAL; /* This is an error which we don't know how to handle. */ 217 return -EINVAL; /* This is an error which we don't know how to handle. */
218 } 218 }
219 219
220 rcib = gs_real_chars_in_buffer(port->tty); 220 rcib = gs_real_chars_in_buffer(port->port.tty);
221 221
222 if(rcib <= 0) { 222 if(rcib <= 0) {
223 gs_dprintk (GS_DEBUG_FLUSH, "nothing to wait for.\n"); 223 gs_dprintk (GS_DEBUG_FLUSH, "nothing to wait for.\n");
@@ -236,7 +236,7 @@ static int gs_wait_tx_flushed (void * ptr, unsigned long timeout)
236 236
237 /* the expression is actually jiffies < end_jiffies, but that won't 237 /* the expression is actually jiffies < end_jiffies, but that won't
238 work around the wraparound. Tricky eh? */ 238 work around the wraparound. Tricky eh? */
239 while ((charsleft = gs_real_chars_in_buffer (port->tty)) && 239 while ((charsleft = gs_real_chars_in_buffer (port->port.tty)) &&
240 time_after (end_jiffies, jiffies)) { 240 time_after (end_jiffies, jiffies)) {
241 /* Units check: 241 /* Units check:
242 chars * (bits/char) * (jiffies /sec) / (bits/sec) = jiffies! 242 chars * (bits/char) * (jiffies /sec) / (bits/sec) = jiffies!
@@ -309,7 +309,7 @@ void gs_flush_chars(struct tty_struct * tty)
309 } 309 }
310 310
311 /* Beats me -- REW */ 311 /* Beats me -- REW */
312 port->flags |= GS_TX_INTEN; 312 port->port.flags |= GS_TX_INTEN;
313 port->rd->enable_tx_interrupts (port); 313 port->rd->enable_tx_interrupts (port);
314 func_exit (); 314 func_exit ();
315} 315}
@@ -329,8 +329,8 @@ void gs_stop(struct tty_struct * tty)
329 329
330 if (port->xmit_cnt && 330 if (port->xmit_cnt &&
331 port->xmit_buf && 331 port->xmit_buf &&
332 (port->flags & GS_TX_INTEN) ) { 332 (port->port.flags & GS_TX_INTEN) ) {
333 port->flags &= ~GS_TX_INTEN; 333 port->port.flags &= ~GS_TX_INTEN;
334 port->rd->disable_tx_interrupts (port); 334 port->rd->disable_tx_interrupts (port);
335 } 335 }
336 func_exit (); 336 func_exit ();
@@ -349,8 +349,8 @@ void gs_start(struct tty_struct * tty)
349 349
350 if (port->xmit_cnt && 350 if (port->xmit_cnt &&
351 port->xmit_buf && 351 port->xmit_buf &&
352 !(port->flags & GS_TX_INTEN) ) { 352 !(port->port.flags & GS_TX_INTEN) ) {
353 port->flags |= GS_TX_INTEN; 353 port->port.flags |= GS_TX_INTEN;
354 port->rd->enable_tx_interrupts (port); 354 port->rd->enable_tx_interrupts (port);
355 } 355 }
356 func_exit (); 356 func_exit ();
@@ -365,7 +365,7 @@ static void gs_shutdown_port (struct gs_port *port)
365 365
366 if (!port) return; 366 if (!port) return;
367 367
368 if (!(port->flags & ASYNC_INITIALIZED)) 368 if (!(port->port.flags & ASYNC_INITIALIZED))
369 return; 369 return;
370 370
371 spin_lock_irqsave(&port->driver_lock, flags); 371 spin_lock_irqsave(&port->driver_lock, flags);
@@ -375,12 +375,12 @@ static void gs_shutdown_port (struct gs_port *port)
375 port->xmit_buf = NULL; 375 port->xmit_buf = NULL;
376 } 376 }
377 377
378 if (port->tty) 378 if (port->port.tty)
379 set_bit(TTY_IO_ERROR, &port->tty->flags); 379 set_bit(TTY_IO_ERROR, &port->port.tty->flags);
380 380
381 port->rd->shutdown_port (port); 381 port->rd->shutdown_port (port);
382 382
383 port->flags &= ~ASYNC_INITIALIZED; 383 port->port.flags &= ~ASYNC_INITIALIZED;
384 spin_unlock_irqrestore(&port->driver_lock, flags); 384 spin_unlock_irqrestore(&port->driver_lock, flags);
385 385
386 func_exit(); 386 func_exit();
@@ -396,16 +396,16 @@ void gs_hangup(struct tty_struct *tty)
396 if (!tty) return; 396 if (!tty) return;
397 397
398 port = tty->driver_data; 398 port = tty->driver_data;
399 tty = port->tty; 399 tty = port->port.tty;
400 if (!tty) 400 if (!tty)
401 return; 401 return;
402 402
403 gs_shutdown_port (port); 403 gs_shutdown_port (port);
404 port->flags &= ~(ASYNC_NORMAL_ACTIVE|GS_ACTIVE); 404 port->port.flags &= ~(ASYNC_NORMAL_ACTIVE|GS_ACTIVE);
405 port->tty = NULL; 405 port->port.tty = NULL;
406 port->count = 0; 406 port->port.count = 0;
407 407
408 wake_up_interruptible(&port->open_wait); 408 wake_up_interruptible(&port->port.open_wait);
409 func_exit (); 409 func_exit ();
410} 410}
411 411
@@ -424,7 +424,7 @@ int gs_block_til_ready(void *port_, struct file * filp)
424 424
425 if (!port) return 0; 425 if (!port) return 0;
426 426
427 tty = port->tty; 427 tty = port->port.tty;
428 428
429 if (!tty) return 0; 429 if (!tty) return 0;
430 430
@@ -433,9 +433,9 @@ int gs_block_til_ready(void *port_, struct file * filp)
433 * If the device is in the middle of being closed, then block 433 * If the device is in the middle of being closed, then block
434 * until it's done, and then try again. 434 * until it's done, and then try again.
435 */ 435 */
436 if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) { 436 if (tty_hung_up_p(filp) || port->port.flags & ASYNC_CLOSING) {
437 interruptible_sleep_on(&port->close_wait); 437 interruptible_sleep_on(&port->port.close_wait);
438 if (port->flags & ASYNC_HUP_NOTIFY) 438 if (port->port.flags & ASYNC_HUP_NOTIFY)
439 return -EAGAIN; 439 return -EAGAIN;
440 else 440 else
441 return -ERESTARTSYS; 441 return -ERESTARTSYS;
@@ -449,7 +449,7 @@ int gs_block_til_ready(void *port_, struct file * filp)
449 */ 449 */
450 if ((filp->f_flags & O_NONBLOCK) || 450 if ((filp->f_flags & O_NONBLOCK) ||
451 (tty->flags & (1 << TTY_IO_ERROR))) { 451 (tty->flags & (1 << TTY_IO_ERROR))) {
452 port->flags |= ASYNC_NORMAL_ACTIVE; 452 port->port.flags |= ASYNC_NORMAL_ACTIVE;
453 return 0; 453 return 0;
454 } 454 }
455 455
@@ -461,34 +461,34 @@ int gs_block_til_ready(void *port_, struct file * filp)
461 /* 461 /*
462 * Block waiting for the carrier detect and the line to become 462 * Block waiting for the carrier detect and the line to become
463 * free (i.e., not in use by the callout). While we are in 463 * free (i.e., not in use by the callout). While we are in
464 * this loop, port->count is dropped by one, so that 464 * this loop, port->port.count is dropped by one, so that
465 * rs_close() knows when to free things. We restore it upon 465 * rs_close() knows when to free things. We restore it upon
466 * exit, either normal or abnormal. 466 * exit, either normal or abnormal.
467 */ 467 */
468 retval = 0; 468 retval = 0;
469 469
470 add_wait_queue(&port->open_wait, &wait); 470 add_wait_queue(&port->port.open_wait, &wait);
471 471
472 gs_dprintk (GS_DEBUG_BTR, "after add waitq.\n"); 472 gs_dprintk (GS_DEBUG_BTR, "after add waitq.\n");
473 spin_lock_irqsave(&port->driver_lock, flags); 473 spin_lock_irqsave(&port->driver_lock, flags);
474 if (!tty_hung_up_p(filp)) { 474 if (!tty_hung_up_p(filp)) {
475 port->count--; 475 port->port.count--;
476 } 476 }
477 spin_unlock_irqrestore(&port->driver_lock, flags); 477 spin_unlock_irqrestore(&port->driver_lock, flags);
478 port->blocked_open++; 478 port->port.blocked_open++;
479 while (1) { 479 while (1) {
480 CD = port->rd->get_CD (port); 480 CD = port->rd->get_CD (port);
481 gs_dprintk (GS_DEBUG_BTR, "CD is now %d.\n", CD); 481 gs_dprintk (GS_DEBUG_BTR, "CD is now %d.\n", CD);
482 set_current_state (TASK_INTERRUPTIBLE); 482 set_current_state (TASK_INTERRUPTIBLE);
483 if (tty_hung_up_p(filp) || 483 if (tty_hung_up_p(filp) ||
484 !(port->flags & ASYNC_INITIALIZED)) { 484 !(port->port.flags & ASYNC_INITIALIZED)) {
485 if (port->flags & ASYNC_HUP_NOTIFY) 485 if (port->port.flags & ASYNC_HUP_NOTIFY)
486 retval = -EAGAIN; 486 retval = -EAGAIN;
487 else 487 else
488 retval = -ERESTARTSYS; 488 retval = -ERESTARTSYS;
489 break; 489 break;
490 } 490 }
491 if (!(port->flags & ASYNC_CLOSING) && 491 if (!(port->port.flags & ASYNC_CLOSING) &&
492 (do_clocal || CD)) 492 (do_clocal || CD))
493 break; 493 break;
494 gs_dprintk (GS_DEBUG_BTR, "signal_pending is now: %d (%lx)\n", 494 gs_dprintk (GS_DEBUG_BTR, "signal_pending is now: %d (%lx)\n",
@@ -500,17 +500,17 @@ int gs_block_til_ready(void *port_, struct file * filp)
500 schedule(); 500 schedule();
501 } 501 }
502 gs_dprintk (GS_DEBUG_BTR, "Got out of the loop. (%d)\n", 502 gs_dprintk (GS_DEBUG_BTR, "Got out of the loop. (%d)\n",
503 port->blocked_open); 503 port->port.blocked_open);
504 set_current_state (TASK_RUNNING); 504 set_current_state (TASK_RUNNING);
505 remove_wait_queue(&port->open_wait, &wait); 505 remove_wait_queue(&port->port.open_wait, &wait);
506 if (!tty_hung_up_p(filp)) { 506 if (!tty_hung_up_p(filp)) {
507 port->count++; 507 port->port.count++;
508 } 508 }
509 port->blocked_open--; 509 port->port.blocked_open--;
510 if (retval) 510 if (retval)
511 return retval; 511 return retval;
512 512
513 port->flags |= ASYNC_NORMAL_ACTIVE; 513 port->port.flags |= ASYNC_NORMAL_ACTIVE;
514 func_exit (); 514 func_exit ();
515 return 0; 515 return 0;
516} 516}
@@ -529,10 +529,10 @@ void gs_close(struct tty_struct * tty, struct file * filp)
529 529
530 if (!port) return; 530 if (!port) return;
531 531
532 if (!port->tty) { 532 if (!port->port.tty) {
533 /* This seems to happen when this is called from vhangup. */ 533 /* This seems to happen when this is called from vhangup. */
534 gs_dprintk (GS_DEBUG_CLOSE, "gs: Odd: port->tty is NULL\n"); 534 gs_dprintk (GS_DEBUG_CLOSE, "gs: Odd: port->port.tty is NULL\n");
535 port->tty = tty; 535 port->port.tty = tty;
536 } 536 }
537 537
538 spin_lock_irqsave(&port->driver_lock, flags); 538 spin_lock_irqsave(&port->driver_lock, flags);
@@ -545,23 +545,23 @@ void gs_close(struct tty_struct * tty, struct file * filp)
545 return; 545 return;
546 } 546 }
547 547
548 if ((tty->count == 1) && (port->count != 1)) { 548 if ((tty->count == 1) && (port->port.count != 1)) {
549 printk(KERN_ERR "gs: gs_close port %p: bad port count;" 549 printk(KERN_ERR "gs: gs_close port %p: bad port count;"
550 " tty->count is 1, port count is %d\n", port, port->count); 550 " tty->count is 1, port count is %d\n", port, port->port.count);
551 port->count = 1; 551 port->port.count = 1;
552 } 552 }
553 if (--port->count < 0) { 553 if (--port->port.count < 0) {
554 printk(KERN_ERR "gs: gs_close port %p: bad port count: %d\n", port, port->count); 554 printk(KERN_ERR "gs: gs_close port %p: bad port count: %d\n", port, port->port.count);
555 port->count = 0; 555 port->port.count = 0;
556 } 556 }
557 557
558 if (port->count) { 558 if (port->port.count) {
559 gs_dprintk(GS_DEBUG_CLOSE, "gs_close port %p: count: %d\n", port, port->count); 559 gs_dprintk(GS_DEBUG_CLOSE, "gs_close port %p: count: %d\n", port, port->port.count);
560 spin_unlock_irqrestore(&port->driver_lock, flags); 560 spin_unlock_irqrestore(&port->driver_lock, flags);
561 func_exit (); 561 func_exit ();
562 return; 562 return;
563 } 563 }
564 port->flags |= ASYNC_CLOSING; 564 port->port.flags |= ASYNC_CLOSING;
565 565
566 /* 566 /*
567 * Now we wait for the transmit buffer to clear; and we notify 567 * Now we wait for the transmit buffer to clear; and we notify
@@ -585,7 +585,7 @@ void gs_close(struct tty_struct * tty, struct file * filp)
585 if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE) 585 if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE)
586 gs_wait_tx_flushed (port, port->closing_wait); 586 gs_wait_tx_flushed (port, port->closing_wait);
587 587
588 port->flags &= ~GS_ACTIVE; 588 port->port.flags &= ~GS_ACTIVE;
589 589
590 gs_flush_buffer(tty); 590 gs_flush_buffer(tty);
591 591
@@ -595,18 +595,18 @@ void gs_close(struct tty_struct * tty, struct file * filp)
595 port->event = 0; 595 port->event = 0;
596 port->rd->close (port); 596 port->rd->close (port);
597 port->rd->shutdown_port (port); 597 port->rd->shutdown_port (port);
598 port->tty = NULL; 598 port->port.tty = NULL;
599 599
600 if (port->blocked_open) { 600 if (port->port.blocked_open) {
601 if (port->close_delay) { 601 if (port->close_delay) {
602 spin_unlock_irqrestore(&port->driver_lock, flags); 602 spin_unlock_irqrestore(&port->driver_lock, flags);
603 msleep_interruptible(jiffies_to_msecs(port->close_delay)); 603 msleep_interruptible(jiffies_to_msecs(port->close_delay));
604 spin_lock_irqsave(&port->driver_lock, flags); 604 spin_lock_irqsave(&port->driver_lock, flags);
605 } 605 }
606 wake_up_interruptible(&port->open_wait); 606 wake_up_interruptible(&port->port.open_wait);
607 } 607 }
608 port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING | ASYNC_INITIALIZED); 608 port->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING | ASYNC_INITIALIZED);
609 wake_up_interruptible(&port->close_wait); 609 wake_up_interruptible(&port->port.close_wait);
610 610
611 func_exit (); 611 func_exit ();
612} 612}
@@ -626,10 +626,10 @@ void gs_set_termios (struct tty_struct * tty,
626 port = tty->driver_data; 626 port = tty->driver_data;
627 627
628 if (!port) return; 628 if (!port) return;
629 if (!port->tty) { 629 if (!port->port.tty) {
630 /* This seems to happen when this is called after gs_close. */ 630 /* This seems to happen when this is called after gs_close. */
631 gs_dprintk (GS_DEBUG_TERMIOS, "gs: Odd: port->tty is NULL\n"); 631 gs_dprintk (GS_DEBUG_TERMIOS, "gs: Odd: port->port.tty is NULL\n");
632 port->tty = tty; 632 port->port.tty = tty;
633 } 633 }
634 634
635 635
@@ -651,15 +651,15 @@ void gs_set_termios (struct tty_struct * tty,
651 baudrate = tty_get_baud_rate(tty); 651 baudrate = tty_get_baud_rate(tty);
652 652
653 if ((tiosp->c_cflag & CBAUD) == B38400) { 653 if ((tiosp->c_cflag & CBAUD) == B38400) {
654 if ( (port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) 654 if ( (port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
655 baudrate = 57600; 655 baudrate = 57600;
656 else if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) 656 else if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
657 baudrate = 115200; 657 baudrate = 115200;
658 else if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) 658 else if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
659 baudrate = 230400; 659 baudrate = 230400;
660 else if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) 660 else if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
661 baudrate = 460800; 661 baudrate = 460800;
662 else if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) 662 else if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)
663 baudrate = (port->baud_base / port->custom_divisor); 663 baudrate = (port->baud_base / port->custom_divisor);
664 } 664 }
665 665
@@ -715,7 +715,7 @@ int gs_init_port(struct gs_port *port)
715 715
716 func_enter (); 716 func_enter ();
717 717
718 if (port->flags & ASYNC_INITIALIZED) { 718 if (port->port.flags & ASYNC_INITIALIZED) {
719 func_exit (); 719 func_exit ();
720 return 0; 720 return 0;
721 } 721 }
@@ -737,15 +737,15 @@ int gs_init_port(struct gs_port *port)
737 } 737 }
738 738
739 spin_lock_irqsave (&port->driver_lock, flags); 739 spin_lock_irqsave (&port->driver_lock, flags);
740 if (port->tty) 740 if (port->port.tty)
741 clear_bit(TTY_IO_ERROR, &port->tty->flags); 741 clear_bit(TTY_IO_ERROR, &port->port.tty->flags);
742 mutex_init(&port->port_write_mutex); 742 mutex_init(&port->port_write_mutex);
743 port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; 743 port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
744 spin_unlock_irqrestore(&port->driver_lock, flags); 744 spin_unlock_irqrestore(&port->driver_lock, flags);
745 gs_set_termios(port->tty, NULL); 745 gs_set_termios(port->port.tty, NULL);
746 spin_lock_irqsave (&port->driver_lock, flags); 746 spin_lock_irqsave (&port->driver_lock, flags);
747 port->flags |= ASYNC_INITIALIZED; 747 port->port.flags |= ASYNC_INITIALIZED;
748 port->flags &= ~GS_TX_INTEN; 748 port->port.flags &= ~GS_TX_INTEN;
749 749
750 spin_unlock_irqrestore(&port->driver_lock, flags); 750 spin_unlock_irqrestore(&port->driver_lock, flags);
751 func_exit (); 751 func_exit ();
@@ -764,11 +764,11 @@ int gs_setserial(struct gs_port *port, struct serial_struct __user *sp)
764 if ((sio.baud_base != port->baud_base) || 764 if ((sio.baud_base != port->baud_base) ||
765 (sio.close_delay != port->close_delay) || 765 (sio.close_delay != port->close_delay) ||
766 ((sio.flags & ~ASYNC_USR_MASK) != 766 ((sio.flags & ~ASYNC_USR_MASK) !=
767 (port->flags & ~ASYNC_USR_MASK))) 767 (port->port.flags & ~ASYNC_USR_MASK)))
768 return(-EPERM); 768 return(-EPERM);
769 } 769 }
770 770
771 port->flags = (port->flags & ~ASYNC_USR_MASK) | 771 port->port.flags = (port->port.flags & ~ASYNC_USR_MASK) |
772 (sio.flags & ASYNC_USR_MASK); 772 (sio.flags & ASYNC_USR_MASK);
773 773
774 port->baud_base = sio.baud_base; 774 port->baud_base = sio.baud_base;
@@ -776,7 +776,7 @@ int gs_setserial(struct gs_port *port, struct serial_struct __user *sp)
776 port->closing_wait = sio.closing_wait; 776 port->closing_wait = sio.closing_wait;
777 port->custom_divisor = sio.custom_divisor; 777 port->custom_divisor = sio.custom_divisor;
778 778
779 gs_set_termios (port->tty, NULL); 779 gs_set_termios (port->port.tty, NULL);
780 780
781 return 0; 781 return 0;
782} 782}
@@ -793,7 +793,7 @@ int gs_getserial(struct gs_port *port, struct serial_struct __user *sp)
793 struct serial_struct sio; 793 struct serial_struct sio;
794 794
795 memset(&sio, 0, sizeof(struct serial_struct)); 795 memset(&sio, 0, sizeof(struct serial_struct));
796 sio.flags = port->flags; 796 sio.flags = port->port.flags;
797 sio.baud_base = port->baud_base; 797 sio.baud_base = port->baud_base;
798 sio.close_delay = port->close_delay; 798 sio.close_delay = port->close_delay;
799 sio.closing_wait = port->closing_wait; 799 sio.closing_wait = port->closing_wait;
@@ -821,10 +821,10 @@ void gs_got_break(struct gs_port *port)
821{ 821{
822 func_enter (); 822 func_enter ();
823 823
824 tty_insert_flip_char(port->tty, 0, TTY_BREAK); 824 tty_insert_flip_char(port->port.tty, 0, TTY_BREAK);
825 tty_schedule_flip(port->tty); 825 tty_schedule_flip(port->port.tty);
826 if (port->flags & ASYNC_SAK) { 826 if (port->port.flags & ASYNC_SAK) {
827 do_SAK (port->tty); 827 do_SAK (port->port.tty);
828 } 828 }
829 829
830 func_exit (); 830 func_exit ();
diff --git a/drivers/char/genrtc.c b/drivers/char/genrtc.c
index 69f0a2993af0..aac0985a572b 100644
--- a/drivers/char/genrtc.c
+++ b/drivers/char/genrtc.c
@@ -51,6 +51,7 @@
51#include <linux/init.h> 51#include <linux/init.h>
52#include <linux/poll.h> 52#include <linux/poll.h>
53#include <linux/proc_fs.h> 53#include <linux/proc_fs.h>
54#include <linux/smp_lock.h>
54#include <linux/workqueue.h> 55#include <linux/workqueue.h>
55 56
56#include <asm/uaccess.h> 57#include <asm/uaccess.h>
@@ -338,12 +339,16 @@ static int gen_rtc_ioctl(struct inode *inode, struct file *file,
338 339
339static int gen_rtc_open(struct inode *inode, struct file *file) 340static int gen_rtc_open(struct inode *inode, struct file *file)
340{ 341{
341 if (gen_rtc_status & RTC_IS_OPEN) 342 lock_kernel();
343 if (gen_rtc_status & RTC_IS_OPEN) {
344 unlock_kernel();
342 return -EBUSY; 345 return -EBUSY;
346 }
343 347
344 gen_rtc_status |= RTC_IS_OPEN; 348 gen_rtc_status |= RTC_IS_OPEN;
345 gen_rtc_irq_data = 0; 349 gen_rtc_irq_data = 0;
346 irq_active = 0; 350 irq_active = 0;
351 unlock_kernel();
347 352
348 return 0; 353 return 0;
349} 354}
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c
index e7fb0bca3667..fb0a85a1eb36 100644
--- a/drivers/char/hpet.c
+++ b/drivers/char/hpet.c
@@ -14,6 +14,7 @@
14#include <linux/interrupt.h> 14#include <linux/interrupt.h>
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/kernel.h> 16#include <linux/kernel.h>
17#include <linux/smp_lock.h>
17#include <linux/types.h> 18#include <linux/types.h>
18#include <linux/miscdevice.h> 19#include <linux/miscdevice.h>
19#include <linux/major.h> 20#include <linux/major.h>
@@ -193,6 +194,7 @@ static int hpet_open(struct inode *inode, struct file *file)
193 if (file->f_mode & FMODE_WRITE) 194 if (file->f_mode & FMODE_WRITE)
194 return -EINVAL; 195 return -EINVAL;
195 196
197 lock_kernel();
196 spin_lock_irq(&hpet_lock); 198 spin_lock_irq(&hpet_lock);
197 199
198 for (devp = NULL, hpetp = hpets; hpetp && !devp; hpetp = hpetp->hp_next) 200 for (devp = NULL, hpetp = hpets; hpetp && !devp; hpetp = hpetp->hp_next)
@@ -207,6 +209,7 @@ static int hpet_open(struct inode *inode, struct file *file)
207 209
208 if (!devp) { 210 if (!devp) {
209 spin_unlock_irq(&hpet_lock); 211 spin_unlock_irq(&hpet_lock);
212 unlock_kernel();
210 return -EBUSY; 213 return -EBUSY;
211 } 214 }
212 215
@@ -214,6 +217,7 @@ static int hpet_open(struct inode *inode, struct file *file)
214 devp->hd_irqdata = 0; 217 devp->hd_irqdata = 0;
215 devp->hd_flags |= HPET_OPEN; 218 devp->hd_flags |= HPET_OPEN;
216 spin_unlock_irq(&hpet_lock); 219 spin_unlock_irq(&hpet_lock);
220 unlock_kernel();
217 221
218 return 0; 222 return 0;
219} 223}
diff --git a/drivers/char/hvc_console.c b/drivers/char/hvc_console.c
index 44160d5ebca0..2f9759d625cc 100644
--- a/drivers/char/hvc_console.c
+++ b/drivers/char/hvc_console.c
@@ -675,12 +675,6 @@ static int hvc_poll(struct hvc_struct *hp)
675 return poll_mask; 675 return poll_mask;
676} 676}
677 677
678#if defined(CONFIG_XMON) && defined(CONFIG_SMP)
679extern cpumask_t cpus_in_xmon;
680#else
681static const cpumask_t cpus_in_xmon = CPU_MASK_NONE;
682#endif
683
684/* 678/*
685 * This kthread is either polling or interrupt driven. This is determined by 679 * This kthread is either polling or interrupt driven. This is determined by
686 * calling hvc_poll() who determines whether a console adapter support 680 * calling hvc_poll() who determines whether a console adapter support
@@ -698,7 +692,7 @@ static int khvcd(void *unused)
698 hvc_kicked = 0; 692 hvc_kicked = 0;
699 try_to_freeze(); 693 try_to_freeze();
700 wmb(); 694 wmb();
701 if (cpus_empty(cpus_in_xmon)) { 695 if (!cpus_are_in_xmon()) {
702 spin_lock(&hvc_structs_lock); 696 spin_lock(&hvc_structs_lock);
703 list_for_each_entry(hp, &hvc_structs, next) { 697 list_for_each_entry(hp, &hvc_structs, next) {
704 poll_mask |= hvc_poll(hp); 698 poll_mask |= hvc_poll(hp);
diff --git a/drivers/char/hvc_console.h b/drivers/char/hvc_console.h
index 8c59818050e6..42ffb17e15df 100644
--- a/drivers/char/hvc_console.h
+++ b/drivers/char/hvc_console.h
@@ -60,4 +60,14 @@ extern struct hvc_struct * __devinit hvc_alloc(uint32_t vtermno, int irq,
60/* remove a vterm from hvc tty operation (modele_exit or hotplug remove) */ 60/* remove a vterm from hvc tty operation (modele_exit or hotplug remove) */
61extern int __devexit hvc_remove(struct hvc_struct *hp); 61extern int __devexit hvc_remove(struct hvc_struct *hp);
62 62
63
64#if defined(CONFIG_XMON) && defined(CONFIG_SMP)
65#include <asm/xmon.h>
66#else
67static inline int cpus_are_in_xmon(void)
68{
69 return 0;
70}
71#endif
72
63#endif // HVC_CONSOLE_H 73#endif // HVC_CONSOLE_H
diff --git a/drivers/char/hvc_xen.c b/drivers/char/hvc_xen.c
index dd68f8541c2d..db2ae4216279 100644
--- a/drivers/char/hvc_xen.c
+++ b/drivers/char/hvc_xen.c
@@ -39,9 +39,14 @@ static int xencons_irq;
39 39
40/* ------------------------------------------------------------------ */ 40/* ------------------------------------------------------------------ */
41 41
42static unsigned long console_pfn = ~0ul;
43
42static inline struct xencons_interface *xencons_interface(void) 44static inline struct xencons_interface *xencons_interface(void)
43{ 45{
44 return mfn_to_virt(xen_start_info->console.domU.mfn); 46 if (console_pfn == ~0ul)
47 return mfn_to_virt(xen_start_info->console.domU.mfn);
48 else
49 return __va(console_pfn << PAGE_SHIFT);
45} 50}
46 51
47static inline void notify_daemon(void) 52static inline void notify_daemon(void)
@@ -101,20 +106,32 @@ static int __init xen_init(void)
101{ 106{
102 struct hvc_struct *hp; 107 struct hvc_struct *hp;
103 108
104 if (!is_running_on_xen()) 109 if (!is_running_on_xen() ||
105 return 0; 110 is_initial_xendomain() ||
111 !xen_start_info->console.domU.evtchn)
112 return -ENODEV;
106 113
107 xencons_irq = bind_evtchn_to_irq(xen_start_info->console.domU.evtchn); 114 xencons_irq = bind_evtchn_to_irq(xen_start_info->console.domU.evtchn);
108 if (xencons_irq < 0) 115 if (xencons_irq < 0)
109 xencons_irq = 0 /* NO_IRQ */; 116 xencons_irq = 0; /* NO_IRQ */
117
110 hp = hvc_alloc(HVC_COOKIE, xencons_irq, &hvc_ops, 256); 118 hp = hvc_alloc(HVC_COOKIE, xencons_irq, &hvc_ops, 256);
111 if (IS_ERR(hp)) 119 if (IS_ERR(hp))
112 return PTR_ERR(hp); 120 return PTR_ERR(hp);
113 121
114 hvc = hp; 122 hvc = hp;
123
124 console_pfn = mfn_to_pfn(xen_start_info->console.domU.mfn);
125
115 return 0; 126 return 0;
116} 127}
117 128
129void xen_console_resume(void)
130{
131 if (xencons_irq)
132 rebind_evtchn_irq(xen_start_info->console.domU.evtchn, xencons_irq);
133}
134
118static void __exit xen_fini(void) 135static void __exit xen_fini(void)
119{ 136{
120 if (hvc) 137 if (hvc)
@@ -134,12 +151,28 @@ module_init(xen_init);
134module_exit(xen_fini); 151module_exit(xen_fini);
135console_initcall(xen_cons_init); 152console_initcall(xen_cons_init);
136 153
154static void raw_console_write(const char *str, int len)
155{
156 while(len > 0) {
157 int rc = HYPERVISOR_console_io(CONSOLEIO_write, len, (char *)str);
158 if (rc <= 0)
159 break;
160
161 str += rc;
162 len -= rc;
163 }
164}
165
166#ifdef CONFIG_EARLY_PRINTK
137static void xenboot_write_console(struct console *console, const char *string, 167static void xenboot_write_console(struct console *console, const char *string,
138 unsigned len) 168 unsigned len)
139{ 169{
140 unsigned int linelen, off = 0; 170 unsigned int linelen, off = 0;
141 const char *pos; 171 const char *pos;
142 172
173 raw_console_write(string, len);
174
175 write_console(0, "(early) ", 8);
143 while (off < len && NULL != (pos = strchr(string+off, '\n'))) { 176 while (off < len && NULL != (pos = strchr(string+off, '\n'))) {
144 linelen = pos-string+off; 177 linelen = pos-string+off;
145 if (off + linelen > len) 178 if (off + linelen > len)
@@ -155,5 +188,23 @@ static void xenboot_write_console(struct console *console, const char *string,
155struct console xenboot_console = { 188struct console xenboot_console = {
156 .name = "xenboot", 189 .name = "xenboot",
157 .write = xenboot_write_console, 190 .write = xenboot_write_console,
158 .flags = CON_PRINTBUFFER | CON_BOOT, 191 .flags = CON_PRINTBUFFER | CON_BOOT | CON_ANYTIME,
159}; 192};
193#endif /* CONFIG_EARLY_PRINTK */
194
195void xen_raw_console_write(const char *str)
196{
197 raw_console_write(str, strlen(str));
198}
199
200void xen_raw_printk(const char *fmt, ...)
201{
202 static char buf[512];
203 va_list ap;
204
205 va_start(ap, fmt);
206 vsnprintf(buf, sizeof(buf), fmt, ap);
207 va_end(ap);
208
209 xen_raw_console_write(buf);
210}
diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig
index 8d6c2089d2a8..efd0b4db7c8e 100644
--- a/drivers/char/hw_random/Kconfig
+++ b/drivers/char/hw_random/Kconfig
@@ -112,3 +112,12 @@ config HW_RANDOM_PASEMI
112 112
113 If unsure, say Y. 113 If unsure, say Y.
114 114
115config HW_RANDOM_VIRTIO
116 tristate "VirtIO Random Number Generator support"
117 depends on HW_RANDOM && VIRTIO
118 ---help---
119 This driver provides kernel-side support for the virtual Random Number
120 Generator hardware.
121
122 To compile this driver as a module, choose M here: the
123 module will be called virtio-rng. If unsure, say N.
diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile
index c8b7300e2fb1..b4940ddbb35f 100644
--- a/drivers/char/hw_random/Makefile
+++ b/drivers/char/hw_random/Makefile
@@ -11,3 +11,4 @@ obj-$(CONFIG_HW_RANDOM_VIA) += via-rng.o
11obj-$(CONFIG_HW_RANDOM_IXP4XX) += ixp4xx-rng.o 11obj-$(CONFIG_HW_RANDOM_IXP4XX) += ixp4xx-rng.o
12obj-$(CONFIG_HW_RANDOM_OMAP) += omap-rng.o 12obj-$(CONFIG_HW_RANDOM_OMAP) += omap-rng.o
13obj-$(CONFIG_HW_RANDOM_PASEMI) += pasemi-rng.o 13obj-$(CONFIG_HW_RANDOM_PASEMI) += pasemi-rng.o
14obj-$(CONFIG_HW_RANDOM_VIRTIO) += virtio-rng.o
diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c
index 662d60e44e9a..e5d583c84e4f 100644
--- a/drivers/char/hw_random/core.c
+++ b/drivers/char/hw_random/core.c
@@ -37,6 +37,7 @@
37#include <linux/kernel.h> 37#include <linux/kernel.h>
38#include <linux/fs.h> 38#include <linux/fs.h>
39#include <linux/sched.h> 39#include <linux/sched.h>
40#include <linux/smp_lock.h>
40#include <linux/init.h> 41#include <linux/init.h>
41#include <linux/miscdevice.h> 42#include <linux/miscdevice.h>
42#include <linux/delay.h> 43#include <linux/delay.h>
@@ -86,6 +87,7 @@ static int rng_dev_open(struct inode *inode, struct file *filp)
86 return -EINVAL; 87 return -EINVAL;
87 if (filp->f_mode & FMODE_WRITE) 88 if (filp->f_mode & FMODE_WRITE)
88 return -EINVAL; 89 return -EINVAL;
90 cycle_kernel_lock();
89 return 0; 91 return 0;
90} 92}
91 93
diff --git a/drivers/char/hw_random/intel-rng.c b/drivers/char/hw_random/intel-rng.c
index 5cc651ef75eb..27fdc0866496 100644
--- a/drivers/char/hw_random/intel-rng.c
+++ b/drivers/char/hw_random/intel-rng.c
@@ -273,7 +273,7 @@ static int __init intel_rng_hw_init(void *_intel_rng_hw)
273 if (mfc != INTEL_FWH_MANUFACTURER_CODE || 273 if (mfc != INTEL_FWH_MANUFACTURER_CODE ||
274 (dvc != INTEL_FWH_DEVICE_CODE_8M && 274 (dvc != INTEL_FWH_DEVICE_CODE_8M &&
275 dvc != INTEL_FWH_DEVICE_CODE_4M)) { 275 dvc != INTEL_FWH_DEVICE_CODE_4M)) {
276 printk(KERN_ERR PFX "FWH not detected\n"); 276 printk(KERN_NOTICE PFX "FWH not detected\n");
277 return -ENODEV; 277 return -ENODEV;
278 } 278 }
279 279
diff --git a/drivers/char/hw_random/pasemi-rng.c b/drivers/char/hw_random/pasemi-rng.c
index 6d50e9bc700b..7fa61dd1d9d9 100644
--- a/drivers/char/hw_random/pasemi-rng.c
+++ b/drivers/char/hw_random/pasemi-rng.c
@@ -24,7 +24,7 @@
24#include <linux/platform_device.h> 24#include <linux/platform_device.h>
25#include <linux/hw_random.h> 25#include <linux/hw_random.h>
26#include <linux/delay.h> 26#include <linux/delay.h>
27#include <asm/of_platform.h> 27#include <linux/of_platform.h>
28#include <asm/io.h> 28#include <asm/io.h>
29 29
30#define SDCRNG_CTL_REG 0x00 30#define SDCRNG_CTL_REG 0x00
diff --git a/drivers/char/hw_random/virtio-rng.c b/drivers/char/hw_random/virtio-rng.c
new file mode 100644
index 000000000000..d0e563e4fc39
--- /dev/null
+++ b/drivers/char/hw_random/virtio-rng.c
@@ -0,0 +1,155 @@
1/*
2 * Randomness driver for virtio
3 * Copyright (C) 2007, 2008 Rusty Russell IBM Corporation
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19#include <linux/err.h>
20#include <linux/hw_random.h>
21#include <linux/scatterlist.h>
22#include <linux/spinlock.h>
23#include <linux/virtio.h>
24#include <linux/virtio_rng.h>
25
26/* The host will fill any buffer we give it with sweet, sweet randomness. We
27 * give it 64 bytes at a time, and the hwrng framework takes it 4 bytes at a
28 * time. */
29#define RANDOM_DATA_SIZE 64
30
31static struct virtqueue *vq;
32static u32 *random_data;
33static unsigned int data_left;
34static DECLARE_COMPLETION(have_data);
35
36static void random_recv_done(struct virtqueue *vq)
37{
38 int len;
39
40 /* We never get spurious callbacks. */
41 if (!vq->vq_ops->get_buf(vq, &len))
42 BUG();
43
44 data_left = len / sizeof(random_data[0]);
45 complete(&have_data);
46}
47
48static void register_buffer(void)
49{
50 struct scatterlist sg;
51
52 sg_init_one(&sg, random_data, RANDOM_DATA_SIZE);
53 /* There should always be room for one buffer. */
54 if (vq->vq_ops->add_buf(vq, &sg, 0, 1, random_data) != 0)
55 BUG();
56 vq->vq_ops->kick(vq);
57}
58
59/* At least we don't udelay() in a loop like some other drivers. */
60static int virtio_data_present(struct hwrng *rng, int wait)
61{
62 if (data_left)
63 return 1;
64
65 if (!wait)
66 return 0;
67
68 wait_for_completion(&have_data);
69 return 1;
70}
71
72/* virtio_data_present() must have succeeded before this is called. */
73static int virtio_data_read(struct hwrng *rng, u32 *data)
74{
75 BUG_ON(!data_left);
76
77 *data = random_data[--data_left];
78
79 if (!data_left) {
80 init_completion(&have_data);
81 register_buffer();
82 }
83 return sizeof(*data);
84}
85
86static struct hwrng virtio_hwrng = {
87 .name = "virtio",
88 .data_present = virtio_data_present,
89 .data_read = virtio_data_read,
90};
91
92static int virtrng_probe(struct virtio_device *vdev)
93{
94 int err;
95
96 /* We expect a single virtqueue. */
97 vq = vdev->config->find_vq(vdev, 0, random_recv_done);
98 if (IS_ERR(vq))
99 return PTR_ERR(vq);
100
101 err = hwrng_register(&virtio_hwrng);
102 if (err) {
103 vdev->config->del_vq(vq);
104 return err;
105 }
106
107 register_buffer();
108 return 0;
109}
110
111static void virtrng_remove(struct virtio_device *vdev)
112{
113 vdev->config->reset(vdev);
114 hwrng_unregister(&virtio_hwrng);
115 vdev->config->del_vq(vq);
116}
117
118static struct virtio_device_id id_table[] = {
119 { VIRTIO_ID_RNG, VIRTIO_DEV_ANY_ID },
120 { 0 },
121};
122
123static struct virtio_driver virtio_rng = {
124 .driver.name = KBUILD_MODNAME,
125 .driver.owner = THIS_MODULE,
126 .id_table = id_table,
127 .probe = virtrng_probe,
128 .remove = __devexit_p(virtrng_remove),
129};
130
131static int __init init(void)
132{
133 int err;
134
135 random_data = kmalloc(RANDOM_DATA_SIZE, GFP_KERNEL);
136 if (!random_data)
137 return -ENOMEM;
138
139 err = register_virtio_driver(&virtio_rng);
140 if (err)
141 kfree(random_data);
142 return err;
143}
144
145static void __exit fini(void)
146{
147 kfree(random_data);
148 unregister_virtio_driver(&virtio_rng);
149}
150module_init(init);
151module_exit(fini);
152
153MODULE_DEVICE_TABLE(virtio, id_table);
154MODULE_DESCRIPTION("Virtio random number driver");
155MODULE_LICENSE("GPL");
diff --git a/drivers/char/ip2/Makefile b/drivers/char/ip2/Makefile
index 6bfe2543ddc2..939618f62fe1 100644
--- a/drivers/char/ip2/Makefile
+++ b/drivers/char/ip2/Makefile
@@ -2,7 +2,7 @@
2# Makefile for the Computone IntelliPort Plus Driver 2# Makefile for the Computone IntelliPort Plus Driver
3# 3#
4 4
5obj-$(CONFIG_COMPUTONE) += ip2.o ip2main.o 5obj-$(CONFIG_COMPUTONE) += ip2.o
6 6
7ip2-objs := ip2base.o 7ip2-objs := ip2base.o ip2main.o
8 8
diff --git a/drivers/char/ip2/fip_firm.h b/drivers/char/ip2/fip_firm.h
deleted file mode 100644
index 4c525fa4929f..000000000000
--- a/drivers/char/ip2/fip_firm.h
+++ /dev/null
@@ -1,2149 +0,0 @@
1/* fip_firm.h - Intelliport II loadware */
2/* -31232 bytes read from ff.lod */
3
4static unsigned char fip_firm[] __initdata = {
50x3C,0x42,0x37,0x18,0x02,0x01,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
60x57,0x65,0x64,0x20,0x44,0x65,0x63,0x20,0x30,0x31,0x20,0x31,0x32,0x3A,0x32,0x34,
70x3A,0x33,0x30,0x20,0x31,0x39,0x39,0x39,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
80xE9,0x6C,0x0F,0x42,0x65,0x47,0x69,0x4E,0x6E,0x49,0x6E,0x47,0x20,0x6F,0x46,0x20,
90x63,0x4F,0x64,0x45,0xCC,0x13,0x5A,0x15,0xE8,0x16,0x76,0x18,0x04,0x1A,0x92,0x1B,
100x20,0x1D,0xAE,0x1E,0x3C,0x20,0xCA,0x21,0x58,0x23,0xE6,0x24,0x74,0x26,0x02,0x28,
110x90,0x29,0x1E,0x2B,0xAC,0x2C,0x3A,0x2E,0xC8,0x2F,0x56,0x31,0xE4,0x32,0x72,0x34,
120x00,0x36,0x8E,0x37,0x1C,0x39,0xAA,0x3A,0x38,0x3C,0xC6,0x3D,0x54,0x3F,0xE2,0x40,
130x70,0x42,0xFE,0x43,0x8C,0x45,0x1A,0x47,0xA8,0x48,0x36,0x4A,0xC4,0x4B,0x52,0x4D,
140xE0,0x4E,0x6E,0x50,0xFC,0x51,0x8A,0x53,0x18,0x55,0xA6,0x56,0x34,0x58,0xC2,0x59,
150x50,0x5B,0xDE,0x5C,0x6C,0x5E,0xFA,0x5F,0x88,0x61,0x16,0x63,0xA4,0x64,0x32,0x66,
160xC0,0x67,0x4E,0x69,0xDC,0x6A,0x6A,0x6C,0xF8,0x6D,0x86,0x6F,0x14,0x71,0xA2,0x72,
170x30,0x74,0xBE,0x75,0x4C,0x77,0x6C,0x77,0x8C,0x77,0xAC,0x77,0x33,0xDB,0x8A,0xDC,
180x53,0x33,0xDB,0x25,0x07,0x00,0x75,0x0A,0x8A,0x1E,0x08,0x01,0x83,0xE3,0x0C,0xEB,
190x20,0x90,0x3C,0x01,0x75,0x0A,0x8A,0x1E,0x08,0x01,0x80,0xE3,0xC0,0xEB,0x12,0x90,
200x8A,0x1E,0x0D,0x01,0x3C,0x02,0x75,0x06,0x80,0xE3,0x0C,0xEB,0x04,0x90,0x80,0xE3,
210xC0,0x53,0x50,0x8B,0x1E,0xBA,0x13,0x8E,0xDB,0xE8,0x6A,0x65,0x55,0x8B,0xEC,0x53,
220x1E,0x2B,0xC0,0x8E,0xD8,0x8B,0x5E,0x04,0xC1,0xE3,0x04,0x03,0x5E,0x06,0xD1,0xE3,
230x2E,0x8B,0x9F,0x44,0x00,0x8D,0x47,0x2A,0x1E,0x5A,0x1F,0x5B,0x5D,0xC3,0x55,0x8B,
240xEC,0x53,0x1E,0x2B,0xC0,0x8E,0xD8,0x8B,0x5E,0x04,0xC1,0xE3,0x04,0x03,0x5E,0x06,
250xD1,0xE3,0x2E,0x8B,0x9F,0x44,0x00,0x8D,0x47,0x34,0x1E,0x5A,0x1F,0x5B,0x5D,0xC3,
260xFB,0x55,0x8B,0xEC,0x53,0x51,0x52,0x56,0x57,0x1E,0x06,0x1E,0x07,0x33,0xC0,0x8E,
270xD8,0x8B,0x5E,0x04,0x26,0x8A,0x47,0x59,0x25,0x03,0x00,0x8B,0xF0,0xD1,0xE6,0x2E,
280x8B,0xB4,0xC4,0x00,0xC1,0xE0,0x04,0x26,0x02,0x47,0x1A,0xD1,0xE0,0x8B,0xE8,0x2E,
290x8B,0xAE,0x44,0x00,0x89,0x2C,0x26,0x8A,0x47,0x1C,0x88,0x44,0x0F,0x26,0x8A,0x47,
300x1D,0x88,0x44,0x10,0x26,0x8A,0x47,0x1E,0x88,0x44,0x11,0x26,0x8A,0x47,0x1F,0x88,
310x44,0x12,0x26,0x8A,0x47,0x20,0x88,0x44,0x13,0x26,0x8A,0x47,0x23,0x88,0x44,0x14,
320x26,0x8A,0x47,0x24,0x88,0x44,0x15,0x26,0x8A,0x47,0x5A,0x88,0x44,0x0E,0x33,0xC0,
330x89,0x44,0x06,0x89,0x44,0x08,0x88,0x44,0x0B,0x88,0x44,0x0A,0xB0,0x21,0xB4,0x64,
340x89,0x44,0x04,0x89,0x44,0x02,0xB0,0x55,0x88,0x44,0x0D,0x88,0x44,0x0C,0xE8,0x6A,
350x00,0x72,0x5B,0xE8,0xC9,0x00,0xE8,0xC1,0x10,0x89,0x44,0x08,0x80,0x7C,0x0F,0x01,
360x74,0x29,0xE8,0x2B,0x02,0xE8,0x7F,0x02,0x80,0x7C,0x0F,0x03,0x74,0x1D,0xE8,0xA9,
370x10,0x8B,0xF8,0x2B,0x44,0x08,0x3D,0xA0,0x0F,0x72,0x10,0x89,0x7C,0x08,0x33,0xC0,
380x87,0x44,0x06,0x85,0xC0,0x75,0x04,0xC6,0x44,0x0A,0xFF,0x8A,0x44,0x0A,0x84,0xC0,
390x75,0x0B,0xB8,0x08,0x00,0xE8,0x6A,0x4A,0xE8,0xA9,0x01,0x73,0xBF,0xE8,0x4F,0x01,
400x81,0x66,0x48,0x7F,0xFF,0x83,0x66,0x7A,0xBF,0xB0,0x02,0xE8,0x04,0x0E,0x8A,0x44,
410x0A,0x98,0x07,0x1F,0x5F,0x5E,0x5A,0x59,0x5B,0x5D,0xC3,0x81,0x4E,0x48,0x80,0x00,
420xB0,0x40,0xE8,0x3D,0x4A,0xE8,0x89,0x40,0x73,0x2A,0xE8,0x4D,0x10,0x8B,0xD8,0xB0,
430x05,0xE8,0x2E,0x4A,0xF6,0x46,0x27,0x02,0x75,0x1A,0xE8,0x3D,0x10,0x2B,0xC3,0x3D,
440x58,0x1B,0x72,0xEB,0x81,0x66,0x48,0x7F,0xFF,0xB0,0x02,0xE8,0xC4,0x0D,0xC6,0x44,
450x0A,0x01,0xF9,0xC3,0x83,0x4E,0x7A,0x40,0xF8,0xC3,0xFB,0xB0,0x01,0xE8,0x02,0x4A,
460xFA,0xE8,0x99,0x1E,0xE4,0x0A,0x84,0xC0,0x75,0xF0,0xB0,0x4E,0xE6,0x0A,0xFB,0xB0,
470x01,0xE8,0xEE,0x49,0xFA,0xE8,0x85,0x1E,0xE4,0x0A,0x84,0xC0,0x75,0xF0,0xC3,0xFA,
480xE8,0x7A,0x1E,0xE4,0xEC,0x88,0x44,0x16,0xE4,0xE4,0x88,0x44,0x17,0xE4,0xF8,0x88,
490x44,0x18,0xE4,0xF0,0x88,0x44,0x19,0xE4,0x10,0x88,0x44,0x1A,0xE4,0x12,0x88,0x44,
500x1B,0xE4,0x14,0x88,0x44,0x1C,0xE4,0x34,0x88,0x44,0x1D,0xE4,0x36,0x88,0x44,0x1E,
510xE4,0xD8,0x24,0x01,0x8A,0xE0,0xE4,0xDA,0x24,0x02,0x0A,0xC4,0x88,0x44,0x1F,0x8A,
520x44,0x10,0xE8,0xCD,0x1F,0x8A,0x44,0x11,0xE8,0x35,0x21,0x8A,0x44,0x12,0xE8,0x89,
530x21,0x8A,0x44,0x13,0xE8,0x43,0x21,0xC6,0x86,0xA1,0x00,0x00,0xE4,0x14,0x24,0x10,
540xE6,0x14,0xE4,0x12,0x24,0x3D,0xE6,0x12,0x8A,0x44,0x15,0x3C,0x01,0x72,0x1E,0x77,
550x16,0xB0,0x11,0xE6,0x34,0xB0,0x13,0xE6,0x36,0xE4,0x14,0x0C,0x10,0xE6,0x14,0xE4,
560x12,0x0C,0x40,0xE6,0x12,0xEB,0x06,0xE4,0x12,0x0C,0x02,0xE6,0x12,0x8A,0x44,0x0F,
570x3C,0x01,0x74,0x06,0x3C,0x02,0x74,0x0A,0xEB,0x0E,0xE4,0x12,0x0C,0x08,0xE6,0x12,
580xEB,0x06,0xE4,0x12,0x0C,0x10,0xE6,0x12,0xE8,0x2F,0xFF,0x8A,0x44,0x14,0x3C,0x02,
590x75,0x08,0xB0,0x55,0x88,0x44,0x0C,0x88,0x44,0x0D,0xB0,0x21,0xB4,0x64,0x89,0x44,
600x04,0x89,0x44,0x02,0xE4,0x0C,0x0C,0x10,0xE6,0x0C,0xE8,0xED,0x39,0xFB,0xC3,0xE8,
610x5F,0x3F,0x73,0x08,0xFB,0xB0,0x0A,0xE8,0x08,0x49,0xEB,0xF3,0xFA,0xE8,0x9D,0x1D,
620x8A,0x64,0x16,0x8A,0x44,0x17,0x89,0x86,0x94,0x00,0xE6,0xE4,0x8A,0xC4,0xE6,0xEC,
630x8A,0x64,0x18,0x8A,0x44,0x19,0x89,0x86,0x96,0x00,0xE6,0xF0,0x8A,0xC4,0xE6,0xF8,
640x8A,0x44,0x1A,0xE6,0x10,0x8A,0x44,0x1B,0xE6,0x12,0x8A,0x44,0x1C,0xE6,0x14,0x8A,
650x44,0x1D,0xE6,0x34,0x8A,0x44,0x1E,0xE6,0x36,0x8A,0x44,0x1F,0xE6,0xD8,0xE6,0xDA,
660xE9,0xB7,0xFE,0x90,0xFA,0x8A,0x44,0x0E,0xE6,0xFE,0xE4,0x02,0xA8,0x01,0x75,0x05,
670x33,0xC0,0xFB,0xF8,0xC3,0x33,0xC0,0xE4,0x00,0xFB,0xF9,0xC3,0x8A,0x64,0x14,0x80,
680xFC,0x02,0x74,0x2B,0xFE,0xC0,0xFE,0xC7,0x80,0xFF,0x4E,0x72,0x1C,0x74,0x09,0x80,
690xFF,0x50,0x73,0x08,0xB0,0x0A,0xEB,0x17,0xB0,0x0D,0xEB,0x13,0x02,0xDC,0x32,0xFF,
700x80,0xFB,0x7F,0x7C,0x02,0xB3,0x21,0x8A,0xC3,0x3C,0x7F,0x7C,0x02,0xB0,0x21,0xC3,
710xFA,0x80,0x7C,0x0B,0x04,0x76,0x02,0xFB,0xC3,0x8B,0x46,0x24,0x3D,0x08,0x00,0x72,
720xF6,0x8E,0x46,0x02,0x8B,0x7E,0x22,0x8A,0x44,0x0C,0x8B,0x5C,0x02,0xAA,0xE8,0xAB,
730xFF,0xAA,0xE8,0xA7,0xFF,0xAA,0xE8,0xA3,0xFF,0xAA,0xE8,0x9F,0xFF,0x88,0x44,0x0C,
740x89,0x5C,0x02,0x80,0x44,0x0B,0x04,0x89,0x7E,0x22,0x83,0x6E,0x24,0x04,0x83,0x46,
750x1A,0x04,0x80,0x7E,0x26,0x02,0x74,0x06,0x80,0x66,0x26,0xFD,0xFB,0xC3,0x60,0xB0,
760xFD,0xE8,0x02,0x3F,0x61,0xFB,0xC3,0xFA,0x80,0x7C,0x0F,0x03,0x75,0x09,0xC6,0x44,
770x0B,0x00,0xE8,0xE5,0x38,0xFB,0xC3,0xC4,0x7E,0x14,0x8B,0x4E,0x3A,0x85,0xC9,0x75,
780x35,0x26,0x8B,0x0D,0x47,0x47,0xE3,0xEA,0x3B,0x7E,0x04,0x76,0x22,0xB8,0x02,0x00,
790x39,0x46,0x2E,0x77,0x07,0xC7,0x46,0x2E,0x00,0x00,0xEB,0x13,0x8B,0x5E,0x2C,0x89,
800x5E,0x04,0x26,0xC7,0x07,0x00,0x00,0x43,0x43,0x89,0x5E,0x2C,0x29,0x46,0x2E,0x85,
810xC9,0x78,0xCE,0x89,0x4E,0x3A,0x8A,0x44,0x0D,0x8B,0x5C,0x04,0x26,0x8A,0x25,0x47,
820x3A,0xC4,0x75,0x16,0xFE,0x4C,0x0B,0xFF,0x44,0x06,0xE8,0x0F,0xFF,0xE2,0xED,0x88,
830x44,0x0D,0x89,0x5C,0x04,0x89,0x4E,0x3A,0xEB,0xA7,0xC6,0x44,0x0A,0xFE,0xE8,0x79,
840x38,0xFB,0xC3,0x90,0xE8,0xB3,0x0D,0x8A,0xE8,0x8A,0x0E,0xCB,0x13,0xB3,0x07,0x8A,
850xC1,0xEE,0xEB,0x00,0xEC,0x3A,0xC1,0x75,0x09,0x02,0xCD,0xFE,0xCB,0x75,0xF0,0xEB,
860x0C,0x90,0x88,0x0E,0xCB,0x13,0x8A,0xE8,0xBB,0xFF,0xFF,0xF9,0xC3,0x88,0x0E,0xCB,
870x13,0xF8,0xC3,0x90,0xBB,0x3F,0x3F,0x8A,0x8E,0x9E,0x00,0xBA,0xFE,0x00,0xEC,0x8A,
880xE8,0x32,0xC1,0x22,0xC3,0x75,0x02,0xF8,0xC3,0xF9,0xC3,0x90,0xE8,0xE5,0xFF,0x73,
890x01,0xC3,0xBA,0xD0,0x00,0xBB,0x03,0x03,0x8A,0x8E,0x9F,0x00,0xEC,0x8A,0xE8,0x32,
900xC1,0x22,0xC3,0x75,0x02,0xF8,0xC3,0xF9,0xC3,0x90,0x33,0xC0,0x8E,0xD8,0x8E,0xC0,
910x80,0x3E,0xC8,0x13,0x00,0x75,0x07,0xB0,0x0A,0xE8,0x26,0x47,0xEB,0xF2,0xFB,0x33,
920xDB,0x8A,0x1E,0xC9,0x13,0x43,0x43,0x83,0xFB,0x7E,0x76,0x07,0x33,0xDB,0xB0,0x02,
930xE8,0x0F,0x47,0x2E,0x8B,0xAF,0x44,0x00,0x83,0x7E,0x08,0x00,0x74,0xE7,0x88,0x1E,
940xC9,0x13,0xB0,0x02,0xE8,0xFB,0x46,0xFA,0xF7,0x46,0x38,0x40,0x00,0x74,0x14,0xE8,
950x96,0x1B,0xE8,0x7F,0xFF,0x72,0x1C,0x33,0xD2,0x8A,0x96,0x9F,0x00,0x83,0xC2,0x0E,
960xEB,0x0C,0x90,0xE8,0x77,0x1B,0xE8,0x83,0xFF,0x72,0x08,0xBA,0x48,0x00,0xE8,0x33,
970xFF,0x73,0xAB,0x23,0xCB,0x89,0x8E,0x9A,0x00,0x89,0x96,0x9C,0x00,0xFE,0x86,0xB5,
980x00,0xC6,0x06,0xC8,0x13,0x00,0xB0,0x0A,0xE8,0x67,0x0A,0xFB,0xEB,0x89,0x10,0x18,
990x08,0x28,0x33,0xC0,0xA0,0x05,0x01,0x8A,0xC8,0x24,0x40,0x75,0x24,0xC7,0x06,0x7C,
1000x12,0x8E,0x45,0xC7,0x06,0x42,0x12,0x01,0x00,0xC6,0x06,0x54,0x12,0x02,0xB0,0x08,
1010xF6,0xC1,0x01,0x74,0x02,0xB0,0x04,0xA3,0x46,0x12,0xA2,0x4C,0x12,0xA2,0x94,0x12,
1020xC3,0xC7,0x06,0x7C,0x12,0xB6,0x45,0xA0,0x0F,0x01,0x84,0xC0,0x75,0x0E,0x6A,0x00,
1030x1F,0xC6,0x06,0x93,0x12,0x1E,0x9C,0x0E,0xE8,0xB1,0x0C,0x90,0xC7,0x06,0x44,0x12,
1040x01,0x00,0xA3,0x42,0x12,0x8B,0xD8,0xC1,0xE3,0x04,0x88,0x1E,0x94,0x12,0xBE,0xE2,
1050x05,0x2B,0xF0,0x8B,0xC8,0x33,0xDB,0x8B,0xFB,0x2E,0xAC,0x88,0x85,0x48,0x12,0x8A,
1060xD8,0x0C,0x05,0xE6,0xFE,0x8A,0xE0,0xEB,0x00,0xE4,0xFE,0x32,0xC4,0xA8,0x3F,0x74,
1070x03,0xE9,0x9E,0x00,0xE4,0x00,0x88,0x85,0x50,0x12,0x8A,0xE0,0x24,0x30,0xBA,0x10,
1080xFF,0x3C,0x30,0x74,0x12,0x80,0xFC,0x04,0x74,0x0A,0xBA,0x04,0x03,0xF6,0x06,0x08,
1090x01,0xFE,0x74,0x03,0xBA,0x08,0x0F,0x88,0x95,0x4C,0x12,0x02,0xFA,0x32,0xC0,0xF6,
1100xC4,0x08,0x74,0x02,0xB0,0x01,0x88,0x85,0x58,0x12,0x8A,0xC4,0x3C,0x35,0x74,0x5B,
1110x3C,0x36,0x74,0x57,0x3C,0x34,0x74,0x53,0x3C,0x04,0x74,0x4F,0x3C,0x14,0x74,0x4B,
1120x3C,0x15,0x74,0x47,0xA8,0x40,0x74,0x25,0xC6,0x85,0x54,0x12,0x04,0xD1,0xE7,0xB4,
1130x03,0x8A,0xC3,0x89,0x85,0x5C,0x12,0x8A,0xC3,0x8A,0xE3,0x80,0xCC,0x01,0x89,0x85,
1140x64,0x12,0xD1,0xEF,0x47,0xE2,0x03,0xEB,0x1A,0x90,0xE9,0x6C,0xFF,0xC6,0x85,0x54,
1150x12,0x02,0xD1,0xE7,0x8A,0xE6,0x8A,0xC3,0x0C,0x04,0x89,0x85,0x5C,0x12,0xD1,0xEF,
1160x47,0xE2,0xE7,0x33,0xC0,0x8A,0xC7,0xA3,0x46,0x12,0xC3,0xC6,0x85,0x54,0x12,0x06,
1170xEB,0xBB,0xC6,0x85,0x54,0x12,0x00,0x33,0xC0,0x88,0x85,0x50,0x12,0x88,0x85,0x4C,
1180x12,0x88,0x85,0x58,0x12,0xEB,0xA6,0xC7,0x46,0x26,0x02,0x12,0x8B,0x46,0x1E,0x89,
1190x46,0x00,0x89,0x46,0x22,0x8B,0x46,0x20,0x89,0x46,0x24,0xC7,0x46,0x1A,0x00,0x00,
1200xC3,0xC7,0x46,0x3C,0x80,0x00,0xC7,0x46,0x38,0x01,0x00,0x1E,0x56,0x8B,0x76,0x30,
1210x89,0x76,0x04,0x89,0x76,0x14,0x8E,0x5E,0x06,0x33,0xC0,0x89,0x04,0x46,0x46,0x89,
1220x76,0x2C,0x89,0x46,0x3A,0x8B,0x46,0x32,0x48,0x48,0x89,0x46,0x2E,0x5E,0x1F,0xC3,
1230x33,0xC0,0x89,0x46,0x48,0x89,0x46,0x4A,0xC7,0x46,0x46,0xAE,0x01,0x89,0x46,0x4E,
1240x8B,0x46,0x44,0x89,0x46,0x50,0x8B,0x46,0x42,0x89,0x46,0x40,0x89,0x46,0x08,0xC3,
1250x33,0xC0,0x89,0x46,0x76,0x89,0x46,0x78,0xC7,0x46,0x7A,0x10,0x00,0x56,0x1E,0x8B,
1260x76,0x70,0x89,0x76,0x10,0x89,0x76,0x0C,0x8E,0x5E,0x12,0xC7,0x04,0x00,0x00,0x8B,
1270x46,0x72,0x89,0x46,0x74,0x1F,0x5E,0xC3,0x89,0x56,0x18,0x89,0x56,0x02,0x89,0x56,
1280x06,0x89,0x56,0x0A,0x89,0x56,0x0E,0x89,0x56,0x12,0x89,0x56,0x16,0x8B,0xD8,0x4B,
1290x4B,0xC1,0xE3,0x02,0xBF,0x02,0x00,0x89,0x7E,0x1E,0x03,0xFB,0x89,0x7E,0x30,0x03,
1300xFB,0x89,0x7E,0x42,0x03,0xFB,0x89,0x7E,0x70,0x83,0xEB,0x08,0x89,0x5E,0x20,0x89,
1310x5E,0x32,0x89,0x5E,0x44,0x89,0x5E,0x72,0x50,0xE8,0x2B,0xFF,0xE8,0x71,0xFF,0xE8,
1320x3F,0xFF,0xE8,0x8B,0xFF,0x58,0xC3,0xB8,0x30,0x75,0xC1,0xE8,0x04,0x0E,0x5B,0x03,
1330xC3,0xA3,0xBA,0x13,0x83,0x3E,0x42,0x12,0x00,0x74,0x07,0x80,0x3E,0x94,0x12,0x00,
1340x75,0x0E,0x6A,0x00,0x1F,0xC6,0x06,0x93,0x12,0x1E,0x9C,0x0E,0xE8,0xBD,0x0A,0x90,
1350xB8,0x30,0x7A,0xC1,0xE8,0x04,0x40,0xA3,0xC0,0x13,0x2B,0x06,0x12,0x01,0xF7,0xD8,
1360x33,0xD2,0x8B,0xCA,0x8A,0x0E,0x94,0x12,0xF7,0xF1,0x3D,0x80,0x00,0x77,0x0E,0x6A,
1370x00,0x1F,0xC6,0x06,0x93,0x12,0x25,0x9C,0x0E,0xE8,0x90,0x0A,0x90,0x48,0x3D,0xFF,
1380x07,0x72,0x03,0xB8,0xFF,0x07,0xA3,0xC2,0x13,0x33,0xC9,0x8A,0x0E,0x94,0x12,0x33,
1390xF6,0xB8,0x00,0x09,0x2E,0x8B,0xAC,0x44,0x00,0x89,0x46,0x4C,0x40,0x46,0x46,0xE2,
1400xF3,0x8A,0x0E,0x94,0x12,0x33,0xF6,0x8B,0x16,0xC0,0x13,0xA1,0xC2,0x13,0x2E,0x8B,
1410xAC,0x44,0x00,0xE8,0x22,0xFF,0x03,0xD0,0x46,0x46,0xE2,0xF2,0xC3,0x33,0xC0,0x2E,
1420x8B,0xAD,0x44,0x00,0x89,0x46,0x08,0x47,0x47,0xE2,0xF4,0xC3,0x51,0x33,0xC0,0x0A,
1430xC2,0x2E,0x8B,0xAD,0x44,0x00,0x89,0x86,0x9E,0x00,0x81,0x4E,0x38,0x00,0x20,0x47,
1440x47,0xFE,0xC4,0x80,0xFC,0x04,0x72,0x04,0x32,0xE4,0xFE,0xC0,0xE2,0xE3,0x59,0x83,
1450xE9,0x10,0x74,0x05,0xF7,0xD9,0xE8,0xC4,0xFF,0xC3,0x51,0x33,0xC0,0x0A,0xC2,0x2E,
1460x8B,0xAD,0x44,0x00,0x89,0x86,0x9E,0x00,0x83,0x4E,0x38,0x40,0x47,0x47,0x80,0xC4,
1470x10,0x79,0x04,0x32,0xE4,0xFE,0xC0,0xE2,0xE6,0x59,0x83,0xE9,0x10,0x74,0x05,0xF7,
1480xD9,0xE8,0x99,0xFF,0xC3,0xE8,0xD2,0xFF,0xC3,0x8D,0x08,0x9C,0x08,0xCA,0x08,0xF5,
1490x08,0x8B,0x0E,0x42,0x12,0x33,0xF6,0x51,0x56,0x33,0xDB,0x8B,0xCB,0x8A,0x94,0x48,
1500x12,0x8A,0x8C,0x4C,0x12,0x8A,0x9C,0x54,0x12,0x8B,0xFE,0xC1,0xE7,0x05,0x85,0xDB,
1510x75,0x02,0xB1,0x10,0x2E,0xFF,0x97,0xF9,0x08,0x5E,0x59,0x46,0xE2,0xD9,0xC3,0x01,
1520xCC,0x03,0xD0,0x00,0xE8,0x02,0xD0,0x00,0xE8,0x01,0xD0,0x00,0xE8,0x00,0xD0,0x00,
1530xE8,0x04,0xD0,0xA8,0xDA,0x00,0xDC,0x00,0xDE,0x01,0xD8,0x03,0xCC,0x03,0xCC,0x03,
1540xCC,0x04,0xD0,0xA8,0xDA,0x20,0xDC,0x00,0xDE,0x03,0xCC,0x03,0xCC,0x03,0xCC,0x00,
1550xD8,0x03,0xCC,0x03,0xCC,0x03,0xCC,0x03,0xCC,0x03,0xCC,0x03,0xCC,0x03,0xCC,0x03,
1560xCC,0x03,0xCC,0x03,0xCC,0x03,0xCC,0x03,0xCC,0x03,0xCC,0x03,0xCC,0x03,0xCC,0x03,
1570xCC,0x04,0xD0,0x00,0xDA,0x20,0xDC,0x03,0xDE,0x01,0xD8,0x03,0xCC,0x03,0xCC,0x03,
1580xCC,0x03,0xCC,0x00,0xD8,0x00,0xCC,0x00,0xD0,0x00,0x00,0x56,0x52,0x1E,0x0E,0x1F,
1590xBE,0x2F,0x09,0x33,0xD2,0xFC,0xAD,0x85,0xC0,0x74,0x0D,0x8A,0xD4,0xEE,0xAD,0x85,
1600xC0,0x74,0x05,0x8A,0xD4,0xEE,0xEB,0xEE,0x1F,0x5A,0x5E,0xC3,0xE4,0x80,0x84,0xC0,
1610x74,0x16,0x78,0x14,0xB0,0x27,0xE6,0xFC,0xB0,0x11,0xE6,0x34,0xE4,0xFC,0x3C,0x27,
1620x75,0x06,0xE4,0x11,0x75,0x02,0xF8,0xC3,0xF9,0xC3,0x83,0xC2,0x06,0xB0,0xBF,0xEE,
1630x83,0xEA,0x02,0xB0,0x10,0xEE,0x88,0x86,0xAF,0x00,0xB0,0x11,0x83,0xC2,0x04,0xEE,
1640x83,0xC2,0x02,0xEE,0xB0,0x13,0x83,0xC2,0x02,0xEE,0x83,0xC2,0x02,0xEE,0x2E,0xA1,
1650x4C,0x2D,0x89,0x86,0x94,0x00,0x83,0xEA,0x0E,0xEE,0x83,0xC2,0x02,0x8A,0xC4,0xEE,
1660x83,0xC2,0x04,0xB0,0x03,0xEE,0x88,0x86,0xA8,0x00,0x83,0xEA,0x04,0x32,0xC0,0xEE,
1670x83,0xC2,0x02,0xB0,0x89,0xEE,0x88,0x86,0xA6,0x00,0x0C,0x06,0xEE,0xB0,0x40,0xB4,
1680x38,0x89,0x46,0x1C,0xC7,0x46,0x36,0x38,0x00,0x83,0xC2,0x04,0x32,0xC0,0xEE,0x88,
1690x86,0xA7,0x00,0xC3,0x83,0xC2,0x06,0xB0,0xBF,0xEE,0x83,0xEA,0x02,0xEC,0x3A,0x86,
1700xAF,0x00,0x75,0x24,0x83,0xC2,0x04,0xEC,0x3C,0x11,0x75,0x1C,0x83,0xC2,0x06,0xEC,
1710x3C,0x13,0x75,0x14,0x83,0xEA,0x08,0x8A,0x86,0xA8,0x00,0xEE,0x83,0xEA,0x02,0xEC,
1720x24,0xC0,0x3C,0xC0,0x75,0x02,0xF8,0xC3,0xF9,0xC3,0x33,0xC9,0x8B,0xD1,0x8B,0xF1,
1730x8A,0x0E,0x94,0x12,0xC1,0xE9,0x02,0x2E,0x8B,0xAC,0x44,0x00,0xF7,0x46,0x38,0x00,
1740x20,0x74,0x0E,0x8A,0x86,0x9E,0x00,0xE6,0xFE,0x32,0xC0,0xE6,0x80,0x42,0xE8,0xFA,
1750xFE,0x83,0xC6,0x08,0xE2,0xE1,0x85,0xD2,0x74,0x03,0xE8,0x05,0x08,0xC3,0x33,0xC9,
1760x8B,0xF1,0x8A,0x0E,0x94,0x12,0x2E,0x8B,0xAC,0x44,0x00,0xF7,0x46,0x38,0x40,0x00,
1770x74,0x06,0xE8,0x73,0x16,0xE8,0x12,0xFF,0x46,0x46,0xE2,0xEA,0xC3,0x33,0xC9,0x8B,
1780xF1,0x8A,0x0E,0x94,0x12,0xC1,0xE9,0x02,0x2E,0x8B,0xAC,0x44,0x00,0xF7,0x46,0x38,
1790x00,0x20,0x74,0x16,0xE8,0x46,0x16,0xE8,0xD2,0xFE,0x73,0x0E,0x6A,0x00,0x1F,0xC6,
1800x06,0x93,0x12,0x1C,0x9C,0x0E,0xE8,0xE3,0x07,0x90,0x83,0xC6,0x08,0xE2,0xD9,0xC3,
1810x33,0xC9,0x8B,0xF1,0x8A,0x0E,0x94,0x12,0x2E,0x8B,0xAC,0x44,0x00,0xF7,0x46,0x38,
1820x40,0x00,0x74,0x16,0xE8,0x21,0x16,0xE8,0x2A,0xFF,0x73,0x0E,0x6A,0x00,0x1F,0xC6,
1830x06,0x93,0x12,0x1C,0x9C,0x0E,0xE8,0xB3,0x07,0x90,0x46,0x46,0xE2,0xDA,0xC3,0x0C,
1840x00,0x00,0x10,0x00,0x13,0x12,0x00,0x00,0x14,0x00,0x28,0x3C,0x00,0x1B,0x3E,0x00,
1850x00,0x2A,0x00,0x00,0x2C,0x00,0x00,0x42,0x00,0x14,0xD8,0x00,0x00,0xDA,0x00,0x00,
1860x34,0x00,0x11,0x36,0x00,0x13,0x38,0x00,0x11,0x3A,0x00,0x13,0x00,0x00,0x56,0x50,
1870x52,0xBE,0x2F,0x0B,0x2E,0xAD,0x85,0xC0,0x74,0x06,0x92,0x2E,0xAC,0xEE,0xEB,0xF4,
1880x5A,0x58,0x5E,0xC3,0x53,0x2E,0xA1,0x60,0x22,0xE6,0xE4,0xE6,0xF0,0x8A,0xC4,0xE6,
1890xEC,0xE6,0xF8,0xE8,0xD8,0xFF,0xB0,0x4B,0xE6,0x10,0xB0,0x50,0xE6,0x12,0xB0,0x38,
1900xE6,0x14,0xE8,0xAE,0x15,0xB0,0x46,0xE6,0x0A,0xE8,0xA7,0x15,0xB0,0x1A,0xE6,0x0A,
1910xE8,0xA0,0x15,0xB0,0x22,0xE6,0x0A,0xE8,0x99,0x15,0xE8,0xFD,0x06,0x8B,0xD8,0xE4,
1920x16,0xA8,0x04,0x75,0x18,0xE8,0xF2,0x06,0x2B,0xC3,0x3D,0x32,0x00,0x72,0xF0,0x6A,
1930x00,0x1F,0xC6,0x06,0x93,0x12,0x23,0x9C,0x0E,0xE8,0x10,0x07,0x90,0xE8,0xDA,0x06,
1940x2B,0xC3,0x3D,0x24,0x00,0x77,0x1B,0xB0,0x31,0xE6,0xFC,0x56,0x51,0x55,0xB9,0x10,
1950x00,0x2E,0x8B,0xAC,0x44,0x00,0x81,0x4E,0x38,0x80,0x00,0x46,0x46,0xE2,0xF2,0x5D,
1960x59,0x5E,0xE8,0x69,0xFF,0xE8,0x4B,0x15,0xB0,0x46,0xE6,0x0A,0xE8,0x44,0x15,0x5B,
1970xC3,0x33,0xF6,0x8B,0x0E,0x42,0x12,0x2E,0x8B,0xAC,0x44,0x00,0xF7,0x46,0x38,0x00,
1980x20,0x74,0x06,0xE8,0x17,0x15,0xE8,0x5B,0xFF,0x83,0xC6,0x20,0xE2,0xE9,0xC3,0x8B,
1990xC2,0x05,0x04,0x00,0x89,0x46,0x28,0x2E,0xA1,0x4C,0x2D,0x89,0x86,0x8E,0x00,0x89,
2000x86,0x90,0x00,0x89,0x86,0x92,0x00,0xC6,0x86,0xA3,0x00,0x0A,0xC6,0x86,0xC3,0x00,
2010x03,0x52,0x83,0xC2,0x04,0x8A,0x86,0xA6,0x00,0x0C,0x06,0xEE,0x5A,0x83,0xC2,0x02,
2020xB0,0x05,0xEE,0x88,0x86,0xA5,0x00,0xC3,0xE8,0x03,0xFF,0xE8,0xE5,0x14,0xB0,0x42,
2030xE6,0x0A,0xF7,0x46,0x38,0x80,0x00,0x74,0x06,0x2E,0xA1,0x9C,0x22,0xEB,0x04,0x2E,
2040xA1,0x6C,0x22,0xC7,0x46,0x1C,0x0C,0x00,0x89,0x86,0x94,0x00,0x89,0x86,0x96,0x00,
2050x89,0x86,0x8E,0x00,0x89,0x86,0x90,0x00,0x89,0x86,0x92,0x00,0xE6,0xF0,0xE6,0xE4,
2060x8A,0xC4,0xE6,0xF8,0xE6,0xEC,0xC6,0x86,0xC3,0x00,0x03,0xE8,0xA5,0x14,0xB0,0x1A,
2070xE6,0x0A,0xB0,0x10,0x88,0x86,0xA5,0x00,0xE6,0x0C,0xC3,0x33,0xC9,0x8B,0xF1,0x8A,
2080x0E,0x94,0x12,0x2E,0x8B,0xAC,0x44,0x00,0xF7,0x46,0x38,0x40,0x00,0x74,0x06,0xE8,
2090x76,0x14,0xE8,0x5A,0xFF,0x46,0x46,0xE2,0xEA,0xC3,0x33,0xC9,0x8B,0xF1,0x8A,0x0E,
2100x94,0x12,0x2E,0x8B,0xAC,0x44,0x00,0xF7,0x46,0x38,0x00,0x20,0x74,0x06,0xE8,0x4C,
2110x14,0xE8,0x74,0xFF,0x46,0x46,0xE2,0xEA,0xC3,0x90,0x83,0x3E,0x44,0x12,0x00,0x75,
2120x14,0xB0,0x01,0xBA,0x06,0x01,0xEE,0x2A,0xC0,0xEE,0xB0,0x02,0xEE,0xB0,0x04,0xEE,
2130xB8,0x00,0x02,0xEB,0x0F,0xBA,0x06,0x01,0xB0,0x40,0xEE,0xB8,0x01,0x00,0x8A,0x0E,
2140x0E,0x01,0xD3,0xE0,0xA3,0x88,0x12,0xC3,0xA1,0x88,0x12,0xA3,0x84,0x12,0x2D,0x20,
2150x00,0xA3,0x8A,0x12,0x2D,0x20,0x00,0xA3,0x82,0x12,0xC7,0x06,0x86,0x12,0x20,0x00,
2160xC7,0x06,0x80,0x12,0x32,0x00,0xC3,0x83,0x3E,0x44,0x12,0x00,0x74,0x76,0x8B,0x0E,
2170x42,0x12,0x33,0xF6,0x8A,0xA4,0x54,0x12,0x84,0xE4,0x74,0x5F,0x8A,0x84,0x48,0x12,
2180x0C,0x04,0xE6,0xFE,0xF6,0xC4,0x04,0x74,0x25,0xB0,0x1B,0xBA,0x00,0x00,0xEE,0xEB,
2190x00,0x2A,0xC0,0xBA,0x02,0x00,0xEE,0xEB,0x00,0xB0,0x03,0xEE,0xEB,0x00,0x32,0xC0,
2200xBA,0x02,0x00,0xEE,0xEB,0x00,0xBA,0x00,0x00,0xB0,0x00,0xEE,0xEB,0x2D,0xB0,0x1F,
2210xBA,0x00,0x00,0xEE,0xEB,0x00,0x2A,0xC0,0xBA,0x02,0x00,0xEE,0xEB,0x00,0xB0,0x03,
2220xEE,0xEB,0x00,0xD1,0xE6,0x8A,0x84,0x5D,0x12,0xD1,0xEE,0xF6,0xD0,0xBA,0x02,0x00,
2230xEE,0xEB,0x00,0xBA,0x00,0x00,0xB0,0x0A,0xEE,0xEB,0x00,0xE4,0x04,0xEB,0x00,0xE4,
2240x04,0x46,0xE2,0x90,0xC3,0x90,0xB8,0x14,0x00,0xBA,0x3E,0xFF,0xEF,0xB8,0x06,0x00,
2250xBA,0x32,0xFF,0xEF,0xB8,0x0F,0x00,0xBA,0x34,0xFF,0xEF,0xBA,0x36,0xFF,0xEF,0x83,
2260x3E,0x44,0x12,0x00,0x75,0x16,0xB8,0x11,0x00,0xBA,0x38,0xFF,0xEF,0xB8,0x12,0x00,
2270xBA,0x3A,0xFF,0xEF,0xB8,0x1B,0x00,0xBA,0x3C,0xFF,0xEF,0xC3,0xB8,0x11,0x00,0xBA,
2280x38,0xFF,0xEF,0xB8,0x12,0x00,0xBA,0x3A,0xFF,0xEF,0xB8,0x1B,0x00,0xBA,0x3C,0xFF,
2290xEF,0xC3,0xB8,0xFC,0x00,0xBA,0x28,0xFF,0xEF,0xFB,0x83,0x3E,0x44,0x12,0x00,0x74,
2300x07,0xB8,0xCC,0x00,0xBA,0x28,0xFF,0xEF,0xC3,0x00,0xFF,0xFF,0x20,0x24,0x28,0xFF,
2310x2C,0xFF,0xFF,0x30,0x34,0x38,0xFF,0xFF,0x3C,0x90,0x3C,0x0F,0x77,0x0E,0xBB,0x19,
2320x0E,0x2E,0xD7,0x3C,0xFF,0x74,0x05,0x8A,0xD8,0xF8,0xC3,0x90,0x2A,0xDB,0xF9,0xC3,
2330x83,0x3E,0x44,0x12,0x00,0x74,0x27,0xA0,0x06,0x01,0x80,0x26,0x06,0x01,0x30,0x80,
2340x3E,0x06,0x01,0x30,0x75,0x18,0xB9,0x02,0x00,0xBF,0xC4,0x13,0xBA,0x06,0x01,0xEC,
2350xA8,0x20,0x75,0xF8,0xBA,0x04,0x01,0xED,0xAB,0xE2,0xF1,0xEB,0x16,0x90,0xB9,0x04,
2360x00,0xBF,0xC4,0x13,0xBA,0x06,0x01,0xEC,0xA8,0x20,0x75,0xF8,0xBA,0x04,0x01,0xEC,
2370xAA,0xE2,0xF1,0xFA,0x90,0xBE,0xC4,0x13,0xAD,0x80,0xE4,0x3F,0x80,0xFC,0x02,0x74,
2380x0E,0x6A,0x00,0x1F,0xC6,0x06,0x93,0x12,0x0A,0x9C,0x0E,0xE8,0x3E,0x04,0x90,0xAD,
2390x3C,0x0F,0x75,0xED,0x8A,0xC4,0xE8,0x81,0xFF,0x72,0xE6,0x88,0x1E,0x1A,0x01,0xC6,
2400x06,0x8E,0x12,0x00,0xB0,0x00,0x0A,0x06,0x1A,0x01,0xBA,0x00,0x01,0xEE,0xC6,0x06,
2410x8F,0x12,0x40,0x83,0x3E,0x44,0x12,0x00,0x75,0x06,0xB8,0x0C,0x00,0xEB,0x04,0x90,
2420xB8,0x4C,0x00,0xBA,0x28,0xFF,0xEF,0xC3,0x83,0x3E,0x44,0x12,0x00,0x75,0x01,0xC3,
2430xA1,0x50,0x12,0x0B,0x06,0x52,0x12,0x0A,0xC4,0xA8,0x08,0x74,0xF2,0xA0,0x0F,0x01,
2440x2A,0xE4,0x50,0xFF,0x36,0xBA,0x13,0x1F,0xE8,0x50,0x56,0x83,0xC4,0x02,0x6A,0x00,
2450x1F,0x33,0xC0,0xA3,0xBC,0x13,0xA0,0x0F,0x01,0xA3,0xBE,0x13,0x8B,0x1E,0xBC,0x13,
2460x8A,0x87,0x50,0x12,0xF6,0x87,0x50,0x12,0x08,0x74,0x0D,0x24,0x07,0x8A,0xE0,0xBE,
2470xCC,0x00,0xA0,0xBC,0x13,0xE8,0x94,0x3D,0xFF,0x06,0xBC,0x13,0xFF,0x0E,0xBE,0x13,
2480x75,0xDA,0xC3,0x90,0x1E,0x33,0xC0,0x8E,0xD8,0xB0,0x01,0xE8,0x54,0x3D,0x1F,0xC3,
2490x33,0xC9,0x8B,0xF1,0x8A,0x0E,0x94,0x12,0x2E,0x8B,0xAC,0x44,0x00,0xC7,0x46,0x62,
2500x38,0x44,0xC7,0x46,0x7C,0xFC,0x3B,0xC7,0x46,0x7E,0xE2,0x3B,0xC7,0x86,0x80,0x00,
2510xEC,0x3C,0xE8,0xAB,0x16,0xC6,0x86,0xC0,0x00,0x11,0x83,0x7E,0x08,0x00,0x74,0x07,
2520x51,0x56,0xE8,0x33,0x33,0x5E,0x59,0x46,0x46,0xE2,0xCD,0xC3,0x33,0xC9,0x8B,0xF1,
2530x8B,0xF9,0x8A,0x0E,0x94,0x12,0xC1,0xE9,0x02,0xE3,0x13,0x2E,0x8B,0xAC,0x44,0x00,
2540x8A,0x86,0x9E,0x00,0x88,0x85,0x6C,0x12,0x83,0xC6,0x08,0x47,0xE2,0xED,0xC3,0xFA,
2550xFC,0xB0,0xC0,0xBA,0x00,0x01,0xEE,0x33,0xC0,0x8E,0xD8,0x8E,0xC0,0x8E,0xD0,0xBF,
2560x16,0x01,0xB9,0xCC,0x77,0x2B,0xCF,0xD1,0xE9,0xF3,0xAB,0xBC,0x40,0x12,0xE8,0xD9,
2570x02,0xE8,0x70,0x3C,0xBE,0xCC,0x0F,0xE8,0xF2,0x3C,0xF4,0x90,0x33,0xC0,0x8E,0xD8,
2580x8E,0xC0,0x8E,0xD0,0xF6,0x06,0x0A,0x01,0x80,0x74,0x0B,0xBE,0x35,0x55,0xE8,0xDB,
2590x3C,0xB0,0x01,0xE8,0xAC,0x3C,0xE8,0xB3,0x00,0xE8,0xF6,0xF5,0xE8,0x08,0xF8,0xE8,
2600x0F,0xF9,0xE8,0x85,0xFA,0xE8,0xB6,0xFA,0xE8,0xEF,0xFC,0xE8,0xC2,0x10,0xE8,0x03,
2610x3C,0xE8,0xB2,0xFD,0xE8,0x30,0xFD,0xE8,0x54,0x02,0xC6,0x06,0x8F,0x12,0xC0,0xE8,
2620xBB,0xFA,0xE8,0xEB,0xFA,0xE8,0xE9,0xFB,0xE8,0xAF,0xFC,0xE8,0x8D,0xFC,0xE8,0x1F,
2630xFF,0xE8,0x58,0xFF,0xE8,0xDB,0xFD,0xE8,0x16,0xFE,0x33,0xC0,0xBE,0x5A,0x05,0xE8,
2640x8A,0x3C,0xE8,0xA3,0xFE,0xE8,0xE0,0xFC,0xFB,0xBE,0xA4,0x44,0xE8,0x7D,0x3C,0xE9,
2650xCA,0x2D,0x56,0x98,0x8B,0xF0,0x8B,0x42,0x52,0x85,0xC0,0x75,0x27,0xC7,0x42,0x52,
2660x01,0x00,0x53,0x36,0x8B,0x9C,0x2C,0x01,0xF6,0xC3,0x01,0x75,0x0C,0x36,0x89,0x68,
2670x52,0x36,0x89,0xAC,0x2C,0x01,0x5B,0x5E,0xC3,0x36,0x89,0xAC,0x2C,0x01,0x36,0x89,
2680xAC,0x1C,0x01,0x5B,0x5E,0xC3,0x56,0x98,0x8B,0xF0,0x33,0xED,0x36,0x8B,0x84,0x1C,
2690x01,0xA8,0x01,0x75,0x15,0x8B,0xE8,0x33,0xC0,0x87,0x42,0x52,0x36,0x89,0x84,0x1C,
2700x01,0xA8,0x01,0x74,0x05,0x36,0x89,0x84,0x2C,0x01,0x5E,0xC3,0x56,0x51,0x33,0xF6,
2710xB8,0x01,0x00,0xB9,0x08,0x00,0x89,0x84,0x1C,0x01,0x89,0x84,0x2C,0x01,0x46,0x46,
2720xE2,0xF4,0x59,0x5E,0xC3,0x90,0xBB,0x01,0x00,0x8B,0xE8,0xFF,0x4E,0x6E,0x74,0x0A,
2730x8B,0xDD,0x8B,0x46,0x58,0xA8,0x01,0x74,0xF0,0xC3,0x8B,0x46,0x48,0xA9,0x08,0x00,
2740x74,0x45,0xF7,0x46,0x38,0x40,0x00,0x74,0x27,0xE8,0x5C,0x10,0x80,0xC2,0x06,0x8A,
2750x86,0xA8,0x00,0x24,0xBF,0x88,0x86,0xA8,0x00,0xEE,0x60,0xB0,0xFE,0xE8,0x86,0x32,
2760x61,0xB0,0x02,0xE8,0x4C,0xFF,0x8B,0x46,0x48,0x24,0xF7,0x89,0x46,0x48,0xEB,0x17,
2770xE8,0x2A,0x10,0x81,0x4E,0x26,0x00,0x40,0x8A,0x86,0xA5,0x00,0x0C,0x02,0x88,0x86,
2780xA5,0x00,0xE6,0x0C,0x8B,0x46,0x48,0xA9,0x04,0x00,0x74,0x14,0xB0,0x02,0xE8,0x21,
2790xFF,0x8B,0x46,0x48,0x24,0xFB,0x89,0x46,0x48,0x60,0xB0,0xDF,0xE8,0x47,0x32,0x61,
2800x33,0xC0,0x87,0x46,0x58,0xF6,0xC3,0x01,0x75,0x0B,0x36,0x89,0x47,0x58,0xA8,0x01,
2810x75,0x0D,0xE9,0x74,0xFF,0xA3,0x22,0x01,0xA8,0x01,0x75,0x03,0xE9,0x6A,0xFF,0x89,
2820x1E,0x32,0x01,0xC3,0xBB,0x01,0x00,0x8B,0xE8,0xF7,0x46,0x38,0x40,0x00,0x74,0x15,
2830xE8,0xD5,0x0F,0x80,0xC2,0x0A,0xEC,0xA8,0x40,0x75,0x0A,0x8B,0xDD,0x8B,0x46,0x56,
2840xA8,0x01,0x74,0xE3,0xC3,0x8B,0x46,0x26,0x80,0xE4,0xFE,0x80,0xCC,0x02,0x89,0x46,
2850x26,0xB0,0x02,0xE8,0xBC,0xFE,0x33,0xC0,0x87,0x46,0x56,0xF6,0xC3,0x01,0x75,0x0A,
2860x36,0x89,0x47,0x56,0xA8,0x01,0x75,0x0B,0xEB,0xBD,0xA3,0x20,0x01,0xA8,0x01,0x75,
2870x02,0xEB,0xB4,0x89,0x1E,0x30,0x01,0xC3,0x60,0x1E,0x06,0x2B,0xC0,0x8E,0xD8,0xA0,
2880x90,0x12,0x84,0xC0,0x75,0x49,0xA1,0x22,0x01,0xA8,0x01,0x75,0x03,0xE8,0xF6,0xFE,
2890xA1,0x20,0x01,0xA8,0x01,0x75,0x03,0xE8,0x8A,0xFF,0xA1,0xAC,0x13,0x48,0x78,0x05,
2900x74,0x45,0xA3,0xAC,0x13,0xA1,0xAE,0x13,0x48,0x78,0x05,0x74,0x51,0xA3,0xAE,0x13,
2910xA1,0xB0,0x13,0x48,0x78,0x05,0x74,0x63,0xA3,0xB0,0x13,0xA1,0x7E,0x12,0x40,0x78,
2920x03,0xA3,0x7E,0x12,0xB8,0x00,0x80,0xBA,0x22,0xFF,0xEF,0x07,0x1F,0x61,0xCF,0xA0,
2930x91,0x12,0x40,0x3C,0x02,0x72,0x0B,0x33,0xC0,0xA2,0x91,0x12,0xFF,0x16,0x7C,0x12,
2940xEB,0xA4,0xA2,0x91,0x12,0xEB,0x9F,0xA0,0x8E,0x12,0x32,0x06,0x8F,0x12,0xA2,0x8E,
2950x12,0x0A,0x06,0x1A,0x01,0xBA,0x00,0x01,0xEE,0xB8,0x2C,0x01,0xEB,0xA4,0x83,0x3E,
2960x84,0x12,0x10,0x72,0x11,0xBA,0x28,0xFF,0xED,0x0C,0x81,0xEF,0xE8,0x53,0x37,0xBA,
2970x28,0xFF,0xED,0x24,0x7E,0xEF,0xB8,0x04,0x00,0xEB,0x92,0xC6,0x06,0x8D,0x12,0x01,
2980xE8,0x3F,0x37,0xC6,0x06,0x8D,0x12,0x00,0xA1,0xB2,0x13,0xEB,0x8B,0x90,0x8A,0x1E,
2990x0B,0x01,0x2A,0xFF,0x6B,0xC3,0x19,0xBA,0x62,0xFF,0xEF,0xB8,0x0A,0x00,0xBA,0x60,
3000xFF,0xEF,0xB8,0x01,0xE0,0xBA,0x66,0xFF,0xEF,0xB8,0xFF,0xFF,0xBA,0x52,0xFF,0xEF,
3010xB8,0x09,0xC0,0xBA,0x56,0xFF,0xEF,0xC7,0x06,0xAC,0x13,0x2C,0x01,0xC7,0x06,0xAE,
3020x13,0x04,0x00,0xC6,0x06,0x91,0x12,0x00,0xC3,0x90,0x8A,0x1E,0x0B,0x01,0x2A,0xFF,
3030x6B,0xC3,0x05,0xD1,0xE8,0xA3,0x18,0x01,0xC3,0x90,0x52,0xBA,0x50,0xFF,0xED,0x5A,
3040xC3,0x90,0x53,0x51,0x8B,0x1E,0x18,0x01,0xB9,0x32,0x05,0x90,0xE2,0xFE,0x4B,0x75,
3050xF7,0x59,0x5B,0xC3,0xB0,0x80,0xBA,0x00,0x01,0x0A,0x06,0x1A,0x01,0xEE,0xC3,0x90,
3060xB0,0x40,0xEB,0xF2,0xB0,0xC0,0xEB,0xEE,0xB0,0x00,0xEB,0xEA,0xFA,0x60,0x06,0x1E,
3070x16,0x2B,0xDB,0x8E,0xDB,0x2E,0xA1,0xBA,0x4C,0x2E,0xA3,0x92,0x4C,0xA0,0x93,0x12,
3080x98,0x8B,0xE8,0x89,0x26,0x2D,0x7A,0x80,0x3E,0xCA,0x13,0x00,0x74,0x03,0xE9,0x6B,
3090x42,0xE8,0xC0,0xFF,0xE8,0xAB,0xFF,0xE8,0xA8,0xFF,0xB0,0x20,0xC6,0x06,0x90,0x12,
3100x00,0xFF,0x16,0x7C,0x12,0x8B,0xFD,0x83,0xFF,0x0A,0x72,0x11,0xE8,0xB9,0xFF,0xE8,
3110x90,0xFF,0xE8,0xAB,0xFF,0xE8,0x8A,0xFF,0x83,0xEF,0x0A,0xEB,0xEA,0x0B,0xFF,0x74,
3120x0F,0xE8,0xA4,0xFF,0xE8,0x7B,0xFF,0xE8,0x9A,0xFF,0xE8,0x75,0xFF,0x4F,0x75,0xF1,
3130xE8,0x95,0xFF,0xE8,0x6C,0xFF,0xEB,0xB9,0x8A,0x86,0xA5,0x00,0x24,0xFD,0xEE,0x88,
3140x86,0xA5,0x00,0xC3,0x8A,0x86,0xA6,0x00,0x0C,0x02,0xEE,0xC3,0x8B,0x76,0x38,0xF7,
3150xC6,0x01,0x00,0x74,0xEF,0x8B,0x4E,0x36,0x8B,0x46,0x2E,0x3B,0xC1,0x73,0x02,0x8B,
3160xC8,0x2B,0xC1,0x89,0x46,0x2E,0x01,0x4E,0x34,0xC4,0x7E,0x04,0x26,0x01,0x0D,0x8B,
3170x7E,0x2C,0x83,0xEA,0x04,0xF3,0x6C,0x8E,0xC1,0x89,0x7E,0x2C,0x3B,0x46,0x3C,0x72,
3180x12,0xF7,0xC6,0x20,0x00,0x75,0x0B,0x83,0xCE,0x20,0x89,0x76,0x38,0xB0,0x00,0xE8,
3190xA0,0xFC,0xC3,0xF7,0xC6,0x04,0x00,0x74,0x1B,0x8B,0xD8,0x83,0xCE,0x10,0x89,0x76,
3200x38,0x8A,0x86,0xA7,0x00,0x24,0xFE,0x88,0x86,0xA7,0x00,0x83,0xC2,0x08,0xEE,0x83,
3210xEA,0x08,0x8B,0xC3,0x3D,0x40,0x00,0x72,0x01,0xC3,0x81,0x4E,0x38,0x00,0x04,0x83,
3220xC2,0x02,0x8A,0x86,0xA5,0x00,0x24,0xFA,0x88,0x86,0xA5,0x00,0xEE,0xC3,0x8A,0x86,
3230xA6,0x00,0x0C,0x02,0xEE,0xC3,0xF7,0x46,0x38,0x01,0x00,0x74,0xF1,0x8B,0x4E,0x2E,
3240x32,0xDB,0x8A,0xBE,0xA3,0x00,0x83,0xC2,0x06,0xC4,0x76,0x04,0x8B,0x7E,0x2C,0x83,
3250xF9,0x08,0x72,0x2C,0xEC,0xA8,0x01,0x74,0x16,0x8A,0xE0,0x83,0xEA,0x0A,0xEC,0x83,
3260xC2,0x0A,0x84,0xE7,0x75,0x51,0xAA,0xFE,0xC3,0x49,0x83,0xF9,0x08,0x73,0xE5,0x32,
3270xFF,0x26,0x01,0x1C,0x01,0x5E,0x34,0x89,0x76,0x04,0x89,0x4E,0x2E,0x89,0x7E,0x2C,
3280x3B,0x4E,0x3C,0x72,0x11,0xF6,0x46,0x38,0x20,0x74,0x01,0xC3,0x83,0x4E,0x38,0x20,
3290xB0,0x00,0xE8,0xFD,0xFB,0xC3,0xF6,0x46,0x38,0x04,0x74,0x15,0x83,0x4E,0x38,0x10,
3300x8A,0x86,0xA7,0x00,0x24,0xFE,0x88,0x86,0xA7,0x00,0x83,0xEA,0x02,0xEE,0x83,0xC2,
3310x02,0x3D,0x40,0x00,0x72,0x5D,0xC3,0x32,0xFF,0x26,0x03,0x1C,0x85,0xDB,0x74,0x09,
3320x26,0x89,0x1C,0x8B,0xF7,0x47,0x47,0x49,0x49,0x80,0xE4,0x1E,0x80,0xCC,0xC0,0x26,
3330x89,0x04,0xF6,0xC4,0x10,0x74,0x27,0x8B,0x76,0x38,0xF7,0xC6,0x00,0x10,0x74,0x0B,
3340x50,0xFE,0x86,0xB2,0x00,0xB0,0x0A,0xE8,0xA8,0xFB,0x58,0xF7,0xC6,0x00,0x01,0x74,
3350x0D,0xE8,0x82,0x26,0x8B,0x76,0x38,0x8B,0x4E,0x2E,0x8B,0x7E,0x04,0xAB,0x8B,0xF7,
3360x33,0xC0,0xAB,0x32,0xDB,0x8A,0xBE,0xA3,0x00,0x49,0x49,0x83,0xF9,0x08,0x72,0x17,
3370xE9,0x41,0xFF,0x81,0x4E,0x38,0x00,0x04,0x83,0xC2,0xF8,0x8A,0x86,0xA5,0x00,0x24,
3380xFA,0x88,0x86,0xA5,0x00,0xEE,0xC3,0xE9,0x45,0xFF,0x83,0xC2,0x08,0xEC,0x88,0x86,
3390xAA,0x00,0xC0,0xE8,0x04,0x8A,0xE0,0x8A,0xC8,0x86,0x86,0xA9,0x00,0x32,0xE0,0x8B,
3400x5E,0x3E,0x84,0xE3,0x74,0x4F,0x8A,0xC1,0x8B,0x4E,0x26,0xF6,0xC5,0x04,0x74,0x0C,
3410xA8,0x08,0x74,0x05,0x80,0xE1,0xBF,0xEB,0x03,0x80,0xC9,0x40,0xF6,0xC5,0x08,0x74,
3420x0C,0xA8,0x02,0x74,0x05,0x80,0xE1,0x7F,0xEB,0x03,0x80,0xC9,0x80,0x88,0x4E,0x26,
3430x8B,0xF0,0x8A,0x86,0xA5,0x00,0x84,0xC9,0x74,0x08,0xA8,0x02,0x74,0x15,0x24,0xFD,
3440xEB,0x06,0xA8,0x02,0x75,0x0D,0x0C,0x02,0x88,0x86,0xA5,0x00,0x83,0xEA,0x0A,0xEE,
3450x83,0xC2,0x0A,0x8B,0xC6,0x84,0xE7,0x75,0x01,0xC3,0xC6,0x86,0xBA,0x00,0x01,0xB0,
3460x0E,0xE8,0xEE,0xFA,0xF7,0x46,0x38,0x00,0x02,0x74,0xEE,0x83,0x7E,0x2E,0x06,0x72,
3470xE8,0x8A,0xA6,0xAA,0x00,0xC4,0x5E,0x04,0x8B,0x7E,0x2C,0xB0,0xFF,0xAA,0xB0,0x02,
3480xAB,0x26,0x83,0x07,0x03,0x83,0x6E,0x2E,0x03,0x89,0x7E,0x2C,0xF6,0x46,0x38,0x20,
3490x74,0x01,0xC3,0x83,0x4E,0x38,0x20,0xB0,0x00,0xE8,0xB6,0xFA,0xC3,0x90,0x83,0xEA,
3500x08,0xE9,0xB4,0xFD,0x83,0xC2,0x06,0x8B,0x5E,0x26,0xF6,0xC3,0xC0,0x75,0xEF,0x8B,
3510x4E,0x1C,0xEC,0x88,0x86,0xA4,0x00,0x83,0xEA,0x0A,0xA8,0x20,0x75,0x02,0x8A,0xCD,
3520x32,0xED,0x8B,0x46,0x1A,0x3B,0xC8,0x73,0x18,0x01,0x4E,0x2A,0x2B,0xC1,0x89,0x46,
3530x1A,0xC5,0x76,0x00,0xF3,0x6E,0x8E,0xD9,0x89,0x76,0x00,0x3D,0x20,0x00,0x72,0x30,
3540xC3,0x85,0xC0,0x74,0x31,0x8B,0xC8,0x01,0x46,0x2A,0xC5,0x76,0x00,0xF3,0x6E,0x8E,
3550xD9,0x80,0xCB,0x02,0x89,0x5E,0x26,0xE8,0x32,0xF1,0xF6,0xC7,0x01,0x75,0x16,0x83,
3560xC2,0x02,0xE8,0x53,0xFD,0xF6,0xC7,0x10,0x75,0x0B,0xB0,0x02,0xE8,0x43,0xFA,0xC3,
3570xF6,0xC7,0x01,0x74,0xF0,0xC3,0x80,0xCB,0x02,0x89,0x5E,0x26,0xF6,0xC7,0x01,0x74,
3580xDE,0x83,0xC2,0x02,0xE8,0x31,0xFD,0xF6,0x86,0xA4,0x00,0x40,0x74,0x0B,0x80,0xE7,
3590xFE,0x80,0xCF,0x02,0x89,0x5E,0x26,0xEB,0xCC,0xB0,0x04,0xE8,0x14,0xFA,0xC3,0xC0,
3600xC2,0xC8,0xCA,0xC4,0xC6,0xCC,0xCE,0xD0,0xD2,0xD8,0xDA,0xD4,0xD6,0xDC,0xDE,0x90,
3610xE9,0x0E,0x01,0xE4,0xC4,0x8A,0xE0,0xE4,0xC4,0x8B,0xD0,0x83,0xF9,0x08,0x72,0xF0,
3620x26,0x83,0x3F,0x00,0x74,0x04,0x8B,0xDF,0x49,0x49,0x8B,0xFB,0x8A,0xDE,0x83,0xE3,
3630x0F,0x2E,0x8A,0xA7,0x2F,0x16,0xAB,0xF6,0xC4,0x10,0x74,0x24,0xF7,0xC6,0x00,0x10,
3640x74,0x0B,0x50,0xFE,0x86,0xB2,0x00,0xB0,0x0A,0xE8,0xC6,0xF9,0x58,0xF7,0xC6,0x00,
3650x01,0x74,0x0D,0xE8,0xA0,0x24,0x8B,0x76,0x38,0x8B,0x4E,0x2E,0x8B,0x7E,0x04,0xAB,
3660x89,0x7E,0x04,0x33,0xC0,0xAB,0x49,0x49,0x89,0x4E,0x2E,0x89,0x7E,0x2C,0x8B,0xC1,
3670xEB,0x4E,0x90,0xEB,0x9E,0x90,0xE4,0xD6,0x84,0xC0,0x79,0x63,0xE6,0xD0,0x8A,0xC8,
3680x25,0x03,0x00,0x03,0xD8,0xD1,0xE3,0x2E,0x8B,0xAF,0x44,0x00,0x88,0x8E,0xAE,0x00,
3690x8B,0x4E,0x2E,0xC4,0x5E,0x04,0x8B,0x7E,0x2C,0x8B,0x76,0x38,0xE4,0x86,0x24,0x07,
3700x3C,0x03,0x75,0xCF,0xE4,0x1C,0x91,0x3B,0xC1,0x73,0x02,0x8B,0xC8,0x2B,0xC1,0x89,
3710x46,0x2E,0x01,0x4E,0x34,0x26,0x01,0x0F,0xBA,0xC4,0x00,0xF3,0x6C,0x89,0x7E,0x2C,
3720x3B,0x46,0x3C,0x72,0x1C,0xF7,0xC6,0x20,0x00,0x75,0x0B,0x83,0xCE,0x20,0x89,0x76,
3730x38,0xB0,0x00,0xE8,0x3C,0xF9,0x8A,0x86,0xAE,0x00,0x24,0x3F,0xE6,0xD6,0xC3,0xF9,
3740xC3,0xF7,0xC6,0x0A,0x00,0x74,0x35,0xF7,0xC6,0x10,0x00,0x75,0x2F,0x83,0xCE,0x10,
3750x89,0x76,0x38,0xF7,0xC6,0x02,0x00,0x74,0x0E,0x50,0xE4,0xD8,0x24,0xFE,0xE6,0xD8,
3760x58,0xF7,0xC6,0x08,0x00,0x74,0x15,0x50,0x51,0xB9,0xE8,0x03,0xE4,0x0A,0x84,0xC0,
3770xE0,0xFA,0x84,0xC0,0x75,0x04,0xB0,0x24,0xE6,0x0A,0x59,0x58,0x3D,0x40,0x00,0x73,
3780xB5,0x8A,0x86,0xA5,0x00,0x24,0xEF,0x88,0x86,0xA5,0x00,0xE6,0x0C,0x81,0xCE,0x10,
3790x04,0x89,0x76,0x38,0xEB,0xA0,0x00,0x08,0x04,0x0C,0x01,0x09,0x05,0x0D,0x02,0x0A,
3800x06,0x0E,0x03,0x0B,0x07,0x0F,0x00,0x40,0x80,0xC0,0x20,0x60,0xA0,0xE0,0x10,0x50,
3810x90,0xD0,0x30,0x70,0xB0,0xF0,0xE4,0xD2,0xE6,0xD0,0x8A,0xC8,0x25,0x03,0x00,0x03,
3820xD8,0xD1,0xE3,0x2E,0x8B,0xAF,0x44,0x00,0x88,0x8E,0xAE,0x00,0xE4,0xD8,0xC0,0xE8,
3830x04,0x8B,0xD8,0x2E,0x8A,0x87,0x66,0x17,0x8A,0xE0,0x8A,0xC8,0x86,0x86,0xA9,0x00,
3840x32,0xE0,0xE4,0x98,0x8B,0x5E,0x3E,0x84,0xE3,0x74,0x54,0x8A,0xC1,0x8B,0x4E,0x26,
3850xF6,0xC5,0x04,0x74,0x0C,0xA8,0x08,0x74,0x05,0x80,0xE1,0xBF,0xEB,0x03,0x80,0xC9,
3860x40,0xF6,0xC5,0x08,0x74,0x0C,0xA8,0x02,0x74,0x05,0x80,0xE1,0x7F,0xEB,0x03,0x80,
3870xC9,0x80,0x88,0x4E,0x26,0x8B,0xF0,0x8A,0x86,0xA5,0x00,0xF6,0xC1,0xFD,0x74,0x08,
3880xA8,0x06,0x74,0x19,0x24,0xF9,0xEB,0x0F,0xA8,0x06,0x75,0x11,0xF6,0xC5,0x01,0x75,
3890x04,0x0C,0x04,0xEB,0x02,0x0C,0x02,0x88,0x86,0xA5,0x00,0xE6,0x0C,0x8B,0xC6,0x84,
3900xE7,0x75,0x09,0x8A,0x86,0xAE,0x00,0x24,0x3F,0xE6,0xD2,0xC3,0xC6,0x86,0xBA,0x00,
3910x01,0xB0,0x0E,0xE8,0x1C,0xF8,0xF7,0x46,0x38,0x00,0x02,0x74,0xE6,0x83,0x7E,0x2E,
3920x06,0x72,0xE0,0x8A,0x86,0xA9,0x00,0x8A,0xE0,0x86,0x86,0xAA,0x00,0x8A,0xC8,0x32,
3930xC4,0x80,0xC9,0x0B,0x22,0xC1,0xC0,0xE4,0x04,0x0A,0xE0,0xC4,0x5E,0x04,0x8B,0x7E,
3940x2C,0xB0,0xFF,0xAA,0xB0,0x02,0xAB,0x26,0x83,0x07,0x03,0x83,0x6E,0x2E,0x03,0x89,
3950x7E,0x2C,0xF6,0x46,0x38,0x20,0x75,0xAB,0x83,0x4E,0x38,0x20,0xB0,0x00,0xE8,0xD1,
3960xF7,0xEB,0xA0,0x90,0xE4,0x12,0x24,0xDF,0xE6,0x12,0x81,0xE3,0xFE,0x9F,0x89,0x5E,
3970x26,0x83,0x66,0x48,0xF7,0xEB,0x73,0x90,0xF6,0xC7,0x20,0x75,0xE7,0xE4,0x12,0x0C,
3980x20,0xE6,0x12,0x32,0xC0,0xE6,0xC6,0xB0,0x83,0xE6,0xC6,0x80,0xCF,0x20,0x89,0x5E,
3990x26,0x8A,0x86,0xA5,0x00,0x0C,0x02,0x88,0x86,0xA5,0x00,0xE6,0x0C,0xEB,0x74,0x90,
4000xF6,0xC7,0x40,0x75,0xD3,0xE4,0x12,0x0C,0x20,0xE6,0x12,0x32,0xC0,0xE6,0xC6,0xB0,
4010x81,0xE6,0xC6,0x80,0xE7,0xDF,0x80,0xCB,0x01,0x89,0x5E,0x26,0xB0,0x06,0xE8,0x71,
4020xF7,0x90,0x8A,0x86,0xA5,0x00,0x24,0xF9,0xE6,0x0C,0x88,0x86,0xA5,0x00,0xEB,0x43,
4030xE4,0xD4,0xE6,0xD0,0x8B,0xF8,0x25,0x03,0x00,0x03,0xD8,0xD1,0xE3,0x2E,0x8B,0xAF,
4040x44,0x00,0x8B,0x5E,0x26,0xF6,0xC7,0x60,0x75,0xB6,0xF6,0xC3,0xC0,0x75,0xD3,0xBA,
4050xC6,0x00,0x8B,0x4E,0x1C,0x8B,0x46,0x1A,0x3B,0xC8,0x73,0x1E,0x01,0x4E,0x2A,0x2B,
4060xC1,0x89,0x46,0x1A,0xC5,0x76,0x00,0xF3,0x6E,0x8E,0xD9,0x89,0x76,0x00,0x3D,0x20,
4070x00,0x72,0x3D,0x8B,0xC7,0x24,0x3F,0xE6,0xD4,0xC3,0x85,0xC0,0x74,0x39,0x8B,0xC8,
4080x01,0x46,0x2A,0xC5,0x76,0x00,0xF3,0x6E,0x8E,0xD9,0x83,0xCB,0x02,0x89,0x5E,0x26,
4090xE8,0xD9,0xED,0xF6,0xC7,0x01,0x75,0x39,0x8A,0x86,0xA5,0x00,0x24,0xF9,0xE6,0x0C,
4100x88,0x86,0xA5,0x00,0xF6,0xC7,0x10,0x75,0xCA,0xB0,0x02,0xE8,0xE4,0xF6,0xEB,0xC3,
4110xF6,0xC7,0x01,0x74,0xEF,0xEB,0xBC,0xF6,0xC7,0x01,0x74,0xDC,0x8A,0x86,0xA5,0x00,
4120xA8,0x02,0x74,0x11,0x81,0xE3,0xFF,0xFE,0x81,0xCB,0x00,0x02,0x89,0x5E,0x26,0xEB,
4130xC7,0x8A,0x86,0xA5,0x00,0x24,0xFB,0x0C,0x02,0xE6,0x0C,0x88,0x86,0xA5,0x00,0xEB,
4140x92,0x90,0xFD,0xF7,0xDF,0x7F,0xFE,0xFB,0xEF,0xBF,0x00,0x04,0x00,0x04,0x05,0x04,
4150x05,0x04,0x01,0x04,0x00,0x04,0x05,0x04,0x05,0x04,0x06,0x04,0x06,0x04,0x05,0x04,
4160x05,0x04,0x06,0x04,0x06,0x04,0x05,0x04,0x05,0x04,0x02,0x04,0x00,0x04,0x05,0x04,
4170x05,0x04,0x01,0x04,0x00,0x04,0x05,0x04,0x05,0x04,0x06,0x04,0x06,0x04,0x05,0x04,
4180x05,0x04,0x06,0x04,0x06,0x04,0x05,0x04,0x05,0x04,0x07,0x04,0x07,0x04,0x05,0x04,
4190x05,0x04,0x07,0x04,0x07,0x04,0x05,0x04,0x05,0x04,0x06,0x04,0x06,0x04,0x05,0x04,
4200x05,0x04,0x06,0x04,0x06,0x04,0x05,0x04,0x05,0x04,0x07,0x04,0x07,0x04,0x05,0x04,
4210x05,0x04,0x07,0x04,0x07,0x04,0x05,0x04,0x05,0x04,0x06,0x04,0x06,0x04,0x05,0x04,
4220x05,0x04,0x06,0x04,0x06,0x04,0x05,0x04,0x05,0x04,0x03,0x04,0x00,0x04,0x05,0x04,
4230x05,0x04,0x01,0x04,0x00,0x04,0x05,0x04,0x05,0x04,0x06,0x04,0x06,0x04,0x05,0x04,
4240x05,0x04,0x06,0x04,0x06,0x04,0x05,0x04,0x05,0x04,0x02,0x04,0x00,0x04,0x05,0x04,
4250x05,0x04,0x01,0x04,0x00,0x04,0x05,0x04,0x05,0x04,0x06,0x04,0x06,0x04,0x05,0x04,
4260x05,0x04,0x06,0x04,0x06,0x04,0x05,0x04,0x05,0x04,0x07,0x04,0x07,0x04,0x05,0x04,
4270x05,0x04,0x07,0x04,0x07,0x04,0x05,0x04,0x05,0x04,0x06,0x04,0x06,0x04,0x05,0x04,
4280x05,0x04,0x06,0x04,0x06,0x04,0x05,0x04,0x05,0x04,0x07,0x04,0x07,0x04,0x05,0x04,
4290x05,0x04,0x07,0x04,0x07,0x04,0x05,0x04,0x05,0x04,0x06,0x04,0x06,0x04,0x05,0x04,
4300x05,0x04,0x06,0x04,0x06,0x04,0x05,0x04,0x05,0x04,0x33,0xDB,0x8A,0xD8,0x8A,0x87,
4310x6C,0x12,0xE6,0xFE,0xC1,0xE3,0x02,0xE4,0xCE,0xA8,0x04,0x75,0x09,0xA8,0x02,0x74,
4320x03,0xE9,0x2C,0xFE,0xF9,0xC3,0x50,0x53,0xE8,0xCB,0xFC,0x5B,0x58,0xA8,0x02,0x74,
4330x03,0xE9,0x1C,0xFE,0xF8,0xC3,0x33,0xDB,0x8A,0xD8,0x8A,0x87,0x6C,0x12,0xE6,0xFE,
4340xC1,0xE3,0x02,0xE9,0xD0,0xFB,0x9A,0x1A,0xC6,0x1A,0x00,0x00,0x02,0x00,0x04,0x00,
4350x02,0x00,0x06,0x00,0x02,0x00,0x04,0x00,0x02,0x00,0x08,0x00,0x02,0x00,0x04,0x00,
4360x02,0x00,0x06,0x00,0x02,0x00,0x04,0x00,0x02,0x00,0x0A,0x00,0x02,0x00,0x04,0x00,
4370x02,0x00,0x06,0x00,0x02,0x00,0x04,0x00,0x02,0x00,0x08,0x00,0x02,0x00,0x04,0x00,
4380x02,0x00,0x06,0x00,0x02,0x00,0x04,0x00,0x02,0x00,0x0C,0x00,0x02,0x00,0x04,0x00,
4390x02,0x00,0x06,0x00,0x02,0x00,0x04,0x00,0x02,0x00,0x08,0x00,0x02,0x00,0x04,0x00,
4400x02,0x00,0x06,0x00,0x02,0x00,0x04,0x00,0x02,0x00,0x0A,0x00,0x02,0x00,0x04,0x00,
4410x02,0x00,0x06,0x00,0x02,0x00,0x04,0x00,0x02,0x00,0x08,0x00,0x02,0x00,0x04,0x00,
4420x02,0x00,0x06,0x00,0x02,0x00,0x04,0x00,0x02,0x00,0x0E,0x00,0x02,0x00,0x04,0x00,
4430x02,0x00,0x06,0x00,0x02,0x00,0x04,0x00,0x02,0x00,0x08,0x00,0x02,0x00,0x04,0x00,
4440x02,0x00,0x06,0x00,0x02,0x00,0x04,0x00,0x02,0x00,0x0A,0x00,0x02,0x00,0x04,0x00,
4450x02,0x00,0x06,0x00,0x02,0x00,0x04,0x00,0x02,0x00,0x08,0x00,0x02,0x00,0x04,0x00,
4460x02,0x00,0x06,0x00,0x02,0x00,0x04,0x00,0x02,0x00,0x0C,0x00,0x02,0x00,0x04,0x00,
4470x02,0x00,0x06,0x00,0x02,0x00,0x04,0x00,0x02,0x00,0x08,0x00,0x02,0x00,0x04,0x00,
4480x02,0x00,0x06,0x00,0x02,0x00,0x04,0x00,0x02,0x00,0x0A,0x00,0x02,0x00,0x04,0x00,
4490x02,0x00,0x06,0x00,0x02,0x00,0x04,0x00,0x02,0x00,0x08,0x00,0x02,0x00,0x04,0x00,
4500x02,0x00,0x06,0x00,0x02,0x00,0x04,0x00,0x02,0x00,0xC3,0x90,0xDA,0x14,0x94,0x15,
4510x5C,0x13,0xE6,0x13,0xDA,0x1B,0xDA,0x1B,0xE6,0x13,0xDA,0x1B,0x8B,0x94,0x64,0x12,
4520xC1,0xE6,0x04,0xA8,0x01,0x74,0x35,0x50,0x33,0xC0,0x8A,0xC2,0xE6,0xFE,0xE4,0xA0,
4530x85,0xC0,0x74,0x27,0x8B,0xD8,0x2E,0x8A,0x9F,0xDA,0x1A,0x52,0x56,0x2E,0x8B,0xA8,
4540x44,0x00,0x8B,0x56,0x28,0xEC,0xA8,0x01,0x75,0x0D,0x88,0x86,0xAD,0x00,0x24,0x0E,
4550x8A,0xD8,0x2E,0xFF,0x97,0xDC,0x1B,0x5E,0x5A,0xEB,0xCD,0x58,0xA8,0x02,0x74,0x36,
4560x83,0xC6,0x10,0x33,0xC0,0x8A,0xC6,0xE6,0xFE,0xE4,0xA0,0x85,0xC0,0x74,0x27,0x8B,
4570xD8,0x2E,0x8A,0x9F,0xDA,0x1A,0x52,0x56,0x2E,0x8B,0xA8,0x44,0x00,0x8B,0x56,0x28,
4580xEC,0xA8,0x01,0x75,0x0D,0x88,0x86,0xAD,0x00,0x24,0x0E,0x8A,0xD8,0x2E,0xFF,0x97,
4590xDC,0x1B,0x5E,0x5A,0xEB,0xCD,0xC3,0x90,0x32,0xE4,0x8B,0xD8,0x8B,0xD0,0x2E,0x8A,
4600x9F,0x9A,0x19,0x2E,0x22,0x97,0x92,0x19,0x56,0x52,0x8A,0xC3,0x24,0x03,0x03,0xC6,
4610x80,0xE3,0x04,0xD0,0xEB,0x2E,0xFF,0x97,0xD6,0x1A,0x58,0x5E,0xA9,0x55,0x00,0x75,
4620xD9,0xC3,0x60,0x1E,0x06,0x2B,0xC0,0x8E,0xD8,0xA1,0x5C,0x12,0xE6,0xFE,0xE4,0x00,
4630x22,0xC4,0x74,0x08,0x33,0xF6,0xE8,0xBF,0xFF,0xEB,0xEE,0x90,0xE4,0x04,0x07,0xE4,
4640x04,0x1F,0xB8,0x00,0x80,0xBA,0x22,0xFF,0xEF,0x61,0xCF,0x90,0x60,0x1E,0x06,0x2B,
4650xC0,0x8E,0xD8,0xA1,0x5E,0x12,0xE6,0xFE,0xE4,0x00,0x22,0xC4,0x74,0x08,0xBE,0x04,
4660x00,0xE8,0x94,0xFF,0xEB,0xED,0xE4,0x04,0x07,0xE4,0x04,0x1F,0xB8,0x00,0x80,0xBA,
4670x22,0xFF,0xEF,0x61,0xCF,0x90,0x60,0x1E,0x06,0x2B,0xC0,0x8E,0xD8,0xA1,0x5C,0x12,
4680xE6,0xFE,0xE4,0x00,0x22,0xC4,0x74,0x18,0x33,0xF6,0xE8,0x6B,0xFF,0xA1,0x60,0x12,
4690xE6,0xFE,0xE4,0x00,0x22,0xC4,0x74,0xE5,0xBE,0x08,0x00,0xE8,0x5A,0xFF,0xEB,0xDD,
4700xA1,0x60,0x12,0xE6,0xFE,0xE4,0x00,0x22,0xC4,0x75,0xED,0xE4,0x04,0x07,0xE4,0x04,
4710xA1,0x5C,0x12,0xE6,0xFE,0xE4,0x04,0x1F,0xE4,0x04,0xB8,0x00,0x80,0xBA,0x22,0xFF,
4720xEF,0x61,0xCF,0x90,0x60,0x1E,0x06,0x2B,0xC0,0x8E,0xD8,0xA1,0x5E,0x12,0xE6,0xFE,
4730xE4,0x00,0x22,0xC4,0x74,0x19,0xBE,0x04,0x00,0xE8,0x1C,0xFF,0xA1,0x62,0x12,0xE6,
4740xFE,0xE4,0x00,0x22,0xC4,0x74,0xE4,0xBE,0x0C,0x00,0xE8,0x0B,0xFF,0xEB,0xDC,0xA1,
4750x62,0x12,0xE6,0xFE,0xE4,0x00,0x22,0xC4,0x75,0xED,0xE4,0x04,0x07,0xE4,0x04,0xA1,
4760x5E,0x12,0xE6,0xFE,0xE4,0x04,0x1F,0xE4,0x04,0xB8,0x00,0x80,0xBA,0x22,0xFF,0xEF,
4770x61,0xCF,0x60,0x1E,0x06,0x2B,0xC0,0x8E,0xD8,0xA1,0x5C,0x12,0xE6,0xFE,0xE4,0x80,
4780x84,0xC4,0x74,0x08,0x33,0xF6,0xE8,0x53,0xFE,0xEB,0xEE,0x90,0xB8,0x00,0x80,0xBA,
4790x22,0xFF,0xEF,0x07,0x1F,0x61,0xCF,0x90,0x60,0x1E,0x06,0x2B,0xC0,0x8E,0xD8,0xA1,
4800x5E,0x12,0xE6,0xFE,0xE4,0x80,0x84,0xC4,0x74,0x08,0xBE,0x02,0x00,0xE8,0x2C,0xFE,
4810xEB,0xED,0xB8,0x00,0x80,0xBA,0x22,0xFF,0xEF,0x07,0x1F,0x61,0xCF,0x90,0x60,0x1E,
4820x06,0x2B,0xC0,0x8E,0xD8,0xA1,0x60,0x12,0xE6,0xFE,0xE4,0x80,0x84,0xC4,0x74,0x08,
4830xBE,0x04,0x00,0xE8,0x06,0xFE,0xEB,0xED,0xB8,0x00,0x80,0xBA,0x22,0xFF,0xEF,0x07,
4840x1F,0x61,0xCF,0x90,0x60,0x1E,0x06,0x2B,0xC0,0x8E,0xD8,0xA1,0x62,0x12,0xE6,0xFE,
4850xE4,0x80,0x84,0xC4,0x74,0x08,0xBE,0x06,0x00,0xE8,0xE0,0xFD,0xEB,0xED,0xB8,0x00,
4860x80,0xBA,0x22,0xFF,0xEF,0x07,0x1F,0x61,0xCF,0x90,0x60,0x1E,0x06,0x2B,0xC0,0x8E,
4870xD8,0xA1,0x5C,0x12,0xE6,0xFE,0xE4,0x00,0x22,0xC4,0x74,0x18,0x33,0xF6,0xE8,0x37,
4880xFE,0xA1,0x60,0x12,0xE6,0xFE,0xE4,0x80,0x84,0xC4,0x74,0xE5,0xBE,0x04,0x00,0xE8,
4890xAA,0xFD,0xEB,0xDD,0xA1,0x60,0x12,0xE6,0xFE,0xE4,0x80,0x84,0xC4,0x75,0xED,0xA1,
4900x5C,0x12,0xE6,0xFE,0xE4,0x04,0x07,0xE4,0x04,0x1F,0xB8,0x00,0x80,0xBA,0x22,0xFF,
4910xEF,0x61,0xCF,0x90,0x60,0x1E,0x06,0x2B,0xC0,0x8E,0xD8,0xA1,0x5E,0x12,0xE6,0xFE,
4920xE4,0x00,0x22,0xC4,0x74,0x19,0xBE,0x04,0x00,0xE8,0xEC,0xFD,0xA1,0x62,0x12,0xE6,
4930xFE,0xE4,0x80,0x84,0xC4,0x74,0xE4,0xBE,0x06,0x00,0xE8,0x5F,0xFD,0xEB,0xDC,0xA1,
4940x62,0x12,0xE6,0xFE,0xE4,0x80,0x84,0xC4,0x75,0xED,0xA1,0x5E,0x12,0xE6,0xFE,0xE4,
4950x04,0x07,0xE4,0x04,0x1F,0xB8,0x00,0x80,0xBA,0x22,0xFF,0xEF,0x61,0xCF,0x60,0x1E,
4960x06,0x2B,0xC0,0x8E,0xD8,0xA1,0x5C,0x12,0xE6,0xFE,0xE4,0x80,0x84,0xC4,0x74,0x18,
4970x33,0xF6,0xE8,0x27,0xFD,0xA1,0x60,0x12,0xE6,0xFE,0xE4,0x00,0x22,0xC4,0x74,0xE5,
4980xBE,0x08,0x00,0xE8,0x92,0xFD,0xEB,0xDD,0xA1,0x60,0x12,0xE6,0xFE,0xE4,0x00,0x22,
4990xC4,0x75,0xED,0xE4,0x04,0x07,0xE4,0x04,0x1F,0xB8,0x00,0x80,0xBA,0x22,0xFF,0xEF,
5000x61,0xCF,0x60,0x1E,0x06,0x2B,0xC0,0x8E,0xD8,0xA1,0x5E,0x12,0xE6,0xFE,0xE4,0x80,
5010x84,0xC4,0x74,0x19,0xBE,0x02,0x00,0xE8,0xE2,0xFC,0xA1,0x62,0x12,0xE6,0xFE,0xE4,
5020x00,0x22,0xC4,0x74,0xE4,0xBE,0x0C,0x00,0xE8,0x4D,0xFD,0xEB,0xDC,0xA1,0x62,0x12,
5030xE6,0xFE,0xE4,0x00,0x22,0xC4,0x75,0xED,0xE4,0x04,0x07,0xE4,0x04,0x1F,0xB8,0x00,
5040x80,0xBA,0x22,0xFF,0xEF,0x61,0xCF,0x90,0x60,0x1E,0x06,0x2B,0xC0,0x8E,0xD8,0xA1,
5050x5C,0x12,0xE6,0xFE,0xE4,0x80,0x84,0xC4,0x74,0x18,0x33,0xF6,0xE8,0x9D,0xFC,0xA1,
5060x60,0x12,0xE6,0xFE,0xE4,0x80,0x84,0xC4,0x74,0xE5,0xBE,0x04,0x00,0xE8,0x8C,0xFC,
5070xEB,0xDD,0xA1,0x60,0x12,0xE6,0xFE,0xE4,0x80,0x84,0xC4,0x75,0xED,0x07,0x1F,0xB8,
5080x00,0x80,0xBA,0x22,0xFF,0xEF,0x61,0xCF,0x60,0x1E,0x06,0x2B,0xC0,0x8E,0xD8,0xA1,
5090x5E,0x12,0xE6,0xFE,0xE4,0x80,0x84,0xC4,0x74,0x19,0xBE,0x02,0x00,0xE8,0x5C,0xFC,
5100xA1,0x62,0x12,0xE6,0xFE,0xE4,0x80,0x84,0xC4,0x74,0xE4,0xBE,0x06,0x00,0xE8,0x4B,
5110xFC,0xEB,0xDC,0xA1,0x62,0x12,0xE6,0xFE,0xE4,0x80,0x84,0xC4,0x75,0xED,0x07,0x1F,
5120xB8,0x00,0x80,0xBA,0x22,0xFF,0xEF,0x61,0xCF,0x90,0x60,0x1E,0x06,0x2B,0xC0,0x8E,
5130xD8,0x90,0x2A,0xC0,0xE6,0xFE,0xE4,0xCE,0xA8,0x01,0x74,0x14,0x33,0xDB,0xE8,0xD5,
5140xF6,0xEB,0xEF,0x90,0xB8,0x00,0x80,0xBA,0x22,0xFF,0xEF,0x07,0x1F,0x61,0xCF,0x90,
5150xF6,0x06,0x05,0x01,0x01,0x75,0xED,0xB0,0x01,0xE6,0xFE,0xE4,0xCE,0xA8,0x01,0x74,
5160xE3,0xBB,0x04,0x00,0xE8,0xAF,0xF6,0xEB,0xC9,0x90,0x60,0x1E,0x06,0x2B,0xC0,0x8E,
5170xD8,0x90,0xFB,0x90,0xFA,0x2A,0xC0,0xE6,0xFE,0xE4,0xCE,0xA8,0x02,0x74,0x13,0x33,
5180xDB,0xE8,0xCC,0xF8,0xEB,0xEC,0xB8,0x00,0x80,0xBA,0x22,0xFF,0xEF,0x07,0x1F,0x61,
5190xCF,0x90,0xA8,0x04,0x74,0xF0,0x33,0xDB,0xE8,0x5B,0xF7,0xEB,0xD5,0x90,0x60,0x1E,
5200x06,0x2B,0xC0,0x8E,0xD8,0x90,0xFB,0x90,0xFA,0xB0,0x01,0xE6,0xFE,0xE4,0xCE,0xA8,
5210x02,0x74,0x15,0xBB,0x04,0x00,0xE8,0x97,0xF8,0xEB,0xEB,0x90,0xB8,0x00,0x80,0xBA,
5220x22,0xFF,0xEF,0x07,0x1F,0x61,0xCF,0x90,0xA8,0x04,0x74,0xF0,0xBB,0x04,0x00,0xE8,
5230x24,0xF7,0xEB,0xD2,0x6A,0x00,0x1F,0xC6,0x06,0x93,0x12,0x09,0x9C,0x0E,0xE8,0x6B,
5240xF2,0x90,0x6A,0x00,0x1F,0xC6,0x06,0x93,0x12,0x29,0x9C,0x0E,0xE8,0x5D,0xF2,0x90,
5250x72,0x20,0x72,0x20,0x72,0x20,0xCE,0x1D,0x92,0x1C,0xE6,0x1C,0x1A,0x1E,0x72,0x20,
5260x82,0x1D,0xAE,0x1E,0x38,0x1F,0x72,0x20,0x82,0x1D,0x72,0x20,0x72,0x20,0x38,0x1F,
5270x72,0x20,0x72,0x20,0x72,0x20,0xF4,0x1D,0xBC,0x1C,0x34,0x1D,0x64,0x1E,0x72,0x20,
5280xA8,0x1D,0xF2,0x1E,0x78,0x1F,0x72,0x20,0xA8,0x1D,0x72,0x20,0x72,0x20,0x78,0x1F,
5290xFC,0xB9,0x40,0x00,0x8C,0xCB,0xB8,0x64,0x20,0x2B,0xFF,0xAB,0x93,0xAB,0x93,0xE2,
5300xFA,0xC7,0x06,0x4C,0x00,0xA8,0x11,0x83,0x3E,0x44,0x12,0x00,0x75,0x20,0xC7,0x06,
5310x3C,0x00,0x08,0x4B,0xC7,0x06,0x30,0x00,0xBA,0x1F,0xC7,0x06,0x34,0x00,0xFA,0x1F,
5320xF6,0x06,0x05,0x01,0x01,0x75,0x06,0xC7,0x06,0x38,0x00,0x2E,0x20,0xC3,0xC7,0x06,
5330x3C,0x00,0x56,0x4B,0x33,0xDB,0x8A,0x1E,0x54,0x12,0xC1,0xE3,0x02,0x02,0x1E,0x56,
5340x12,0x2E,0x8B,0x87,0x80,0x20,0xA3,0x30,0x00,0x8A,0x1E,0x55,0x12,0xC1,0xE3,0x02,
5350x02,0x1E,0x57,0x12,0x2E,0x8B,0x87,0xA0,0x20,0xA3,0x34,0x00,0xC3,0x8B,0x86,0x9E,
5360x00,0xE6,0xFE,0x86,0xC4,0xE6,0xD0,0xC3,0x8B,0x86,0x9E,0x00,0xE6,0xFE,0x33,0xD2,
5370x8A,0xD4,0xC3,0x51,0xB9,0x10,0x27,0xE4,0x0A,0x90,0x90,0x84,0xC0,0x74,0x05,0xE2,
5380xF6,0x59,0xF9,0xC3,0x59,0xF8,0xC3,0x84,0xC0,0x78,0x1E,0x51,0x8A,0xE8,0x8A,0xC8,
5390xB8,0x01,0x00,0xD3,0xE0,0x09,0x86,0x98,0x00,0x3A,0xAE,0xA0,0x00,0x59,0x75,0x10,
5400xE8,0xA9,0xE5,0x83,0x4E,0x26,0x02,0xF9,0xC3,0x98,0x89,0x86,0x98,0x00,0xEB,0xF0,
5410xF8,0xC3,0x84,0xC0,0x78,0x12,0x51,0x8A,0xE0,0x8A,0xC8,0xB8,0x01,0x00,0xD3,0xE0,
5420x59,0xF7,0xD0,0x21,0x86,0x98,0x00,0xC3,0xC7,0x86,0x98,0x00,0x00,0x00,0xC3,0x83,
5430xC2,0x04,0x8A,0x86,0xA6,0x00,0x0C,0x04,0xEE,0x83,0xEA,0x04,0xC3,0xE8,0x93,0xFF,
5440x72,0x04,0xB0,0x82,0xE6,0x0A,0xC3,0x8B,0x46,0x26,0xA8,0xFD,0x74,0x11,0x8A,0x86,
5450xA5,0x00,0xA8,0x06,0x74,0x08,0x24,0xF9,0x88,0x86,0xA5,0x00,0xE6,0x0C,0xC3,0xF6,
5460xC4,0x01,0x74,0x0A,0x8A,0x86,0xA5,0x00,0x24,0xFB,0x0C,0x02,0xEB,0x0C,0xA8,0x02,
5470x75,0x0F,0x8A,0x86,0xA5,0x00,0x24,0xFD,0x0C,0x04,0x3A,0x86,0xA5,0x00,0x75,0xD8,
5480xC3,0x8A,0x86,0xA5,0x00,0xEB,0xCF,0xE4,0xD8,0x33,0xDB,0x8A,0xD8,0xC0,0xEB,0x04,
5490x2E,0x8A,0x9F,0x66,0x17,0x88,0x9E,0xA9,0x00,0x8B,0x5E,0x26,0x80,0xE3,0x3F,0xF6,
5500xC7,0x04,0x74,0x07,0xA8,0x10,0x75,0x03,0x80,0xCB,0x40,0xF6,0xC7,0x08,0x74,0x07,
5510xA8,0x80,0x75,0x03,0x80,0xCB,0x40,0x88,0x5E,0x26,0x8A,0x86,0xA5,0x00,0xF6,0xC3,
5520xFD,0x74,0x0D,0xA8,0x06,0x74,0x08,0x24,0xF9,0x88,0x86,0xA5,0x00,0xE6,0x0C,0xC3,
5530xF6,0xC7,0x01,0x74,0x04,0x0C,0x02,0xEB,0xF0,0xF6,0xC3,0x02,0x75,0xE9,0x0C,0x04,
5540xEB,0xE7,0xC4,0x04,0xC4,0x04,0x85,0x04,0x59,0x04,0x48,0x04,0x41,0x04,0xC3,0x03,
5550x82,0x03,0x41,0x03,0x82,0x02,0x57,0x02,0x41,0x02,0x82,0x01,0x41,0x01,0x82,0x00,
5560x41,0x00,0x4E,0x02,0xAD,0x01,0x57,0x01,0x2D,0x00,0x2B,0x00,0x27,0x00,0x21,0x00,
5570x16,0x00,0xF4,0x04,0xF4,0x04,0xA3,0x04,0x6F,0x04,0x5B,0x04,0x51,0x04,0xF4,0x03,
5580xA3,0x03,0x51,0x03,0xA3,0x02,0x6D,0x02,0x51,0x02,0xA3,0x01,0x51,0x01,0xA3,0x00,
5590x51,0x00,0x62,0x02,0xD9,0x01,0x6D,0x01,0x38,0x00,0x36,0x00,0x31,0x00,0x29,0x00,
5600x1B,0x00,0x51,0x57,0xBF,0x02,0x00,0xEB,0x0F,0x90,0x51,0x56,0xBF,0x01,0x00,0xEB,
5610x07,0x90,0x51,0x56,0xBF,0x03,0x00,0x90,0x3C,0x19,0x76,0x02,0xB0,0x17,0x98,0x8B,
5620xF0,0x8A,0x82,0xC4,0x00,0x2A,0xE4,0x8B,0xF0,0x83,0xFE,0x18,0x73,0x46,0xD1,0xE6,
5630x2E,0x8B,0x8C,0x52,0x22,0xF7,0x46,0x38,0x80,0x00,0x74,0x05,0x2E,0x8B,0x8C,0x82,
5640x22,0xF7,0xC7,0x02,0x00,0x74,0x12,0x3B,0x8E,0x94,0x00,0x74,0x0C,0x89,0x8E,0x94,
5650x00,0x8A,0xC5,0xE6,0xEC,0x8A,0xC1,0xE6,0xE4,0xF7,0xC7,0x01,0x00,0x74,0x12,0x3B,
5660x8E,0x96,0x00,0x74,0x0C,0x89,0x8E,0x96,0x00,0x8A,0xC5,0xE6,0xF8,0x8A,0xC1,0xE6,
5670xF0,0x5E,0x59,0xC3,0x77,0x06,0x8B,0x8E,0x8E,0x00,0xEB,0xC5,0x8B,0x8E,0x90,0x00,
5680xEB,0xBF,0xD5,0x03,0xF6,0x00,0x3E,0x00,0x10,0x00,0x04,0x00,0xCA,0x04,0x33,0x01,
5690x4D,0x00,0x14,0x00,0x05,0x00,0x01,0x03,0x05,0x07,0x09,0x00,0x01,0x02,0x03,0x04,
5700x80,0x84,0x1E,0x00,0xA0,0x25,0x26,0x00,0x00,0x00,0x60,0x8B,0xF0,0x33,0xFF,0x2E,
5710xA1,0x50,0x23,0x2E,0x8B,0x16,0x52,0x23,0xBB,0x32,0x23,0xF7,0x46,0x38,0x80,0x00,
5720x74,0x0C,0x2E,0xA1,0x54,0x23,0x2E,0x8B,0x16,0x56,0x23,0xBB,0x3C,0x23,0xB9,0x05,
5730x00,0x2E,0x3B,0x31,0x73,0x0A,0x47,0x47,0xE2,0xF7,0xB8,0xFF,0xFF,0xEB,0x1D,0x90,
5740xD1,0xEF,0x2E,0x8A,0x8D,0x46,0x23,0x2A,0xED,0xD1,0xEA,0xD1,0xD8,0xE2,0xFA,0xF7,
5750xF6,0x05,0x02,0x00,0xC1,0xE8,0x02,0x2E,0x8A,0xA5,0x4B,0x23,0x2E,0xA3,0x58,0x23,
5760x61,0x2E,0xA1,0x58,0x23,0xC3,0x08,0x00,0x20,0x00,0x80,0x00,0x00,0x02,0x60,0x09,
5770x08,0x00,0x20,0x00,0x80,0x00,0x00,0x02,0x00,0x08,0x00,0x00,0x01,0x00,0x02,0x00,
5780x03,0x00,0x04,0x00,0x52,0x56,0x57,0x85,0xC0,0x74,0x05,0x3D,0x01,0x09,0x76,0x03,
5790xB8,0x01,0x09,0xBF,0x5B,0x01,0xF7,0x46,0x38,0x80,0x00,0x74,0x03,0xBF,0xB2,0x01,
5800x33,0xF6,0x2E,0x3B,0x84,0xB6,0x23,0x76,0x04,0x46,0x46,0xEB,0xF5,0xF7,0xE7,0x2E,
5810x8B,0xBC,0xC0,0x23,0x03,0xC7,0x83,0xD2,0x00,0xD1,0xE7,0xF7,0xF7,0x2E,0x8A,0xA4,
5820xCA,0x23,0x5F,0x5E,0x5A,0xC3,0xE4,0x3E,0x80,0xBE,0xC3,0x00,0x03,0x75,0x0C,0xF7,
5830x46,0x7A,0x20,0x00,0x74,0x05,0x0C,0x80,0xE6,0x3E,0xC3,0x24,0x7F,0xE6,0x3E,0xC3,
5840x24,0x03,0x88,0x86,0xC3,0x00,0x8A,0xE0,0xE4,0x10,0x24,0xFC,0x0A,0xC4,0xE6,0x10,
5850x80,0x8E,0xA1,0x00,0x42,0xE8,0xCE,0xFF,0xC3,0x90,0x56,0x8B,0xF0,0x83,0xE6,0x07,
5860xD1,0xE6,0x2E,0xFF,0xA4,0x58,0x24,0x90,0x68,0x24,0x6C,0x24,0x70,0x24,0x74,0x24,
5870x78,0x24,0x87,0x24,0x87,0x24,0x87,0x24,0xB4,0x00,0xEB,0x0E,0xB4,0xC0,0xEB,0x0A,
5880xB4,0x40,0xEB,0x06,0xB4,0x20,0xEB,0x02,0xB4,0xA0,0xE4,0x10,0x24,0x1F,0x0A,0xC4,
5890xE6,0x10,0x80,0x8E,0xA1,0x00,0x42,0x5E,0xC3,0x90,0x3C,0x02,0x77,0x12,0x8A,0xE0,
5900xE4,0x10,0x24,0xF3,0xC0,0xE4,0x02,0x0A,0xC4,0xE6,0x10,0x80,0x8E,0xA1,0x00,0x42,
5910xC3,0x90,0x8B,0x5E,0x38,0x84,0xC0,0x74,0x1F,0x3C,0x02,0x74,0x20,0x83,0xCB,0x08,
5920x8B,0x46,0x2E,0x3B,0x46,0x3C,0x77,0x0C,0xE8,0x88,0xFC,0x72,0x07,0xB0,0x24,0xE6,
5930x0A,0x83,0xCB,0x10,0x89,0x5E,0x38,0xC3,0x83,0xE3,0xF7,0xEB,0xF7,0xF7,0xC3,0x10,
5940x00,0x74,0xF5,0xE8,0x6D,0xFC,0x72,0xEC,0x8A,0x86,0xC0,0x00,0xE6,0x38,0xB0,0x23,
5950xE6,0x0A,0xEB,0xE0,0x8B,0x5E,0x38,0x8B,0x46,0x2E,0x3B,0x46,0x3C,0xE4,0xD8,0x77,
5960x0B,0x24,0xFE,0x80,0xCB,0x12,0xE6,0xD8,0x89,0x5E,0x38,0xC3,0x0C,0x01,0x80,0xCB,
5970x02,0xEB,0xF3,0x50,0x33,0xDB,0xC1,0xE8,0x04,0x25,0x0F,0x0F,0x8A,0xD8,0x2E,0x8A,
5980x87,0x66,0x17,0x8A,0xDC,0x2E,0x8A,0xA7,0x66,0x17,0x09,0x46,0x3E,0x58,0xC3,0x50,
5990x33,0xDB,0xC1,0xE8,0x04,0x25,0x0F,0x0F,0x8A,0xD8,0x2E,0x8A,0x87,0x66,0x17,0x8A,
6000xDC,0x2E,0x8A,0xA7,0x66,0x17,0xF7,0xD0,0x21,0x46,0x3E,0x58,0xC3,0x8B,0x46,0x3E,
6010x33,0xDB,0x8A,0xD8,0x0A,0xDC,0x2E,0x8A,0x87,0x76,0x17,0xE6,0x2C,0x8A,0xE0,0xE4,
6020x2A,0x24,0x0F,0x0A,0xC4,0xE6,0x2A,0x8A,0x86,0xA5,0x00,0x84,0xE4,0x75,0x0D,0xA8,
6030x80,0x74,0x11,0x24,0x7F,0x88,0x86,0xA5,0x00,0xE6,0x0C,0xC3,0xA8,0x80,0x75,0x04,
6040x0C,0x80,0xEB,0xF1,0xC3,0x1E,0x60,0x33,0xC9,0x33,0xD2,0x33,0xF6,0x8E,0xD9,0x8D,
6050xBE,0xFD,0x00,0x57,0x8B,0x05,0x84,0xC0,0x74,0x16,0x8B,0xD1,0x42,0x8B,0xFE,0x4F,
6060x78,0x09,0x38,0xA3,0xE4,0x00,0x74,0x08,0x4F,0x79,0xF7,0x88,0xA2,0xE4,0x00,0x46,
6070x5F,0x83,0xC7,0x09,0x41,0x83,0xF9,0x10,0x72,0xD9,0x89,0xB6,0x86,0x00,0x89,0x96,
6080x84,0x00,0x61,0x1F,0xC3,0x53,0xC7,0x46,0x66,0x00,0x00,0x8B,0x46,0x64,0xA9,0x40,
6090x00,0x74,0x0D,0xB3,0x00,0xA9,0x80,0x00,0x74,0x02,0xB3,0x7F,0x88,0x9E,0xC1,0x00,
6100x32,0xDB,0xA9,0x02,0x00,0x74,0x03,0x80,0xCB,0x40,0xA9,0x00,0x40,0x74,0x03,0x80,
6110xCB,0x02,0xA9,0x00,0x80,0x74,0x03,0x80,0xCB,0x01,0xA9,0x30,0x1E,0x74,0x03,0x80,
6120xCB,0xBC,0xA9,0x00,0x20,0x74,0x03,0x80,0xCB,0x08,0xA9,0x04,0x01,0x74,0x03,0x80,
6130xCB,0x10,0xA9,0x08,0x00,0x74,0x03,0x80,0xCB,0x20,0x88,0x9E,0xC2,0x00,0x5B,0xC3,
6140x06,0x51,0x57,0x50,0x16,0x07,0x8D,0xBE,0xC4,0x00,0xB9,0x1F,0x00,0x33,0xC0,0xAA,
6150x40,0xE2,0xFC,0x8B,0x86,0x92,0x00,0x89,0x86,0x8E,0x00,0x89,0x86,0x90,0x00,0x58,
6160x5F,0x59,0x07,0xC3,0xE4,0xD8,0xC0,0xE8,0x04,0x53,0x25,0x0F,0x00,0x8B,0xD8,0x2E,
6170x8A,0x87,0x66,0x17,0x88,0x86,0xA9,0x00,0x5A,0xC3,0x08,0x86,0xAC,0x00,0xC6,0x86,
6180xBA,0x00,0x01,0xB0,0x0E,0xE8,0xEA,0xE9,0xC3,0xAD,0x36,0xA3,0xB4,0x13,0xAD,0x36,
6190xA3,0xB6,0x13,0xAD,0x36,0xA3,0xB8,0x13,0x83,0xE9,0x06,0x36,0xF7,0x06,0xB6,0x13,
6200x0F,0x00,0xC3,0x8A,0x46,0x26,0xF7,0x46,0x48,0x80,0x00,0x74,0x02,0x0C,0x10,0x88,
6210x86,0xBD,0x00,0x32,0xC0,0x83,0x7E,0x1A,0x00,0x75,0x0E,0x8B,0x5E,0x40,0x43,0x80,
6220xE3,0xFE,0x3B,0x5E,0x08,0x75,0x02,0x0C,0x01,0x83,0x7E,0x3A,0x00,0x75,0x0D,0x1E,
6230xC5,0x5E,0x14,0x8B,0x1F,0x1F,0x85,0xDB,0x75,0x02,0x0C,0x02,0xF7,0x46,0x38,0x10,
6240x00,0x74,0x02,0x0C,0x04,0x8B,0x5E,0x7A,0xF7,0xC3,0x02,0x00,0x74,0x02,0x0C,0x08,
6250xF7,0xC3,0x04,0x00,0x74,0x02,0x0C,0x10,0xF7,0xC3,0x08,0x00,0x74,0x02,0x0C,0x20,
6260xF7,0xC3,0x40,0x00,0x74,0x02,0x0C,0x40,0x88,0x86,0xBF,0x00,0xC3,0x90,0x6A,0x00,
6270x1F,0xC6,0x06,0x93,0x12,0x0D,0x9C,0x0E,0xE8,0xF1,0xEB,0x90,0xB0,0x02,0xE6,0xDA,
6280xF8,0xC3,0x33,0xC0,0xE6,0xDA,0xF8,0xC3,0xB0,0x01,0xE6,0xD8,0xF8,0xC3,0x33,0xC0,
6290xE6,0xD8,0xF8,0xC3,0xB0,0xFF,0xE8,0x4E,0xFA,0xE8,0xA1,0xFA,0xF8,0xC3,0xAC,0x49,
6300xE8,0xAF,0xFB,0xF8,0xC3,0x90,0xAC,0x49,0xE8,0x15,0xFD,0xF8,0xC3,0x90,0xAC,0x49,
6310xE8,0x67,0xFD,0xF8,0xC3,0x90,0xAC,0x49,0xE8,0x1F,0xFD,0xF8,0xC3,0x90,0xAC,0x49,
6320xE6,0x34,0xF8,0xC3,0xAC,0x49,0xE6,0x36,0xF8,0xC3,0xAC,0x49,0x3C,0x02,0x77,0x1F,
6330x84,0xC0,0x75,0x1D,0xE4,0x14,0x24,0xEF,0xE6,0x14,0xE4,0x12,0x24,0x3F,0xE6,0x12,
6340xE4,0x16,0xA8,0x04,0x74,0x09,0xE8,0xEA,0xF9,0x72,0x04,0xB0,0x18,0xE6,0x0A,0xF8,
6350xC3,0x8A,0xE0,0xE4,0x14,0x0C,0x10,0xE6,0x14,0xE4,0x12,0x0C,0xC0,0xF6,0xC4,0x01,
6360x74,0x02,0x24,0x7F,0xE6,0x12,0xF8,0xC3,0xAC,0x49,0xE8,0x25,0xFD,0xF8,0xC3,0x90,
6370xB8,0x00,0x40,0xE8,0x7D,0xFD,0xE8,0xB4,0xFD,0xE8,0xA8,0xFE,0xB0,0x01,0xE8,0xB9,
6380xFE,0xF8,0xC3,0x90,0xB8,0x00,0x40,0xE8,0x85,0xFD,0xE8,0xA0,0xFD,0xF8,0xC3,0x90,
6390xB8,0x00,0x10,0xE8,0x5D,0xFD,0xE8,0x94,0xFD,0xE8,0x88,0xFE,0xB0,0x08,0xE8,0x99,
6400xFE,0xF8,0xC3,0x90,0xB8,0x00,0x10,0xE8,0x65,0xFD,0xE8,0x80,0xFD,0xF8,0xC3,0x90,
6410xB8,0x00,0x80,0xE8,0x3D,0xFD,0xE8,0x74,0xFD,0xE8,0x68,0xFE,0xB0,0x02,0xE8,0x79,
6420xFE,0xF8,0xC3,0x90,0xB8,0x00,0x80,0xE8,0x45,0xFD,0xE8,0x60,0xFD,0xF8,0xC3,0x90,
6430xB8,0x00,0x20,0xE8,0x1D,0xFD,0xE8,0x54,0xFD,0xE8,0x48,0xFE,0xB0,0x04,0xE8,0x59,
6440xFE,0xF8,0xC3,0x90,0xB8,0x00,0x20,0xE8,0x25,0xFD,0xE8,0x40,0xFD,0xF8,0xC3,0x90,
6450xAC,0x49,0xE8,0x48,0x14,0xE4,0x3C,0x24,0xE7,0x0A,0xC4,0xE6,0x3C,0xF8,0xC3,0x90,
6460xB8,0xFC,0x3B,0x89,0x46,0x7C,0xE4,0x3C,0x0C,0x18,0xE6,0x3C,0xF8,0xC3,0xE4,0x12,
6470x0C,0x02,0xE6,0x12,0xF8,0xC3,0xE4,0x12,0x24,0xFD,0xEB,0xF6,0xE8,0xB5,0xFC,0xF8,
6480xC3,0x90,0x83,0x66,0x38,0xFD,0xF8,0xC3,0xAC,0x49,0xA8,0x01,0x74,0x06,0x83,0x4E,
6490x7A,0x20,0xEB,0x04,0x83,0x66,0x7A,0xDF,0xE8,0xCB,0xFB,0xF8,0xC3,0x90,0x8A,0x86,
6500xA5,0x00,0x0C,0x02,0x24,0xFB,0x88,0x86,0xA5,0x00,0xE6,0x0C,0x81,0x4E,0x26,0x01,
6510x20,0xAC,0x49,0x32,0xE4,0x89,0x46,0x6E,0x83,0x4E,0x48,0x08,0x49,0x46,0xF9,0xC3,
6520x8A,0x86,0xA5,0x00,0x0C,0x02,0x24,0xFB,0x88,0x86,0xA5,0x00,0xE6,0x0C,0x81,0x4E,
6530x26,0x01,0x20,0xAC,0xB4,0x0A,0xF6,0xE4,0xEB,0xD8,0xE8,0xFA,0x13,0xE4,0x3C,0x24,
6540xF8,0x0A,0xC4,0xE6,0x3C,0xF8,0xC3,0x90,0xAD,0x49,0x49,0x89,0x46,0x64,0xA9,0x01,
6550x00,0x74,0x1B,0x8B,0xD8,0x83,0xE3,0xFA,0x75,0x1A,0xA9,0x04,0x00,0x74,0x0F,0xE4,
6560x3E,0x0C,0x02,0xE6,0x3E,0xB8,0x38,0x44,0x89,0x46,0x62,0xF8,0xC3,0x90,0xE4,0x3E,
6570x24,0xFC,0xEB,0xEF,0xE4,0x3E,0x24,0xFC,0xE6,0x3E,0xE8,0xE8,0xFC,0xB8,0xAA,0x40,
6580xEB,0xE6,0xE8,0x6E,0xF8,0x72,0x05,0xB0,0x18,0xE6,0x0A,0xF8,0xC3,0x90,0xAC,0x49,
6590xE8,0xCF,0xF9,0xF8,0xC3,0x90,0xAC,0x49,0xE8,0xCF,0xF9,0xF8,0xC3,0x90,0xE8,0x68,
6600xFD,0x75,0x06,0x32,0xC0,0xE6,0xDA,0xF8,0xC3,0xB0,0x02,0xE6,0xDA,0x36,0xA0,0xB4,
6610x13,0x24,0x10,0x34,0x10,0xE8,0x16,0x01,0x36,0xA1,0xB4,0x13,0xA9,0x01,0x00,0x74,
6620x05,0xE8,0xFC,0xFE,0xEB,0x0E,0xA9,0x02,0x00,0x74,0x04,0x32,0xC0,0xEB,0x02,0xB0,
6630x01,0xE8,0xDE,0xFE,0x36,0xA1,0xB4,0x13,0xE8,0xB5,0x13,0xE4,0x3C,0x24,0xF8,0x0A,
6640xC4,0xE6,0x3C,0x36,0xA1,0xB4,0x13,0xC1,0xE8,0x05,0x25,0x01,0x00,0xE8,0xFA,0xFE,
6650x36,0xA0,0xB5,0x13,0x24,0x10,0xE8,0x59,0xFB,0x32,0xC0,0x36,0x8A,0x26,0xB5,0x13,
6660xF6,0xC4,0x04,0x74,0x09,0xFE,0xC0,0xF6,0xC4,0x08,0x74,0x02,0xFE,0xC0,0xE8,0xDB,
6670xFD,0x36,0xA1,0xB6,0x13,0x25,0x0F,0x00,0xE8,0x57,0xF9,0x36,0xA1,0xB6,0x13,0xC1,
6680xE8,0x04,0x25,0x03,0x00,0xE8,0xB8,0xFA,0x36,0xA1,0xB6,0x13,0xC1,0xE8,0x05,0x25,
6690x02,0x00,0xE8,0x05,0xFB,0x36,0xA1,0xB6,0x13,0xF6,0xC4,0x01,0x75,0x04,0x32,0xC0,
6700xEB,0x09,0x80,0xE4,0x02,0xD0,0xEC,0xB0,0x02,0x2A,0xC4,0xE8,0xAC,0xFA,0x36,0xF6,
6710x06,0xB7,0x13,0x40,0x74,0x05,0xE8,0x83,0xFE,0xEB,0x03,0xE8,0x84,0xFE,0x36,0xF6,
6720x06,0xB7,0x13,0x20,0x74,0x05,0xE8,0x65,0xFE,0xEB,0x03,0xE8,0x68,0xFE,0xF8,0xC3,
6730xE4,0x12,0x0C,0x01,0xE6,0x12,0xF8,0xC3,0xE4,0x12,0x24,0xFE,0xEB,0xF6,0xE4,0x14,
6740x24,0xF0,0x0C,0x05,0xE6,0x14,0xE4,0x2A,0x24,0xF0,0x0C,0x06,0xE6,0x2A,0xF8,0xC3,
6750xE4,0x2A,0x24,0xF0,0xE6,0x2A,0xE4,0x14,0x24,0xF0,0x0C,0x07,0xE6,0x14,0xF8,0xC3,
6760xAD,0x49,0x49,0xE8,0x64,0xF9,0x89,0x86,0x8E,0x00,0xF8,0xC3,0xAD,0x49,0x49,0xE8,
6770x58,0xF9,0x89,0x86,0x90,0x00,0xF8,0xC3,0x83,0x4E,0x26,0x04,0xE8,0xA8,0xF7,0xF8,
6780xC3,0x90,0x83,0x66,0x26,0xFB,0xE8,0x9E,0xF7,0xF8,0xC3,0x90,0xAC,0x49,0x84,0xC0,
6790x75,0x0D,0xE4,0x10,0x24,0xEF,0xE6,0x10,0x80,0x8E,0xA1,0x00,0x42,0xF8,0xC3,0xE4,
6800x10,0x0C,0x10,0xEB,0xF1,0x90,0xAC,0x49,0x3C,0x02,0x76,0x02,0x32,0xC0,0xC0,0xE0,
6810x04,0xA8,0x20,0x74,0x02,0x0C,0x08,0x24,0x18,0x8A,0xE0,0xE4,0x12,0x24,0xE7,0x0A,
6820xC4,0xE6,0x12,0x80,0x8E,0xA1,0x00,0x44,0xF8,0xC3,0xAC,0x49,0x88,0x86,0xC0,0x00,
6830xF8,0xC3,0xAC,0x49,0xE6,0x3A,0xF8,0xC3,0xAC,0x49,0x84,0xC0,0x74,0x08,0xE4,0x12,
6840x0C,0x04,0xE6,0x12,0xF8,0xC3,0xE4,0x12,0x24,0xFB,0xEB,0xF6,0xAC,0x49,0xE8,0xD6,
6850xF6,0x73,0x03,0xE8,0x27,0xF7,0xF8,0xC3,0xE4,0x12,0xA8,0x02,0x74,0x04,0x24,0xFD,
6860xE6,0x12,0xB8,0xF0,0x00,0xE8,0x87,0xFA,0x81,0x66,0x26,0xFF,0xF3,0xE8,0x57,0xF7,
6870xE8,0x9A,0xFA,0xF8,0xC3,0x90,0xB8,0x80,0x00,0xE8,0x57,0xFA,0x80,0x4E,0x27,0x08,
6880xE8,0x44,0xF7,0xE8,0x87,0xFA,0xF8,0xC3,0xB8,0x80,0x00,0xE8,0x61,0xFA,0x81,0x66,
6890x26,0xFF,0xF7,0xE8,0x31,0xF7,0xE8,0x74,0xFA,0xF8,0xC3,0x90,0xB8,0x10,0x00,0xE8,
6900x31,0xFA,0x80,0x4E,0x27,0x04,0xE8,0x1E,0xF7,0xE8,0x61,0xFA,0xF8,0xC3,0xB8,0x10,
6910x00,0xE8,0x3B,0xFA,0x81,0x66,0x26,0xFF,0xFB,0xE8,0x0B,0xF7,0xE8,0x4E,0xFA,0xF8,
6920xC3,0x90,0x33,0xC0,0xAC,0x49,0x3C,0x01,0x73,0x04,0xB0,0x01,0xEB,0x06,0x3C,0x0C,
6930x76,0x02,0xB0,0x0C,0x89,0x46,0x1C,0xF8,0xC3,0x90,0x81,0x4E,0x26,0x00,0x20,0x8A,
6940x86,0xA5,0x00,0x0C,0x02,0x24,0xFB,0x88,0x86,0xA5,0x00,0xE6,0x0C,0x83,0x4E,0x26,
6950x01,0xF8,0xC3,0x90,0x81,0x4E,0x26,0x00,0x40,0x8A,0x86,0xA5,0x00,0x0C,0x02,0x88,
6960x86,0xA5,0x00,0xE6,0x0C,0xF8,0xC3,0x90,0xAC,0x49,0x50,0xE8,0x05,0xF6,0x58,0x72,
6970x08,0xE6,0x38,0xB0,0x23,0xE6,0x0A,0xF8,0xC3,0xF9,0xC3,0x90,0xAC,0x50,0xAD,0xE8,
6980x82,0xF8,0x5A,0xF6,0xC2,0x01,0x74,0x12,0x39,0x86,0x96,0x00,0x74,0x0C,0x89,0x86,
6990x96,0x00,0xE6,0xF0,0x86,0xE0,0xE6,0xF8,0x86,0xE0,0xF6,0xC2,0x02,0x74,0x10,0x39,
7000x86,0x94,0x00,0x74,0x0A,0x89,0x86,0x94,0x00,0xE6,0xE4,0x86,0xE0,0xE6,0xEC,0x83,
7010xE9,0x03,0xC3,0x90,0xE4,0x16,0x88,0x86,0xBC,0x00,0xE8,0xE6,0xFA,0x33,0xDB,0xE4,
7020x0C,0xA8,0x06,0x74,0x03,0x80,0xCB,0x01,0xA8,0x10,0x74,0x03,0x80,0xCB,0x02,0xA8,
7030x80,0x74,0x03,0x80,0xCB,0x04,0xE4,0x12,0x8A,0xE0,0x24,0x18,0x0A,0xD8,0xE4,0xDA,
7040xF6,0xC4,0x02,0x74,0x07,0xA8,0x40,0x75,0x03,0x80,0xCB,0x20,0xA8,0x02,0x75,0x09,
7050xE4,0x2A,0xA8,0x0F,0x74,0x03,0x80,0xCB,0x40,0xF7,0x46,0x38,0x02,0x00,0x74,0x09,
7060xE4,0xD8,0xA8,0x01,0x75,0x03,0x80,0xCB,0x80,0x88,0x9E,0xBE,0x00,0xFE,0x86,0xB4,
7070x00,0xB0,0x0A,0xE8,0x5C,0xE4,0xF8,0xC3,0xAC,0x49,0x3C,0x02,0x74,0x41,0x77,0x1F,
7080x50,0xE8,0x4F,0xF5,0x58,0x72,0x0C,0x84,0xC0,0x74,0x0A,0xB0,0x12,0xE6,0x0A,0x80,
7090x4E,0x38,0x01,0xF8,0xC3,0xB0,0x11,0xE6,0x0A,0x80,0x66,0x38,0xFE,0xF8,0xC3,0x8B,
7100x46,0x38,0x25,0xFF,0xF7,0x89,0x46,0x38,0xA9,0x00,0x04,0x75,0xE6,0x8A,0x86,0xA5,
7110x00,0xA8,0x10,0x75,0xDE,0x0C,0x10,0x88,0x86,0xA5,0x00,0xE6,0x0C,0xF8,0xC3,0x81,
7120x4E,0x38,0x00,0x08,0x8A,0x86,0xA5,0x00,0xA8,0x10,0x74,0xC7,0x24,0xEF,0xEB,0xE7,
7130xAD,0x49,0x49,0x3C,0x01,0x72,0x11,0x3C,0x0C,0x77,0x0D,0x50,0x8A,0xE0,0xE4,0x14,
7140x25,0xF0,0x0F,0x0A,0xC4,0xE6,0x14,0x58,0x8A,0xC4,0x84,0xC0,0x74,0x02,0xE6,0x42,
7150xF8,0xC3,0xE8,0xCF,0xF9,0xFE,0x86,0xB9,0x00,0xB0,0x0E,0xE8,0xD4,0xE3,0xF8,0xC3,
7160x3A,0x86,0xAF,0x00,0x74,0x1F,0x88,0x86,0xAF,0x00,0x8A,0xE0,0x80,0xC2,0x06,0xB0,
7170xBF,0xEE,0x80,0xEA,0x02,0x8A,0xC4,0xEE,0x8A,0x86,0xA8,0x00,0x80,0xC2,0x02,0xEE,
7180x80,0xEA,0x06,0x8A,0xC4,0xC3,0x8B,0x46,0x3E,0x85,0xC0,0x8A,0x86,0xA5,0x00,0x74,
7190x12,0xA8,0x08,0x75,0x0D,0x0C,0x08,0x88,0x86,0xA5,0x00,0x80,0xC2,0x02,0xEE,0x80,
7200xEA,0x02,0xC3,0xA8,0x08,0x74,0xFB,0x24,0xF7,0xEB,0xEC,0x8B,0x46,0x26,0x84,0xC0,
7210x74,0x16,0x8A,0x86,0xA5,0x00,0xA8,0x02,0x74,0x0D,0x24,0xFD,0x88,0x86,0xA5,0x00,
7220x83,0xC2,0x02,0xEE,0x83,0xEA,0x02,0xC3,0x8A,0x86,0xA5,0x00,0xA8,0x02,0x75,0xF7,
7230x0C,0x02,0xEB,0xE8,0x52,0x83,0xC2,0x0C,0xEC,0xC0,0xE8,0x04,0x88,0x86,0xA9,0x00,
7240x8B,0x5E,0x26,0x80,0xE3,0x3F,0xF6,0xC7,0x04,0x74,0x07,0xA8,0x08,0x75,0x03,0x80,
7250xCB,0x40,0xF6,0xC7,0x08,0x74,0x07,0xA8,0x02,0x75,0x03,0x80,0xCB,0x80,0x88,0x5E,
7260x26,0x8A,0x86,0xA5,0x00,0x84,0xDB,0x74,0x10,0xA8,0x02,0x74,0x0A,0x24,0xFD,0x88,
7270x86,0xA5,0x00,0x83,0xEA,0x0A,0xEE,0x5A,0xC3,0xA8,0x02,0x75,0xFA,0x0C,0x02,0xEB,
7280xEE,0x90,0xFF,0xFF,0x00,0x48,0x00,0x30,0xBA,0x20,0xC4,0x1A,0x00,0x18,0x00,0x12,
7290x00,0x0C,0x00,0x06,0x00,0x03,0x00,0x02,0x80,0x01,0xC0,0x00,0x60,0x00,0x30,0x00,
7300x18,0x00,0xCD,0x01,0x00,0x01,0x80,0x00,0x10,0x00,0x10,0x00,0x0E,0x00,0x0C,0x00,
7310x08,0x00,0x00,0x00,0x00,0x00,0x06,0x00,0x04,0x00,0x03,0x00,0x02,0x00,0x01,0x00,
7320x52,0x51,0x56,0x3C,0x1E,0x77,0x47,0x98,0x8B,0xF0,0x8A,0x82,0xC4,0x00,0x32,0xE4,
7330x83,0xFE,0x18,0x74,0x3D,0x83,0xFE,0x19,0x74,0x3E,0x83,0xFE,0x1E,0x77,0x2F,0xD1,
7340xE6,0x2E,0x8B,0x8C,0x32,0x2D,0x3B,0x8E,0x94,0x00,0x74,0x22,0x89,0x8E,0x94,0x00,
7350x83,0xC2,0x06,0x8A,0x86,0xA8,0x00,0x8A,0xE0,0x0C,0x80,0xEE,0x83,0xEA,0x06,0x8A,
7360xC1,0xEE,0x83,0xC2,0x02,0x8A,0xC5,0xEE,0x83,0xC2,0x04,0x8A,0xC4,0xEE,0x5E,0x59,
7370x5A,0xC3,0x8B,0x8E,0x8E,0x00,0xEB,0xCE,0x8B,0x8E,0x90,0x00,0xEB,0xC8,0x52,0x51,
7380x3D,0x05,0x00,0x77,0x03,0xB8,0x05,0x00,0x8B,0xC8,0xBA,0x02,0x00,0xB8,0x00,0xD0,
7390xF7,0xF1,0x05,0x01,0x00,0xD1,0xE8,0x59,0x5A,0xC3,0x8B,0x46,0x7A,0xA8,0x20,0x74,
7400x0B,0x80,0xBE,0xC3,0x00,0x03,0x75,0x04,0x0C,0x01,0xEB,0x02,0x24,0xFE,0x89,0x46,
7410x7A,0xC3,0x24,0x03,0x88,0x86,0xC3,0x00,0x8A,0xA6,0xA8,0x00,0x8A,0xDC,0x80,0xE4,
7420xFC,0x0A,0xC4,0x3A,0xC3,0x74,0x0B,0x88,0x86,0xA8,0x00,0x83,0xC2,0x06,0xEE,0x83,
7430xEA,0x06,0xE8,0xC5,0xFF,0xC3,0x00,0x08,0x18,0x38,0x28,0x90,0x3C,0x04,0x77,0x23,
7440x32,0xE4,0x8B,0xD8,0x2E,0x8A,0x87,0x26,0x2E,0x8A,0xA6,0xA8,0x00,0x8A,0xDC,0x80,
7450xE4,0xC7,0x0A,0xC4,0x3A,0xC3,0x74,0x0B,0x88,0x86,0xA8,0x00,0x83,0xC2,0x06,0xEE,
7460x83,0xEA,0x06,0xC3,0x84,0xC0,0x74,0x02,0xB0,0x04,0x8A,0xA6,0xA8,0x00,0x8A,0xDC,
7470x80,0xE4,0xFB,0x0A,0xC4,0x3A,0xC3,0x74,0x0B,0x88,0x86,0xA8,0x00,0x83,0xC2,0x06,
7480xEE,0x83,0xEA,0x06,0xC3,0x90,0x8B,0x5E,0x38,0x84,0xC0,0x74,0x34,0x3C,0x02,0x74,
7490x3B,0x8A,0x86,0xAF,0x00,0x0C,0x04,0xE8,0xE6,0xFD,0x8B,0x46,0x2E,0x3B,0x46,0x3C,
7500x77,0x1B,0xF7,0xC3,0x00,0x04,0x75,0x15,0x81,0xCB,0x00,0x04,0x83,0xC2,0x02,0x8A,
7510x86,0xA5,0x00,0x24,0xFA,0x88,0x86,0xA5,0x00,0xEE,0x83,0xEA,0x02,0x89,0x5E,0x38,
7520xC3,0x8A,0x86,0xAF,0x00,0x24,0xFB,0xE8,0xB6,0xFD,0xEB,0xF1,0xF7,0xC3,0x10,0x00,
7530x74,0xEF,0xEB,0xED,0x83,0xC2,0x0C,0xEC,0x83,0xEA,0x0C,0xC0,0xE8,0x04,0x88,0x86,
7540xA9,0x00,0xC3,0x90,0x8A,0x86,0xA7,0x00,0x0C,0x01,0x88,0x86,0xA7,0x00,0x8B,0xDA,
7550x80,0xC2,0x08,0xEE,0x8B,0xD3,0xF8,0xC3,0x8A,0x86,0xA7,0x00,0x24,0xFE,0xEB,0xEA,
7560x8A,0x86,0xA7,0x00,0x0C,0x02,0xEB,0xE2,0x8A,0x86,0xA7,0x00,0x24,0xFD,0xEB,0xDA,
7570xB0,0xFF,0xE8,0x52,0xF2,0xE8,0x97,0xF2,0xF8,0xC3,0xAC,0x49,0xE8,0x61,0xFE,0xF8,
7580xC3,0x90,0xAC,0x49,0xE8,0xEB,0xFE,0xF8,0xC3,0x90,0xAC,0x49,0xE8,0x35,0xFF,0xF8,
7590xC3,0x90,0xAC,0x49,0xE8,0x05,0xFF,0xF8,0xC3,0x90,0x52,0x83,0xC2,0x06,0xB0,0xBF,
7600xEE,0x52,0x83,0xC2,0x02,0xAC,0x49,0xEE,0x5A,0x8A,0x86,0xA8,0x00,0xEE,0x5A,0xF8,
7610xC3,0x90,0x52,0x83,0xC2,0x06,0xB0,0xBF,0xEE,0x52,0x83,0xC2,0x06,0xEB,0xE6,0x90,
7620xAC,0x49,0x3C,0x02,0x77,0x0D,0x84,0xC0,0x75,0x0B,0x8A,0x86,0xAF,0x00,0x24,0xFD,
7630xE8,0x0D,0xFD,0xF8,0xC3,0x50,0x8A,0x86,0xAF,0x00,0x0C,0x02,0xE8,0x01,0xFD,0x5B,
7640x83,0xC2,0x08,0x8A,0x86,0xA7,0x00,0xF6,0xC3,0x01,0x74,0x0C,0x24,0xDF,0x88,0x86,
7650xA7,0x00,0xEE,0x83,0xEA,0x08,0xF8,0xC3,0x0C,0x20,0xEB,0xF2,0xAC,0x49,0xE8,0xE5,
7660xFE,0xF8,0xC3,0x90,0xB8,0x00,0x40,0xE8,0x69,0xF5,0xE8,0xF9,0xFC,0xE8,0x24,0xFF,
7670xB0,0x01,0xE8,0xA5,0xF6,0xF8,0xC3,0x90,0xB8,0x00,0x40,0xE8,0x71,0xF5,0xE8,0xE5,
7680xFC,0xF8,0xC3,0x90,0xB8,0x00,0x10,0xE8,0x49,0xF5,0xE8,0xD9,0xFC,0xE8,0x04,0xFF,
7690xB0,0x08,0xE8,0x85,0xF6,0xF8,0xC3,0x90,0xB8,0x00,0x10,0xE8,0x51,0xF5,0xE8,0xC5,
7700xFC,0xF8,0xC3,0x90,0xB8,0x00,0x80,0xE8,0x29,0xF5,0xE8,0xB9,0xFC,0xE8,0xE4,0xFE,
7710xB0,0x02,0xE8,0x65,0xF6,0xF8,0xC3,0x90,0xB8,0x00,0x80,0xE8,0x31,0xF5,0xE8,0xA5,
7720xFC,0xF8,0xC3,0x90,0xB8,0x00,0x20,0xE8,0x09,0xF5,0xE8,0x99,0xFC,0xE8,0xC4,0xFE,
7730xB0,0x04,0xE8,0x45,0xF6,0xF8,0xC3,0x90,0xB8,0x00,0x20,0xE8,0x11,0xF5,0xE8,0x85,
7740xFC,0xF8,0xC3,0x90,0xAC,0x49,0xE8,0x34,0x0C,0xF8,0xC3,0x90,0xB8,0xFC,0x3B,0x89,
7750x46,0x7C,0xF8,0xC3,0x8A,0x86,0xAF,0x00,0x0C,0x80,0xE8,0x43,0xFC,0xF8,0xC3,0x90,
7760x8A,0x86,0xAF,0x00,0x24,0x7F,0xEB,0xF2,0x8A,0x86,0xAF,0x00,0x0C,0x40,0xE8,0x2F,
7770xFC,0xF8,0xC3,0x90,0x8A,0x86,0xAF,0x00,0x24,0xBF,0xEB,0xF2,0xAC,0x49,0xA8,0x01,
7780x74,0x07,0x83,0x4E,0x7A,0x20,0xEB,0x05,0x90,0x83,0x66,0x7A,0xDF,0xE8,0x8A,0xFD,
7790xF8,0xC3,0x83,0xC2,0x06,0x8A,0x86,0xA8,0x00,0x0C,0x40,0x88,0x86,0xA8,0x00,0xEE,
7800x83,0xEA,0x06,0xAC,0x49,0x32,0xE4,0x89,0x46,0x6E,0x83,0x4E,0x26,0x01,0x83,0x4E,
7810x48,0x08,0xB0,0x06,0xE8,0xBB,0xDF,0x49,0x46,0xF9,0xC3,0x90,0x83,0xC2,0x06,0x8A,
7820x86,0xA8,0x00,0x0C,0x40,0x88,0x86,0xA8,0x00,0xEE,0x83,0xEA,0x06,0xAC,0xB4,0x0A,
7830xF6,0xE4,0xEB,0xD0,0xE8,0xE0,0x0B,0xF8,0xC3,0x90,0xAD,0x49,0x49,0x89,0x46,0x64,
7840xA9,0x01,0x00,0x74,0x19,0x8B,0xD8,0x83,0xE3,0xFA,0x75,0x0A,0xA9,0x04,0x00,0x74,
7850x0D,0xB8,0xE2,0x3F,0xEB,0x0B,0xE8,0xEC,0xF4,0xB8,0xAA,0x40,0xEB,0x03,0xB8,0x38,
7860x44,0x89,0x46,0x62,0xF8,0xC3,0x8A,0x86,0xAF,0x00,0xA8,0x02,0x74,0x0A,0x24,0xFD,
7870xE8,0x8D,0xFB,0x0C,0x02,0xE8,0x88,0xFB,0xF8,0xC3,0xAC,0x49,0xE8,0x81,0xFC,0xF8,
7880xC3,0x90,0xAC,0x49,0xE8,0x79,0xFC,0xF8,0xC3,0x90,0xE8,0x5C,0xF5,0x75,0x05,0xE8,
7890xE6,0xFD,0xF8,0xC3,0xE8,0xCD,0xFD,0x36,0xA0,0xB4,0x13,0x24,0x10,0x34,0x10,0xE8,
7900x26,0x01,0x36,0xA1,0xB4,0x13,0xA9,0x01,0x00,0x74,0x05,0xE8,0xFE,0xFE,0xEB,0x0E,
7910xA9,0x02,0x00,0x74,0x04,0x32,0xC0,0xEB,0x02,0xB0,0x01,0xE8,0xE8,0xFE,0x36,0xA1,
7920xB4,0x13,0xE8,0xAB,0x0B,0x36,0xA1,0xB4,0x13,0xC1,0xE8,0x05,0x25,0x01,0x00,0xE8,
7930x0C,0xFF,0x36,0xA0,0xB5,0x13,0x24,0x10,0xE8,0x2B,0xFD,0x32,0xC0,0x36,0x8A,0x26,
7940xB5,0x13,0xF6,0xC4,0x04,0x74,0x09,0xFE,0xC0,0xF6,0xC4,0x08,0x74,0x02,0xFE,0xC0,
7950xE8,0xEF,0xFD,0x36,0xA1,0xB6,0x13,0x25,0x0F,0x00,0xE8,0x03,0xFC,0x36,0xA1,0xB6,
7960x13,0xC1,0xE8,0x04,0x25,0x03,0x00,0xE8,0x88,0xFC,0x36,0xA1,0xB6,0x13,0xC1,0xE8,
7970x05,0x25,0x02,0x00,0xE8,0xCD,0xFC,0x36,0xA1,0xB6,0x13,0xF6,0xC4,0x01,0x75,0x04,
7980x32,0xC0,0xEB,0x09,0x80,0xE4,0x02,0xD0,0xEC,0xB0,0x02,0x2A,0xC4,0xE8,0x8C,0xFC,
7990x36,0xF6,0x06,0xB7,0x13,0x40,0x74,0x05,0xE8,0x8D,0xFE,0xEB,0x03,0xE8,0x94,0xFE,
8000x36,0xF6,0x06,0xB7,0x13,0x20,0x74,0x05,0xE8,0x69,0xFE,0xEB,0x03,0xE8,0x70,0xFE,
8010xF8,0xC3,0xF8,0xC3,0x8B,0x46,0x38,0xA9,0x04,0x00,0x75,0x23,0x0D,0x04,0x00,0x89,
8020x46,0x38,0x83,0xC2,0x08,0x8B,0x46,0x2E,0x3B,0x46,0x3C,0x73,0x14,0x83,0x4E,0x38,
8030x10,0x8A,0x86,0xA7,0x00,0x24,0xFE,0x88,0x86,0xA7,0x00,0xEE,0x83,0xEA,0x08,0xF8,
8040xC3,0x8A,0x86,0xA7,0x00,0x0C,0x01,0xEB,0xEE,0x90,0x8B,0x46,0x38,0xA9,0x04,0x00,
8050x74,0x06,0x25,0xFB,0xFF,0x89,0x46,0x38,0xF8,0xC3,0xAD,0x49,0x49,0xE8,0xBE,0xFB,
8060x89,0x86,0x8E,0x00,0xF8,0xC3,0xAD,0x49,0x49,0xE8,0xB2,0xFB,0x89,0x86,0x90,0x00,
8070xF8,0xC3,0x83,0x4E,0x26,0x04,0xE8,0x92,0xFA,0xF8,0xC3,0x90,0x83,0x66,0x26,0xFB,
8080xE8,0x88,0xFA,0xF8,0xC3,0x90,0xAC,0x49,0x84,0xC0,0x75,0x07,0x80,0x8E,0xA3,0x00,
8090x04,0xF8,0xC3,0x80,0xA6,0xA3,0x00,0xFB,0xF8,0xC3,0xAC,0x49,0x83,0xC2,0x08,0x3C,
8100x02,0x76,0x02,0x32,0xC0,0x3C,0x01,0x74,0x12,0x77,0x0B,0x8A,0x86,0xA7,0x00,0x24,
8110xEF,0x88,0x86,0xA7,0x00,0xEE,0x83,0xEA,0x08,0xF8,0xC3,0x8A,0x86,0xA7,0x00,0x0C,
8120x10,0xEB,0xEE,0x90,0x52,0x83,0xC2,0x06,0xB0,0xBF,0xEE,0x52,0x83,0xC2,0x04,0xAC,
8130x49,0xEE,0x5A,0x8A,0x86,0xA8,0x00,0xEE,0x5A,0xF8,0xC3,0x90,0x52,0x83,0xC2,0x06,
8140xB0,0xBF,0xEE,0x52,0x83,0xC2,0x08,0xEB,0xE6,0x90,0xAC,0x49,0xF8,0xC3,0xAC,0x49,
8150xE8,0xB4,0xEE,0x73,0x03,0xE8,0xF7,0xEE,0xF8,0xC3,0x8A,0x86,0xAF,0x00,0x24,0x7F,
8160xE8,0xBD,0xF9,0xB8,0xF0,0x00,0xE8,0x66,0xF2,0x81,0x66,0x26,0xFF,0xF3,0xE8,0x23,
8170xFA,0xE8,0xD2,0xF9,0xF8,0xC3,0xB8,0x80,0x00,0xE8,0x37,0xF2,0x80,0x4E,0x27,0x08,
8180xE8,0x11,0xFA,0xE8,0xC0,0xF9,0xF8,0xC3,0xB8,0x80,0x00,0xE8,0x41,0xF2,0x81,0x66,
8190x26,0xFF,0xF7,0xE8,0xFE,0xF9,0xE8,0xAD,0xF9,0xF8,0xC3,0x90,0xB8,0x10,0x00,0xE8,
8200x11,0xF2,0x80,0x4E,0x27,0x04,0xE8,0xEB,0xF9,0xE8,0x9A,0xF9,0xF8,0xC3,0xB8,0x10,
8210x00,0xE8,0xFF,0xF1,0x81,0x66,0x26,0xFF,0xFB,0xE8,0xD8,0xF9,0xF8,0xC3,0xAC,0x49,
8220xF8,0xC3,0x83,0xC2,0x06,0x8A,0x86,0xA8,0x00,0x0C,0x40,0x88,0x86,0xA8,0x00,0xEE,
8230x83,0xEA,0x06,0xF8,0xC3,0x90,0x83,0xC2,0x06,0x8A,0x86,0xA8,0x00,0x24,0xBF,0xEB,
8240xEA,0x90,0xAC,0x49,0x8A,0xE0,0x80,0xC2,0x0A,0xEC,0x80,0xEA,0x0A,0xA8,0x20,0x74,
8250x05,0x8A,0xC4,0xEE,0xF8,0xC3,0x06,0x51,0x57,0x8B,0x4E,0x24,0xE3,0x34,0x49,0x89,
8260x4E,0x24,0xFF,0x46,0x1A,0x8E,0x46,0x02,0x8B,0x7E,0x22,0x8A,0xC4,0xAA,0x89,0x7E,
8270x22,0x8B,0x46,0x26,0x24,0xFD,0x89,0x46,0x26,0x75,0x29,0x8A,0x86,0xA5,0x00,0xA8,
8280x02,0x75,0x21,0x80,0xC2,0x02,0x0C,0x02,0x88,0x86,0xA5,0x00,0xEE,0x80,0xEA,0x02,
8290xEB,0x12,0xC4,0x7E,0x00,0x3B,0x7E,0x1E,0x76,0x0A,0x4F,0x26,0x88,0x25,0x89,0x7E,
8300x00,0xFF,0x46,0x1A,0x5F,0x59,0x07,0xF8,0xC3,0x90,0xAC,0xAD,0x83,0xE9,0x03,0x85,
8310xC0,0x74,0x05,0x3D,0x00,0x20,0x72,0x05,0xB8,0xFF,0xFF,0xEB,0x03,0xC1,0xE0,0x03,
8320x3B,0x86,0x94,0x00,0x74,0x26,0x89,0x86,0x94,0x00,0x8B,0xD8,0x52,0x83,0xC2,0x06,
8330x8A,0x86,0xA8,0x00,0x8A,0xE0,0x0C,0x80,0xEE,0x83,0xEA,0x06,0x8A,0xC3,0xEE,0x83,
8340xC2,0x02,0x8A,0xC7,0xEE,0x83,0xC2,0x04,0x8A,0xC4,0xEE,0x5A,0xF8,0xC3,0xB0,0x88,
8350x88,0x86,0xBC,0x00,0xE8,0x8C,0xF2,0x33,0xDB,0x8A,0x86,0xA5,0x00,0xA8,0x02,0x74,
8360x03,0x80,0xCB,0x01,0xA8,0x05,0x74,0x03,0x80,0xCB,0x02,0xA8,0x08,0x74,0x03,0x80,
8370xCB,0x04,0xF6,0x86,0xA7,0x00,0x10,0x74,0x03,0x80,0xCB,0x10,0x8A,0x86,0xA9,0x00,
8380xF6,0xC3,0x04,0x75,0x0A,0x83,0xC2,0x0C,0xEC,0x83,0xEA,0x0C,0xC0,0xE8,0x04,0x8A,
8390xE0,0x8A,0x86,0xAF,0x00,0xA8,0x80,0x74,0x08,0xF6,0xC4,0x01,0x75,0x03,0x80,0xCB,
8400x20,0xF6,0x86,0xA7,0x00,0x02,0x75,0x0A,0xF7,0x46,0x38,0x04,0x00,0x74,0x03,0x80,
8410xCB,0x40,0x88,0x9E,0xBE,0x00,0xFE,0x86,0xB4,0x00,0xB0,0x0A,0xE8,0xF3,0xDB,0xF8,
8420xC3,0xFE,0x86,0xB4,0x00,0xB0,0x0A,0xE8,0xE8,0xDB,0xF8,0xC3,0xAC,0x49,0x3C,0x02,
8430x74,0x37,0x77,0x10,0x84,0xC0,0x74,0x06,0x80,0x4E,0x38,0x01,0xF8,0xC3,0x80,0x66,
8440x38,0xFE,0xF8,0xC3,0x8B,0x46,0x38,0x25,0xFF,0xF7,0x89,0x46,0x38,0xA9,0x00,0x04,
8450x75,0xEA,0x8A,0x86,0xA5,0x00,0xA8,0x01,0x75,0xE2,0x0C,0x05,0x83,0xC2,0x02,0x88,
8460x86,0xA5,0x00,0xEE,0x83,0xEA,0x02,0xF8,0xC3,0x81,0x4E,0x38,0x00,0x08,0x8A,0x86,
8470xA5,0x00,0xA8,0x01,0x74,0xC6,0x24,0xFA,0xEB,0xE2,0xAD,0x49,0x49,0xF8,0xC3,0x90,
8480xE8,0x11,0xFA,0xFE,0x86,0xB9,0x00,0xB0,0x0E,0xE8,0x86,0xDB,0xF8,0xC3,0xB0,0xFF,
8490xE8,0xBF,0xEC,0xF8,0xC3,0x90,0x83,0x66,0x7A,0xFB,0xB0,0x00,0xE8,0x73,0xDB,0xF8,
8500xC3,0x90,0xAC,0x49,0xE8,0x53,0xD9,0x72,0x11,0x36,0x88,0x1E,0x1A,0x01,0x36,0xA0,
8510x8E,0x12,0x0A,0xC3,0x52,0xBA,0x00,0x01,0xEE,0x5A,0xF8,0xC3,0xAC,0x49,0x32,0xE4,
8520x36,0xA3,0x86,0x12,0x05,0x06,0x00,0x36,0x8B,0x1E,0x88,0x12,0x2B,0xD8,0x36,0x89,
8530x1E,0x8A,0x12,0xF8,0xC3,0x90,0xAD,0x8B,0xD8,0xAD,0x83,0xE9,0x04,0x03,0xC3,0x2B,
8540x46,0x76,0x89,0x46,0x78,0xF7,0x46,0x7A,0x02,0x00,0x74,0x0A,0x83,0x66,0x7A,0xFD,
8550xB8,0x00,0x00,0xE8,0x1C,0xDB,0xF8,0xC3,0x06,0x16,0x07,0xAC,0x49,0x25,0x0F,0x00,
8560x6B,0xC0,0x09,0x8D,0xBE,0xFD,0x00,0x03,0xF8,0xAC,0x49,0x25,0x0F,0x00,0xAA,0x85,
8570xC0,0x74,0x08,0x2B,0xC8,0x51,0x8B,0xC8,0xF3,0xA4,0x59,0xE8,0x27,0xF0,0xE8,0x44,
8580x03,0x07,0xF8,0xC3,0x33,0xC0,0xAC,0x49,0x36,0xA3,0xB2,0x13,0x36,0xA3,0xB0,0x13,
8590xF8,0xC3,0x83,0x66,0x7A,0xEF,0xE8,0x2C,0x03,0xF8,0xC3,0x90,0x83,0x4E,0x7A,0x10,
8600xEB,0xF4,0xE8,0x9B,0xF0,0xF8,0xC3,0x90,0xAD,0x3C,0x19,0x77,0x0E,0x3C,0x19,0x77,
8610x0A,0x8B,0xF8,0x81,0xE7,0xFF,0x00,0x88,0xA6,0xC4,0x00,0xF8,0xC3,0x90,0x83,0x4E,
8620x26,0x20,0xAC,0x49,0x32,0xE4,0xD1,0xE0,0x8B,0xD8,0xC1,0xE3,0x02,0x03,0xC3,0x89,
8630x46,0x6E,0x83,0x4E,0x48,0x04,0xB0,0x06,0xE8,0x97,0xDA,0x49,0x46,0xF9,0xC3,0x90,
8640xFE,0x86,0xB3,0x00,0xB0,0x0A,0xE8,0x89,0xDA,0xF8,0xC3,0x90,0x33,0xC0,0xAC,0x49,
8650x6B,0xC0,0x0A,0x89,0x86,0x8A,0x00,0xF8,0xC3,0x90,0xAC,0x49,0x32,0xE4,0x3D,0x0A,
8660x00,0x77,0x05,0xB8,0x0A,0x00,0xEB,0x08,0x3D,0x5A,0x00,0x72,0x03,0xB8,0x5A,0x00,
8670x51,0xF7,0xD8,0x05,0x64,0x00,0x8B,0xC8,0x8B,0x46,0x44,0xF7,0xE1,0xB9,0x64,0x00,
8680xF7,0xF1,0x89,0x46,0x46,0x59,0xF8,0xC3,0xAC,0x49,0xE8,0x85,0xEB,0xF8,0xC3,0x90,
8690xAC,0x49,0x84,0xC0,0x75,0x07,0x81,0x66,0x38,0xFF,0xFD,0xF8,0xC3,0x81,0x4E,0x38,
8700x00,0x02,0xF7,0x46,0x38,0x40,0x00,0x75,0x08,0x8A,0x86,0xA9,0x00,0x88,0x86,0xAA,
8710x00,0xF8,0xC3,0x90,0x51,0x56,0xE8,0x7F,0x0C,0x5E,0x59,0xF8,0xC3,0x90,0xFE,0x86,
8720xB6,0x00,0xB0,0x0A,0xE8,0x0B,0xDA,0xF8,0xC3,0x90,0xFE,0x86,0xB7,0x00,0xB0,0x0A,
8730xE8,0xFF,0xD9,0xF8,0xC3,0x90,0xFE,0x86,0xB8,0x00,0xB0,0x0A,0xE8,0xF3,0xD9,0xF8,
8740xC3,0x90,0x00,0x90,0x51,0x55,0xAC,0x2E,0xA2,0x52,0x36,0x33,0xC9,0xAD,0x8B,0xF9,
8750xC1,0xE7,0x05,0xA9,0x01,0x00,0x74,0x23,0x2E,0x8B,0xAD,0x44,0x00,0x83,0x7E,0x08,
8760x00,0x74,0x18,0x2E,0x80,0x3E,0x52,0x36,0x01,0x74,0x09,0x60,0xB0,0x04,0xE8,0xBB,
8770x0C,0x61,0xEB,0x07,0x60,0xB0,0xFB,0xE8,0xEC,0x0C,0x61,0x47,0x47,0xD1,0xE8,0x75,
8780xD2,0x41,0x83,0xF9,0x04,0x72,0xC6,0x5D,0x59,0x83,0xE9,0x05,0xF7,0x46,0x38,0x40,
8790x00,0x74,0x05,0xE8,0x87,0xEA,0xF8,0xC3,0xE8,0x8D,0xEA,0xF8,0xC3,0x90,0x36,0xC6,
8800x06,0xC8,0x13,0x01,0xF8,0xC3,0x33,0xC0,0xAC,0x49,0x36,0xA3,0x80,0x12,0xAC,0x49,
8810x36,0x2B,0x06,0x88,0x12,0xF7,0xD8,0x36,0xA3,0x82,0x12,0xF8,0xC3,0x90,0xDE,0x26,
8820xDE,0x26,0xEC,0x26,0xF2,0x26,0xF8,0x26,0xFE,0x26,0x04,0x27,0x0E,0x27,0x16,0x27,
8830x1E,0x27,0x26,0x27,0x2E,0x27,0x34,0x27,0xBE,0x34,0xC6,0x34,0xD2,0x34,0x3A,0x27,
8840x78,0x27,0x80,0x27,0x94,0x27,0xA0,0x27,0xB4,0x27,0xC0,0x27,0xD4,0x27,0xE0,0x27,
8850xF4,0x27,0x00,0x28,0x10,0x28,0xEC,0x34,0xDE,0x26,0x1E,0x28,0x26,0x28,0x2C,0x28,
8860x32,0x28,0x38,0x28,0x4E,0x28,0x8A,0x28,0x06,0x35,0x28,0x35,0x98,0x28,0xBE,0x28,
8870xD2,0x28,0xDE,0x28,0xE6,0x28,0x54,0x35,0x62,0x35,0x6C,0x35,0xEE,0x28,0xC0,0x29,
8880xC8,0x29,0xCE,0x29,0xE0,0x29,0x72,0x35,0x78,0x35,0xF0,0x29,0xFC,0x29,0x8E,0x35,
8890x08,0x2A,0x12,0x2A,0x1C,0x2A,0xB0,0x35,0x36,0x2A,0xBC,0x35,0x5A,0x2A,0x62,0x2A,
8900x68,0x2A,0xCA,0x35,0x7C,0x2A,0xF8,0x35,0x88,0x2A,0xA6,0x2A,0xB8,0x2A,0xCC,0x2A,
8910xDE,0x2A,0xF2,0x2A,0x00,0x36,0x0A,0x2B,0x24,0x2B,0x24,0x36,0x38,0x2B,0x4C,0x2B,
8920x84,0x2B,0x2E,0x36,0x3A,0x36,0x46,0x36,0x54,0x36,0xE8,0x2B,0xAE,0x36,0x40,0x2C,
8930x62,0x2C,0xB6,0x36,0x70,0x28,0xDE,0x26,0xDE,0x26,0xD4,0x2E,0xE8,0x2E,0xF0,0x2E,
8940xF8,0x2E,0x00,0x2F,0x0A,0x2F,0x12,0x2F,0x1A,0x2F,0x22,0x2F,0x2A,0x2F,0x42,0x2F,
8950xBE,0x34,0xC6,0x34,0xD2,0x34,0x50,0x2F,0x8C,0x2F,0x94,0x2F,0xA8,0x2F,0xB4,0x2F,
8960xC8,0x2F,0xD4,0x2F,0xE8,0x2F,0xF4,0x2F,0x08,0x30,0x14,0x30,0x1C,0x30,0xEC,0x34,
8970xDE,0x26,0x24,0x30,0x30,0x30,0x38,0x30,0x44,0x30,0x4C,0x30,0x62,0x30,0xA4,0x30,
8980x06,0x35,0x28,0x35,0xAA,0x30,0xCE,0x30,0xD6,0x30,0xEA,0x30,0xF2,0x30,0x54,0x35,
8990x62,0x35,0x6C,0x35,0xFA,0x30,0xC2,0x31,0xC2,0x31,0xC4,0x31,0xFA,0x31,0x72,0x35,
9000x78,0x35,0x0A,0x32,0x16,0x32,0x8E,0x35,0x22,0x32,0x2C,0x32,0x36,0x32,0xB0,0x35,
9010x4A,0x32,0xBC,0x35,0x74,0x32,0x8C,0x32,0x9A,0x32,0xCA,0x35,0x9E,0x32,0xF8,0x35,
9020xAA,0x32,0xC6,0x32,0xD8,0x32,0xEC,0x32,0xFE,0x32,0x0E,0x33,0x00,0x36,0x12,0x33,
9030x26,0x33,0x24,0x36,0x32,0x33,0x9A,0x33,0xDE,0x33,0x2E,0x36,0x3A,0x36,0x46,0x36,
9040x54,0x36,0x5C,0x34,0xAE,0x36,0xAA,0x34,0xB0,0x34,0xB6,0x36,0x8C,0x30,0xE3,0x28,
9050xF7,0x46,0x38,0x40,0x00,0x75,0x32,0xE8,0xE3,0xE8,0x33,0xC0,0xAC,0x49,0x3D,0x5B,
9060x00,0x77,0x19,0x8B,0xD8,0xD1,0xE3,0x2E,0xFF,0x97,0xCE,0x36,0x72,0x0B,0x85,0xC9,
9070x75,0xE8,0x8B,0x46,0x48,0xE8,0x1A,0x0C,0xC3,0x4E,0x41,0xC3,0x6A,0x00,0x1F,0xC6,
9080x06,0x93,0x12,0x0C,0x9C,0x0E,0xE8,0x63,0xDA,0xE8,0xBC,0xE8,0x33,0xC0,0xAC,0x49,
9090x3D,0x5B,0x00,0x77,0xE7,0x8B,0xD8,0xD1,0xE3,0x2E,0xFF,0x97,0x86,0x37,0x72,0xD9,
9100x85,0xC9,0x75,0xE8,0xC3,0xF7,0x46,0x7A,0x10,0x00,0x75,0x0F,0x83,0xBE,0x84,0x00,
9110x00,0x74,0x08,0xB8,0x48,0x3A,0x89,0x86,0x80,0x00,0xC3,0x81,0xBE,0x80,0x00,0xEC,
9120x3C,0x74,0xF7,0x83,0xBE,0x88,0x00,0x00,0x75,0x05,0xB8,0xEC,0x3C,0xEB,0xE7,0xF7,
9130x46,0x7A,0x08,0x00,0x75,0x40,0x1E,0x60,0x8B,0x8E,0x88,0x00,0x3B,0x4E,0x74,0x77,
9140x33,0x3B,0x4E,0x78,0x77,0x2E,0xC4,0x7E,0x10,0x8B,0xDF,0x26,0x03,0x3D,0x47,0x47,
9150x33,0xC0,0x8E,0xD8,0x8D,0xB6,0xF4,0x00,0x8B,0xC1,0xF7,0x46,0x7A,0x01,0x00,0x75,
9160x1D,0xF3,0xA4,0x26,0x01,0x07,0x29,0x46,0x78,0x01,0x46,0x76,0x29,0x46,0x74,0xB0,
9170x0C,0xE8,0x3E,0xD7,0x61,0x1F,0xC7,0x86,0x88,0x00,0x00,0x00,0xEB,0xAC,0xE3,0xE3,
9180x50,0x90,0xAC,0x24,0x7F,0xAA,0xE2,0xFA,0x58,0xEB,0xD8,0x90,0x8B,0x8E,0x88,0x00,
9190xE3,0x46,0x8B,0x9E,0x8A,0x00,0x85,0xDB,0x74,0x3E,0xBA,0x50,0xFF,0xED,0x2B,0x86,
9200x82,0x00,0x3B,0xC3,0x72,0x37,0x8D,0xB6,0xF4,0x00,0xC4,0x7E,0x10,0x8B,0xDF,0x26,
9210x03,0x3D,0x47,0x47,0x8B,0xC1,0x16,0x1F,0xF7,0x46,0x7A,0x01,0x00,0x75,0x24,0xF3,
9220xA4,0x26,0x01,0x07,0x29,0x46,0x78,0x01,0x46,0x76,0x29,0x46,0x74,0xC7,0x86,0x88,
9230x00,0x00,0x00,0xB0,0x0C,0xE8,0xDA,0xD6,0x83,0x66,0x7A,0xF7,0xC3,0xB0,0x00,0xE8,
9240xD0,0xD6,0xC3,0xE3,0xDC,0x50,0xAC,0x24,0x7F,0xAA,0xE2,0xFA,0x58,0xEB,0xD2,0x90,
9250x1E,0x60,0x33,0xC0,0x8E,0xD8,0x8D,0xB6,0xFD,0x00,0x8B,0x86,0x88,0x00,0x8B,0x96,
9260x84,0x00,0x3A,0x04,0x75,0x10,0x8B,0xDE,0x46,0x8B,0xC8,0x8D,0xBE,0xF4,0x00,0xF3,
9270xA6,0x74,0x66,0x8B,0xF3,0x90,0x83,0xC6,0x09,0x4A,0x75,0xE6,0x8D,0xB6,0xFD,0x00,
9280x8B,0x96,0x84,0x00,0x3A,0x04,0x73,0x10,0x8B,0xDE,0x46,0x8B,0xC8,0x8D,0xBE,0xF4,
9290x00,0xF3,0xA6,0x74,0x76,0x8B,0xF3,0x90,0x83,0xC6,0x09,0x4A,0x75,0xE6,0x8D,0xB6,
9300xF4,0x00,0xAC,0xF7,0x46,0x7A,0x01,0x00,0x74,0x02,0x24,0x7F,0x1E,0xC5,0x5E,0x10,
9310x8B,0x37,0x88,0x40,0x02,0x46,0x89,0x37,0xFF,0x4E,0x78,0xFF,0x46,0x76,0xFF,0x4E,
9320x74,0x1F,0x8B,0x8E,0x88,0x00,0x49,0x89,0x8E,0x88,0x00,0xE3,0x43,0x8D,0xB6,0xF4,
9330x00,0x8B,0xFE,0x46,0xF3,0xA4,0xE9,0x7D,0xFF,0xC5,0x76,0x10,0x8B,0x1C,0x85,0xDB,
9340x74,0x08,0x03,0xF3,0x83,0xC6,0x03,0x83,0xE6,0xFE,0x8B,0x86,0x84,0x00,0x2B,0xC2,
9350xB4,0x80,0x89,0x04,0x46,0x46,0xC7,0x04,0x00,0x00,0x89,0x76,0x10,0x83,0x4E,0x7A,
9360x04,0xC7,0x86,0x88,0x00,0x00,0x00,0x61,0x1F,0xF9,0xC3,0x33,0xC0,0x61,0x1F,0xC3,
9370xB0,0x80,0x84,0xC0,0x61,0x1F,0xC3,0x90,0x8B,0x4E,0x78,0x2B,0x8E,0x88,0x00,0x76,
9380x27,0x89,0xB6,0x8C,0x00,0x8B,0x5E,0x74,0x3B,0xCB,0x72,0x02,0x8B,0xCB,0x3B,0xC8,
9390x72,0x02,0x8B,0xC8,0x8B,0xC1,0xE3,0x44,0x33,0xD2,0x8E,0xC2,0x8B,0xD1,0x83,0xBE,
9400x88,0x00,0x00,0x74,0x06,0xE9,0x8E,0x00,0x33,0xC0,0xC3,0x8B,0x5E,0x10,0x03,0x1F,
9410x43,0x43,0x52,0xF7,0x46,0x7A,0x01,0x00,0x75,0x2A,0xAC,0x8D,0xBE,0xE4,0x00,0x8B,
9420x8E,0x86,0x00,0xF2,0xAE,0x74,0x34,0x88,0x07,0x43,0x4A,0x75,0xED,0x58,0x8B,0x5E,
9430x10,0x01,0x07,0x29,0x46,0x78,0x01,0x46,0x76,0x29,0x46,0x74,0x8B,0xC6,0x2B,0x86,
9440x8C,0x00,0xC3,0x90,0xAC,0x8D,0xBE,0xE4,0x00,0x8B,0x8E,0x86,0x00,0xF2,0xAE,0x74,
9450x0A,0x24,0x7F,0x88,0x07,0x43,0x4A,0x75,0xEB,0xEB,0xD2,0x88,0x86,0xF4,0x00,0xC7,
9460x86,0x88,0x00,0x01,0x00,0x58,0x2B,0xC2,0x74,0x0E,0x8B,0x5E,0x10,0x01,0x07,0x29,
9470x46,0x78,0x01,0x46,0x76,0x29,0x46,0x74,0x40,0xE8,0x94,0xFE,0x72,0xBE,0x4A,0x75,
9480x15,0x83,0xBE,0x8A,0x00,0x00,0x74,0xB4,0xBA,0x50,0xFF,0xED,0x89,0x86,0x82,0x00,
9490x83,0x4E,0x7A,0x08,0xEB,0xA6,0x8D,0xBE,0xF4,0x00,0x03,0xBE,0x88,0x00,0xA4,0xFF,
9500x86,0x88,0x00,0xE8,0x6A,0xFE,0x72,0x94,0x79,0x06,0x4A,0x74,0x8F,0xE9,0x5B,0xFF,
9510x4A,0x74,0xCE,0xEB,0xE1,0x90,0x50,0xE8,0x11,0xCC,0x8B,0x46,0x74,0x39,0x46,0x72,
9520x74,0x27,0x1E,0x56,0x51,0x33,0xC9,0xC5,0x76,0x0C,0xAD,0x74,0x10,0x78,0x09,0x03,
9530xC8,0x05,0x01,0x00,0x24,0xFE,0x03,0xF0,0x3B,0x76,0x10,0x76,0xED,0x29,0x4E,0x76,
9540x01,0x4E,0x78,0xE8,0x37,0xCC,0x59,0x5E,0x1F,0x58,0xC3,0x90,0xC4,0x7E,0x10,0x26,
9550x8B,0x1D,0x83,0xC3,0x03,0x26,0x89,0x1D,0x4B,0x03,0xFB,0xAB,0x91,0xAA,0xB8,0x03,
9560x00,0x29,0x46,0x78,0x01,0x46,0x76,0x29,0x46,0x74,0xC3,0x90,0xC4,0x7E,0x10,0x26,
9570x8B,0x1D,0x43,0x26,0x89,0x1D,0x43,0x03,0xFB,0xAA,0xFF,0x4E,0x78,0xFF,0x46,0x76,
9580xFF,0x4E,0x74,0xC3,0xE8,0xE5,0xFF,0xC3,0x80,0x81,0x84,0x85,0x82,0x83,0x86,0x87,
9590x50,0x53,0x8A,0xDC,0x83,0xE3,0x0E,0xD1,0xEB,0x2E,0x8A,0x87,0x98,0x3B,0x08,0x86,
9600xB0,0x00,0xFE,0x86,0xB1,0x00,0xB0,0x0A,0xE8,0x87,0xD4,0x5B,0x58,0xC3,0x50,0x8A,
9610xC8,0xB8,0xFF,0x00,0xE8,0x95,0xFF,0x58,0xC3,0x90,0x8A,0x86,0xBB,0x00,0xE8,0xAB,
9620xFF,0xC3,0xE8,0xCB,0xFF,0xE8,0xF2,0xFF,0xC3,0x90,0xE8,0xC3,0xFF,0xE8,0xB4,0xFF,
9630xC3,0x90,0x33,0xC0,0xE8,0x95,0xFF,0xC3,0xB8,0xFF,0x00,0x33,0xC9,0xE8,0x6C,0xFF,
9640xC3,0x90,0xB8,0xFF,0x01,0xB1,0x10,0xE8,0x62,0xFF,0xC3,0x90,0xC3,0xFC,0x3B,0xE2,
9650x3B,0xF2,0x3B,0xF2,0x3B,0xFC,0x3B,0xE2,0x3B,0xE8,0x3B,0xE8,0x3B,0xFC,0x3B,0xE2,
9660x3B,0xE8,0x3B,0xE8,0x3B,0xFC,0x3B,0xE2,0x3B,0xE2,0x3B,0xE2,0x3B,0x00,0x10,0x00,
9670x00,0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x10,0x00,
9680x00,0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x10,0x00,0x00,0x00,0x08,0x00,
9690x00,0x00,0x08,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x08,0x00,0x00,0x51,0x53,0x8B,
9700x4E,0x38,0x81,0xE1,0xFF,0xEE,0xA8,0x04,0x74,0x04,0x81,0xC9,0x00,0x01,0x8A,0xE0,
9710x80,0xE4,0x03,0x24,0x18,0xD0,0xE4,0x0A,0xC4,0x33,0xDB,0x8A,0xD8,0x2E,0x8B,0x87,
9720xFD,0x3B,0x89,0x46,0x7C,0x2E,0x0B,0x8F,0x1D,0x3C,0x89,0x4E,0x38,0xD1,0xEB,0x2E,
9730x8A,0xA7,0x3D,0x3C,0x5B,0x59,0xC3,0xAC,0x49,0x3C,0x01,0x72,0x1D,0x74,0x20,0x3C,
9740x03,0x72,0x23,0x74,0x28,0x3C,0x08,0x72,0x2B,0x74,0x30,0x3C,0x20,0x72,0x37,0x74,
9750x3A,0xBB,0xDA,0x3B,0x32,0xE4,0x89,0x5E,0x7E,0xC3,0xBB,0xA0,0x3B,0xEB,0xF5,0xBB,
9760x94,0x3B,0xB4,0x01,0xEB,0xF0,0xBB,0xFC,0x3B,0xB4,0x02,0xEB,0xE9,0xBB,0xE2,0x3B,
9770xB4,0x03,0xEB,0xE2,0xBB,0xBE,0x3B,0xB4,0x04,0xEB,0xDB,0xBB,0xCA,0x3B,0xAC,0x49,
9780x88,0x86,0xBB,0x00,0xEB,0xCE,0xBB,0xD2,0x3B,0xEB,0xF3,0xBB,0xFC,0x3B,0xEB,0xC4,
9790xA9,0x04,0x00,0x75,0xD1,0xA9,0x08,0x00,0x75,0xDA,0xEB,0xD1,0x8B,0x5E,0x74,0x8B,
9800x4E,0x78,0x3B,0xCB,0x72,0x02,0x8B,0xCB,0x3B,0xC8,0x72,0x02,0x8B,0xC8,0x8B,0xC1,
9810xE3,0x2C,0xC4,0x7E,0x10,0x8B,0xDF,0x26,0x03,0x3D,0x47,0x47,0xF7,0x46,0x7A,0x01,
9820x00,0x75,0x1C,0xF7,0xC7,0x01,0x00,0x74,0x02,0x49,0xA4,0xD1,0xE9,0xF3,0xA5,0x73,
9830x01,0xA4,0x26,0x01,0x07,0x29,0x46,0x78,0x01,0x46,0x76,0x29,0x46,0x74,0xC3,0x50,
9840x53,0xBB,0x7F,0x7F,0xF7,0xC7,0x01,0x00,0x74,0x05,0x49,0xAC,0x22,0xC3,0xAA,0xD1,
9850xE9,0xE3,0x1D,0x9C,0xAD,0x23,0xC3,0xAB,0x49,0x74,0x14,0xAD,0x23,0xC3,0xAB,0x49,
9860x74,0x0D,0xAD,0x23,0xC3,0xAB,0x49,0x74,0x06,0xAD,0x23,0xC3,0xAB,0xE2,0xE5,0x9D,
9870x73,0x04,0xAC,0x22,0xC3,0xAB,0x5B,0x58,0xEB,0xB8,0xE8,0xCE,0xC9,0x8B,0x5E,0x38,
9880xF7,0xC3,0x10,0x04,0x75,0x01,0xC3,0xF7,0xC3,0x40,0x00,0x74,0x05,0xE8,0xB8,0xE3,
9890xEB,0x03,0xE8,0xA8,0xE3,0x81,0x66,0x38,0xEF,0xFB,0xF6,0xC3,0x10,0x74,0x3C,0xF6,
9900xC3,0x02,0x74,0x06,0xE4,0xD8,0x0C,0x01,0xE6,0xD8,0xF6,0xC3,0x04,0x74,0x11,0x83,
9910xC2,0x08,0x8A,0x86,0xA7,0x00,0x0C,0x01,0xEE,0x88,0x86,0xA7,0x00,0x83,0xEA,0x08,
9920xF6,0xC3,0x08,0x74,0x0F,0xE8,0x8B,0xE3,0x72,0x0A,0x8A,0x86,0xC0,0x00,0xE6,0x38,
9930xB0,0x23,0xE6,0x0A,0xF7,0xC3,0x00,0x04,0x75,0x01,0xC3,0xF7,0xC3,0x00,0x08,0x75,
9940xF9,0x8A,0x86,0xA5,0x00,0xF6,0xC3,0x40,0x75,0x0D,0xA8,0x10,0x75,0xEC,0x0C,0x10,
9950x88,0x86,0xA5,0x00,0xE6,0x0C,0xC3,0xA8,0x01,0x75,0xDF,0x83,0xC2,0x02,0x0C,0x05,
9960xEE,0x88,0x86,0xA5,0x00,0xC3,0xB0,0x00,0xE8,0x47,0xD2,0xEB,0x0F,0xB0,0x02,0xE8,
9970x90,0x0E,0xEB,0x08,0x83,0x66,0x38,0xDF,0x83,0x4E,0x7A,0x02,0x33,0xC0,0x8E,0xD8,
9980xFA,0xA0,0x92,0x12,0x40,0xA2,0x92,0x12,0x3C,0x05,0x72,0x1E,0xC6,0x06,0x92,0x12,
9990x00,0xFB,0xB0,0x01,0xE8,0x6B,0x0E,0xFA,0xA1,0x26,0x01,0x23,0x06,0x2A,0x01,0xA8,
10000x01,0x75,0x07,0xE8,0xE2,0x07,0xE8,0x61,0x09,0x90,0xB0,0x00,0xE8,0x37,0xD2,0xFB,
10010x85,0xED,0x74,0xB9,0xFA,0xF7,0x46,0x7A,0x46,0x00,0x75,0xC0,0x8B,0x46,0x78,0x3D,
10020x0A,0x00,0x72,0xB0,0x8B,0x4E,0x74,0x83,0xF9,0x50,0x72,0x9A,0x83,0x66,0x38,0xDF,
10030xC5,0x76,0x14,0x8B,0x46,0x3A,0x85,0xC0,0x75,0x58,0xAD,0x85,0xC0,0x75,0x0F,0xE8,
10040xF8,0xFE,0xF7,0x46,0x7A,0x08,0x00,0x74,0x93,0xE8,0xA0,0xFA,0xEB,0x8E,0x3B,0x76,
10050x04,0x76,0x21,0xB9,0x02,0x00,0x39,0x4E,0x2E,0x77,0x05,0xC7,0x46,0x2E,0x00,0x00,
10060x56,0x8B,0x76,0x2C,0x89,0x76,0x04,0xC7,0x04,0x00,0x00,0x46,0x46,0x89,0x76,0x2C,
10070x29,0x4E,0x2E,0x5E,0x85,0xC0,0x79,0x17,0xF6,0xC4,0x10,0x74,0x05,0xFF,0x56,0x7C,
10080xEB,0x03,0xFF,0x56,0x7E,0x89,0x76,0x14,0xB0,0x0C,0xE8,0x85,0xD1,0xEB,0x86,0x89,
10090x46,0x3A,0xFF,0x96,0x80,0x00,0x29,0x46,0x3A,0x89,0x76,0x14,0xB0,0x0C,0xE8,0x71,
10100xD1,0xE9,0x71,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x04,0x10,0x02,
10110x01,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
10120x00,0x00,0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
10130x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
10140x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
10150x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
10160x80,0x80,0x80,0x80,0x80,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,
10170xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0x80,
10180x80,0x80,0x80,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
10190x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
10200x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
10210x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
10220x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
10230x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
10240x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
10250x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,
10260x80,0x80,0x80,0x80,0x4E,0x41,0x78,0x41,0xD0,0x41,0xF4,0x41,0x06,0x42,0x18,0x42,
10270xC3,0x90,0x8E,0x46,0x02,0x8B,0x7E,0x22,0x89,0x7E,0x6C,0x80,0x66,0x27,0xFD,0x8B,
10280x56,0x24,0x83,0xFA,0x04,0x72,0xE9,0x83,0xEA,0x02,0x8B,0xD9,0x3B,0xCA,0x76,0x02,
10290x8B,0xCA,0xB0,0x0A,0x57,0x51,0x8B,0xFE,0xF2,0xAE,0x8B,0xC1,0x59,0x5F,0x75,0x1E,
10300x50,0x40,0x2B,0xC8,0x74,0x06,0x2B,0xD1,0x2B,0xD9,0xF3,0xA4,0x59,0x4B,0x4A,0x4A,
10310xB0,0x0D,0xAA,0xA4,0x3B,0xCA,0x76,0x02,0x8B,0xCA,0xE3,0x13,0xEB,0xD4,0x2B,0xD9,
10320xF7,0xC6,0x01,0x00,0x74,0x02,0xA4,0x49,0xD1,0xE9,0xF3,0xA5,0x73,0x01,0xA4,0x89,
10330x7E,0x22,0x2B,0x7E,0x6C,0x29,0x7E,0x24,0x01,0x7E,0x1A,0x8B,0xCB,0x80,0x7E,0x26,
10340x02,0x74,0x05,0x80,0x66,0x26,0xFD,0xC3,0x60,0xB0,0xFD,0xE8,0x18,0x03,0x61,0xC3,
10350xC3,0x90,0xE8,0x7C,0x02,0x72,0xF9,0x90,0x83,0x4E,0x26,0x20,0x8B,0x46,0x6A,0x89,
10360x46,0x6E,0x8B,0x46,0x48,0x0D,0x04,0x00,0x25,0xBF,0xFF,0x89,0x46,0x48,0xB0,0x06,
10370xE8,0xBF,0xCF,0xC3,0x89,0x7E,0x22,0x2B,0x7E,0x6C,0x01,0x7E,0x1A,0x29,0x7E,0x24,
10380x80,0x7E,0x26,0x02,0x74,0x05,0x83,0x66,0x26,0xFD,0xC3,0x60,0xB0,0xFD,0xE8,0xD5,
10390x02,0x61,0xC3,0x90,0x8A,0xBE,0xC2,0x00,0xEB,0x24,0xF7,0x46,0x48,0x40,0x00,0x75,
10400xB1,0x8E,0x46,0x02,0x8B,0x7E,0x22,0x89,0x7E,0x6C,0x8B,0x56,0x24,0x83,0xEA,0x0A,
10410x78,0x9E,0x03,0xD7,0x80,0x66,0x27,0xFD,0x33,0xC0,0x8A,0xBE,0xC2,0x00,0xE3,0xB4,
10420x3B,0xFA,0x77,0xB0,0xAC,0x49,0x93,0x2E,0x8A,0x87,0xD4,0x3E,0x93,0x22,0xDF,0x75,
10430x17,0xAA,0xE3,0xA0,0x3B,0xFA,0x77,0x9C,0xAC,0x49,0x93,0x2E,0x8A,0x87,0xD4,0x3E,
10440x93,0x22,0xDF,0x75,0x03,0xAA,0xEB,0xD6,0xF6,0xC3,0x7F,0x75,0x05,0xFF,0x46,0x66,
10450xEB,0xDF,0xF6,0xC3,0x40,0x75,0x0C,0x8B,0xD8,0x83,0xEB,0x08,0xD1,0xE3,0x2E,0xFF,
10460xA7,0xD4,0x3F,0xFF,0x46,0x66,0x2C,0x20,0xEB,0xC7,0x85,0xC0,0x74,0x2C,0x89,0x46,
10470x6A,0x83,0x4E,0x48,0x40,0x89,0x7E,0x22,0x2B,0x7E,0x6C,0x01,0x7E,0x1A,0x29,0x7E,
10480x24,0x80,0x7E,0x26,0x02,0x74,0x08,0x83,0x66,0x26,0xFD,0xE8,0xA3,0x01,0xC3,0x60,
10490xB0,0xFD,0xE8,0x31,0x02,0x61,0xE8,0x98,0x01,0xC3,0xE9,0x57,0xFF,0x90,0x8B,0x5E,
10500x66,0x4B,0x78,0x03,0x89,0x5E,0x66,0xAA,0x8B,0x5E,0x64,0xF7,0xC3,0x00,0x20,0x75,
10510x03,0xE9,0x40,0xFF,0xF7,0xC3,0x40,0x00,0x74,0x08,0x8A,0x86,0xC1,0x00,0xAA,0xE9,
10520x32,0xFF,0xB8,0x32,0x00,0xEB,0xA3,0x90,0x8B,0x5E,0x66,0x89,0x5E,0x68,0x83,0xC3,
10530x08,0x80,0xE3,0xF8,0x89,0x5E,0x66,0x8B,0x5E,0x64,0x81,0xE3,0x00,0x18,0x81,0xFB,
10540x00,0x18,0x74,0x2D,0xAA,0x85,0xDB,0x74,0x25,0xF7,0x46,0x64,0x40,0x00,0x75,0x18,
10550x81,0xFB,0x00,0x10,0x74,0x0C,0x8B,0x46,0x66,0x2B,0x46,0x68,0xC1,0xE0,0x04,0xE9,
10560x68,0xFF,0xB8,0x64,0x00,0xE9,0x62,0xFF,0x8A,0x86,0xC1,0x00,0xAA,0xAA,0xE9,0xE3,
10570xFE,0x51,0x8B,0x4E,0x66,0x2B,0x4E,0x68,0xB0,0x20,0xF3,0xAA,0x59,0xE9,0xD4,0xFE,
10580x8B,0x5E,0x66,0x89,0x5E,0x68,0x8B,0x5E,0x64,0xF7,0xC3,0x24,0x00,0x74,0x10,0xC7,
10590x46,0x66,0x00,0x00,0xF7,0xC3,0x04,0x00,0x74,0x05,0xB0,0x0D,0xAA,0xB0,0x0A,0xAA,
10600xEB,0x48,0x90,0x90,0xAA,0xF7,0x46,0x64,0x00,0x40,0x74,0x06,0xB8,0xD0,0x07,0xE9,
10610x18,0xFF,0xE9,0x9F,0xFE,0x90,0xAA,0xF7,0x46,0x64,0x00,0x80,0x74,0x06,0xB8,0xD0,
10620x07,0xE9,0x06,0xFF,0xE9,0x8D,0xFE,0x90,0x8B,0x5E,0x66,0x89,0x5E,0x68,0x85,0xDB,
10630x75,0x0C,0x8B,0x5E,0x64,0xF7,0xC3,0x10,0x00,0x74,0x06,0xE9,0x76,0xFE,0x8B,0x5E,
10640x64,0xF7,0xC3,0x08,0x00,0x74,0x27,0xB0,0x0A,0xAA,0xF7,0xC3,0x20,0x00,0x75,0x1F,
10650xF7,0xC3,0x00,0x01,0x75,0x03,0xE9,0x5B,0xFE,0xF7,0xC3,0x40,0x00,0x75,0x06,0xB8,
10660x64,0x00,0xE9,0xC5,0xFE,0x8A,0x86,0xC1,0x00,0xAA,0xAA,0xE9,0x46,0xFE,0xAA,0xC7,
10670x46,0x66,0x00,0x00,0xF7,0xC3,0x00,0x06,0x74,0xF1,0xF7,0xC3,0x40,0x00,0x74,0x19,
10680x8A,0x86,0xC1,0x00,0x81,0xE3,0x00,0x06,0x81,0xFB,0x00,0x04,0x72,0x06,0x76,0x02,
10690xAA,0xAA,0xAA,0xAA,0xAA,0xAA,0xE9,0x1B,0xFE,0x81,0xE3,0x00,0x06,0x81,0xFB,0x00,
10700x04,0x72,0x0E,0x76,0x06,0xB8,0x96,0x00,0xE9,0x7F,0xFE,0xB8,0x64,0x00,0xE9,0x79,
10710xFE,0x8B,0x46,0x68,0xE9,0x73,0xFE,0x90,0x36,0x8B,0x0E,0xDA,0x12,0x83,0xF9,0x32,
10720x73,0x1D,0x1E,0x06,0x33,0xC0,0x8E,0xD8,0x8E,0xC0,0x8D,0x76,0x4C,0xBF,0xDC,0x12,
10730x03,0xF9,0xA5,0xA5,0xA5,0x83,0xC1,0x06,0x89,0x0E,0xDA,0x12,0x07,0x1F,0xC3,0xB0,
10740x08,0xE8,0x6E,0xCD,0xC3,0x90,0x83,0x66,0x48,0xFE,0xE8,0x93,0xC4,0xE8,0xC8,0xFF,
10750xC3,0xF6,0x46,0x27,0x02,0x75,0x0F,0x9C,0xFA,0x83,0x7E,0x1A,0x00,0x74,0x09,0x80,
10760x4E,0x27,0x01,0x9D,0xF9,0xC3,0xF8,0xC3,0x50,0x52,0xF7,0x46,0x38,0x40,0x00,0x74,
10770x1D,0xE8,0x34,0xDE,0x83,0xC2,0x0A,0xEC,0xA8,0x40,0x75,0x27,0x83,0xEA,0x08,0x8A,
10780x86,0xA5,0x00,0x0C,0x02,0x88,0x86,0xA5,0x00,0xEE,0x5A,0x58,0xEB,0xD1,0xE8,0x0C,
10790xDE,0x8A,0x86,0xA5,0x00,0x24,0xFB,0x0C,0x02,0x88,0x86,0xA5,0x00,0xE6,0x0C,0x5A,
10800x58,0xEB,0xBC,0x80,0x4E,0x27,0x02,0x5A,0x58,0x9D,0xF8,0xC3,0x08,0x46,0x26,0x9C,
10810xFA,0x8A,0x8E,0xA5,0x00,0xF7,0x46,0x38,0x40,0x00,0x75,0x14,0xF6,0xC1,0x06,0x74,
10820x23,0xE8,0xD9,0xDD,0x8A,0xC1,0x24,0xF9,0x88,0x86,0xA5,0x00,0xE6,0x0C,0x9D,0xC3,
10830xF6,0xC1,0x02,0x74,0x0F,0xE8,0xD0,0xDD,0x83,0xC2,0x02,0x8A,0xC1,0x24,0xFD,0x88,
10840x86,0xA5,0x00,0xEE,0x9D,0xC3,0x8B,0x5E,0x26,0x22,0xC3,0x88,0x46,0x26,0x74,0x01,
10850xC3,0x80,0x66,0x27,0xFD,0x9C,0xFA,0x8A,0x8E,0xA5,0x00,0xF7,0x46,0x38,0x40,0x00,
10860x75,0x16,0xF6,0xC1,0x04,0x75,0x0F,0xE8,0x93,0xDD,0x8A,0xC1,0x24,0xFD,0x0C,0x04,
10870x88,0x86,0xA5,0x00,0xE6,0x0C,0x9D,0xC3,0xF6,0xC1,0x02,0x75,0xF9,0xE8,0x88,0xDD,
10880x83,0xC2,0x0A,0xEC,0xA8,0x20,0x75,0x0E,0x83,0xEA,0x08,0x8A,0xC1,0x0C,0x02,0x88,
10890x86,0xA5,0x00,0xEE,0x9D,0xC3,0x83,0xEA,0x0A,0x33,0xC9,0x8A,0x4E,0x1C,0x8B,0x46,
10900x1A,0x3B,0xC8,0x73,0x1B,0x01,0x4E,0x2A,0x2B,0xC1,0x89,0x46,0x1A,0x1E,0xC5,0x76,
10910x00,0xF3,0x6E,0x1F,0x89,0x76,0x00,0x83,0xC2,0x02,0x8A,0x86,0xA5,0x00,0xEB,0xCD,
10920x85,0xC0,0x74,0x12,0x01,0x46,0x2A,0x8B,0xC8,0x1E,0xC5,0x76,0x00,0xF3,0x6E,0x1F,
10930x89,0x76,0x00,0x89,0x4E,0x1A,0xF6,0xC7,0x01,0x75,0x23,0x80,0xCB,0x02,0x89,0x5E,
10940x26,0xE8,0x08,0xC3,0x83,0xC2,0x02,0x8A,0x86,0xA5,0x00,0x24,0xFD,0xEE,0x88,0x86,
10950xA5,0x00,0xF6,0xC7,0x10,0x75,0x05,0xB0,0x02,0xE8,0x16,0xCC,0x9D,0xC3,0x83,0xC2,
10960x02,0x8A,0x86,0xA5,0x00,0xEB,0x86,0x90,0x8B,0xD1,0x8B,0x46,0x24,0x3B,0xC8,0x76,
10970x02,0x8B,0xC8,0x2B,0xD1,0x2B,0xC1,0x8B,0xD9,0xE3,0x22,0x80,0x66,0x27,0xFD,0x8E,
10980x46,0x02,0x8B,0x7E,0x22,0xF7,0xC6,0x01,0x00,0x74,0x02,0xA4,0x49,0xD1,0xE9,0xF3,
10990xA5,0x73,0x01,0xA4,0x89,0x7E,0x22,0x89,0x46,0x24,0x01,0x5E,0x1A,0x8B,0xCA,0x80,
11000x7E,0x26,0x02,0x74,0x05,0x80,0x66,0x26,0xFD,0xC3,0x60,0xB0,0xFD,0xE8,0xF6,0xFE,
11010x61,0xC3,0x50,0xE4,0x0A,0x84,0xC0,0x75,0x0A,0x86,0x86,0xA1,0x00,0x84,0xC0,0x74,
11020x0A,0xE6,0x0A,0x58,0x0C,0x20,0x89,0x46,0x48,0xF9,0xC3,0x58,0x24,0xDF,0x89,0x46,
11030x48,0xF8,0xC3,0x90,0xFB,0xB0,0x02,0xE8,0xE8,0x07,0xFA,0xE8,0x2E,0x01,0xFB,0xB0,
11040x01,0xE8,0xDE,0x07,0xFA,0xB0,0x02,0xE8,0xBC,0xCB,0xFB,0x85,0xED,0x74,0xE5,0xFA,
11050x8E,0x5E,0x0A,0xFB,0x90,0xFA,0x8B,0x46,0x48,0x8B,0x76,0x40,0xA8,0x8C,0x75,0xDE,
11060xA8,0x20,0x74,0x1A,0x50,0xE8,0x55,0xDC,0x58,0xE8,0xA6,0xFF,0x73,0x10,0xB0,0x02,
11070xE8,0x5F,0xCB,0xEB,0xC9,0x90,0x25,0xFF,0x00,0x8B,0xC8,0xEB,0x36,0x90,0xA8,0x01,
11080x75,0x22,0x46,0x83,0xE6,0xFE,0x3B,0x76,0x08,0x74,0x79,0xAD,0x8A,0xFC,0xB3,0xF0,
11090x22,0xFB,0x3A,0xFB,0x74,0xE0,0x3A,0xBE,0xA0,0x00,0x74,0x2E,0xE8,0xD2,0xFD,0x73,
11100x77,0xEB,0x9B,0x90,0x8A,0xE0,0x24,0xFC,0x88,0x46,0x48,0x8B,0x4E,0x4A,0xF6,0xC4,
11110x02,0x74,0x1D,0xE8,0xBB,0xFD,0x72,0x86,0xE8,0x13,0xF3,0x89,0x76,0x40,0xE3,0x93,
11120x83,0x4E,0x48,0x03,0x89,0x4E,0x4A,0xE9,0x74,0xFF,0x25,0xFF,0x0F,0x8B,0xC8,0x90,
11130x8B,0x86,0x98,0x00,0x85,0xC0,0x74,0x1A,0x51,0x8A,0x8E,0xA0,0x00,0xC0,0xE9,0x04,
11140xBA,0x01,0x00,0xD3,0xE2,0x59,0x23,0xC2,0x74,0x08,0x03,0xF1,0x89,0x76,0x40,0xE9,
11150x61,0xFF,0xFF,0x56,0x62,0xE3,0xF5,0x83,0x4E,0x48,0x01,0x89,0x4E,0x4A,0x89,0x76,
11160x40,0xE9,0x3A,0xFF,0x81,0x4E,0x26,0x00,0x10,0x8B,0x46,0x50,0x3B,0x46,0x46,0x77,
11170x03,0xE8,0x52,0xFD,0xE9,0x27,0xFF,0x90,0x88,0xBE,0xA0,0x00,0xEB,0xAC,0x0A,0x06,
11180x90,0x12,0x8A,0xE0,0xBA,0x06,0x01,0xB0,0x04,0xEE,0xEC,0x84,0xC0,0x75,0x12,0xB0,
11190x04,0xEE,0x8A,0xC4,0xEE,0x32,0xE4,0xA8,0x80,0x74,0x06,0xC7,0x06,0x84,0x12,0x00,
11200x00,0x88,0x26,0x90,0x12,0xC3,0x0A,0x06,0x90,0x12,0x8A,0xE0,0xBA,0x06,0x01,0xEC,
11210xA8,0x01,0x75,0xED,0xBA,0x08,0x01,0x8A,0xC4,0xEE,0x32,0xE4,0xA8,0x80,0x74,0xE1,
11220xC7,0x06,0x84,0x12,0x00,0x00,0x88,0x26,0x90,0x12,0xC3,0x90,0x36,0xF7,0x06,0x24,
11230x01,0x01,0x00,0x75,0x30,0x36,0x8B,0x0E,0xDA,0x12,0x80,0xF9,0x36,0x73,0x26,0x33,
11240xC0,0x8E,0xC0,0x8E,0xD8,0xBF,0xDC,0x12,0x03,0xF9,0xB0,0x08,0xE8,0x77,0xCA,0x85,
11250xED,0x74,0x0E,0x8D,0x76,0x4C,0xA5,0xA5,0xA5,0x80,0xC1,0x06,0x80,0xF9,0x36,0x72,
11260xE9,0x89,0x0E,0xDA,0x12,0xC3,0xC3,0x90,0xF7,0x06,0x26,0x01,0x01,0x00,0x75,0xF6,
11270x8B,0x0E,0x20,0x13,0x85,0xC9,0x75,0xEE,0x33,0xC0,0x8E,0xC0,0x8E,0xD8,0xBF,0x24,
11280x13,0xB9,0x36,0x00,0xB0,0x0A,0xE8,0x3D,0xCA,0x85,0xED,0x75,0x06,0xE9,0x12,0x01,
11290xE9,0x0A,0x01,0x33,0xDB,0x8A,0x46,0x4C,0x8A,0xA6,0xB3,0x00,0xFE,0xCC,0x78,0x0E,
11300x88,0xA6,0xB3,0x00,0x0A,0xDC,0xB4,0x0A,0xAB,0x83,0xE9,0x02,0x76,0xE2,0x8A,0xA6,
11310xB2,0x00,0xFE,0xCC,0x78,0x0E,0x88,0xA6,0xB2,0x00,0x0A,0xDC,0xB4,0x08,0xAB,0x83,
11320xE9,0x02,0x76,0xCC,0x8A,0xA6,0xB1,0x00,0xFE,0xCC,0x78,0x18,0x8A,0xBE,0xB0,0x00,
11330x75,0x04,0x88,0xA6,0xB0,0x00,0x88,0xA6,0xB1,0x00,0x0A,0xDC,0x8A,0xE7,0xAB,0x83,
11340xE9,0x02,0x76,0xAC,0x8A,0xA6,0xB4,0x00,0xFE,0xCC,0x78,0x1F,0x88,0xA6,0xB4,0x00,
11350x0A,0xDC,0xB4,0x0B,0xAB,0x8A,0x86,0xBC,0x00,0x8A,0xA6,0xBD,0x00,0xAB,0x8B,0x86,
11360xBE,0x00,0xAB,0x83,0xE9,0x06,0x76,0x88,0x8A,0x46,0x4C,0x8A,0xA6,0xB6,0x00,0xFE,
11370xCC,0x78,0x19,0x88,0xA6,0xB6,0x00,0x0A,0xDC,0xB4,0x0C,0xAB,0xE8,0xDB,0xCB,0xAB,
11380x8B,0x46,0x2A,0xAB,0x83,0xE9,0x06,0x76,0x74,0x8A,0x46,0x4C,0x8A,0xA6,0xB7,0x00,
11390xFE,0xCC,0x78,0x19,0x88,0xA6,0xB7,0x00,0x0A,0xDC,0xB4,0x0D,0xAB,0xE8,0xBA,0xCB,
11400xAB,0x8B,0x46,0x34,0xAB,0x83,0xE9,0x06,0x76,0x53,0x8A,0x46,0x4C,0x8A,0xA6,0xB8,
11410x00,0xFE,0xCC,0x78,0x19,0x88,0xA6,0xB8,0x00,0x0A,0xDC,0xB4,0x0E,0xAB,0xA1,0x50,
11420x12,0xAB,0xA1,0x52,0x12,0xAB,0x83,0xE9,0x06,0x76,0x32,0x8A,0x46,0x4C,0x8A,0xA6,
11430xB5,0x00,0xFE,0xCC,0x78,0x18,0x88,0xA6,0xB5,0x00,0x0A,0xDC,0xB4,0x0F,0xAB,0x8B,
11440x86,0x9A,0x00,0xAB,0x8B,0x86,0x9C,0x00,0xAB,0x83,0xE9,0x06,0x76,0x0F,0x84,0xDB,
11450x75,0x03,0xE9,0xEF,0xFE,0xB0,0x0A,0xE8,0xF8,0xC8,0xE9,0xE7,0xFE,0xB0,0x0A,0xE8,
11460xF0,0xC8,0xF7,0xD9,0x83,0xC1,0x36,0x8B,0xC1,0x0D,0x80,0x00,0x86,0xC4,0xA3,0x22,
11470x13,0x41,0x41,0x89,0x0E,0x20,0x13,0xC3,0xA1,0x84,0x12,0x2B,0xC1,0x72,0x11,0xA3,
11480x84,0x12,0xBE,0x22,0x13,0xD1,0xE9,0xF3,0x6F,0x90,0x89,0x0E,0x20,0x13,0xF8,0xC3,
11490xF9,0xC3,0xC3,0x81,0xEF,0x6A,0x13,0x74,0xF9,0x8B,0xC7,0x0D,0x80,0x00,0x86,0xC4,
11500xA3,0x68,0x13,0x47,0x47,0x89,0x3E,0x66,0x13,0xC3,0xF7,0x06,0x2A,0x01,0x01,0x00,
11510x75,0xE0,0x8B,0x0E,0x66,0x13,0xE3,0x07,0x80,0xF9,0x20,0x77,0xD5,0x49,0x49,0x33,
11520xC0,0x8E,0xC0,0x8E,0xD8,0xBF,0x6A,0x13,0x8B,0xF7,0x03,0xF9,0x83,0xC6,0x34,0x3B,
11530xFE,0x77,0xC0,0xB0,0x0E,0xE8,0xAE,0xC8,0x85,0xED,0x74,0xB7,0x8A,0x46,0x4C,0x8A,
11540xB6,0xB9,0x00,0xFE,0xCE,0x78,0x15,0x88,0xB6,0xB9,0x00,0x8A,0xA6,0xA9,0x00,0x80,
11550xCC,0xC0,0xAB,0x84,0xF6,0x74,0x05,0xB0,0x0E,0xE8,0x56,0xC8,0x8A,0xB6,0xBA,0x00,
11560xFE,0xCE,0x78,0xCB,0x8A,0x9E,0xA9,0x00,0x8A,0xBE,0xAB,0x00,0x8A,0x56,0x3F,0x8A,
11570xF3,0x32,0xF7,0x0A,0xB6,0xAC,0x00,0xC6,0x86,0xAC,0x00,0x00,0x22,0xF2,0x74,0x4B,
11580xF6,0xC6,0x08,0x74,0x0F,0xB4,0x02,0xF6,0xC3,0x08,0x75,0x02,0xB4,0x03,0xAB,0x80,
11590xE6,0xF7,0x74,0x37,0xF6,0xC6,0x01,0x74,0x0F,0xB4,0x00,0xF6,0xC3,0x01,0x75,0x02,
11600xB4,0x01,0xAB,0x80,0xE6,0xFE,0x74,0x23,0xF6,0xC6,0x02,0x74,0x0F,0xB4,0x04,0xF6,
11610xC3,0x02,0x75,0x02,0xB4,0x05,0xAB,0x80,0xE6,0xFD,0x74,0x0F,0xF6,0xC6,0x04,0x74,
11620x0A,0xB4,0x06,0xF6,0xC3,0x04,0x75,0x02,0xB4,0x07,0xAB,0xC6,0x86,0xBA,0x00,0x00,
11630x88,0x9E,0xAB,0x00,0xE9,0x58,0xFF,0x90,0xA1,0x84,0x12,0x2B,0xC1,0x72,0x11,0xA3,
11640x84,0x12,0xBE,0x68,0x13,0xD1,0xE9,0xF3,0x6F,0x90,0x89,0x0E,0x66,0x13,0xF8,0xC3,
11650xF9,0xC3,0xA1,0x84,0x12,0x41,0x41,0x2B,0xC1,0x72,0x23,0xA3,0x84,0x12,0x8B,0xC1,
11660x48,0x48,0x32,0xE4,0x0C,0x80,0x86,0xC4,0xEF,0x90,0x90,0x90,0x90,0x90,0xBE,0xDC,
11670x12,0x49,0x49,0xD1,0xE9,0xF3,0x6F,0x90,0x89,0x0E,0xDA,0x12,0xF8,0xC3,0xF9,0xC3,
11680x8A,0xC8,0x8A,0x46,0x4C,0xB4,0x01,0x83,0xEB,0x06,0xEF,0x90,0x90,0x90,0x90,0x90,
11690xB8,0x01,0x00,0xEF,0x90,0x90,0x90,0x90,0x90,0x8A,0xC1,0xEF,0x90,0x90,0x90,0x90,
11700x90,0xE9,0x97,0x00,0xE9,0xAC,0x00,0x33,0xC0,0x8E,0xD8,0x89,0x1E,0x84,0x12,0xC3,
11710x36,0x8B,0x1E,0x84,0x12,0xFB,0x90,0xFA,0xB0,0x0C,0xE8,0x89,0xC7,0x85,0xED,0x74,
11720xE6,0xC5,0x76,0x0C,0x83,0xFB,0x14,0x72,0xDB,0xFB,0x90,0xFA,0xAD,0x85,0xC0,0x78,
11730xAF,0x74,0xE2,0x8B,0xFE,0x03,0xF8,0x36,0x8B,0x0E,0x86,0x12,0x3B,0xC1,0x77,0x02,
11740x8B,0xC8,0x83,0xEB,0x04,0x3B,0xD9,0x77,0x02,0x8B,0xCB,0x33,0xC0,0x8A,0x46,0x4C,
11750xEF,0x90,0x90,0x90,0x90,0x90,0x8B,0xC1,0xEF,0x90,0x90,0x90,0x90,0x90,0x41,0x80,
11760xE1,0xFE,0x2B,0xD9,0x51,0xD1,0xE9,0xF3,0x6F,0x90,0x59,0x8B,0xC7,0x40,0x24,0xFE,
11770x3B,0xC6,0x74,0x27,0x2B,0xFE,0x4E,0x4E,0x53,0x8B,0x5E,0x10,0x3B,0xF3,0x72,0x13,
11780x03,0x1F,0x83,0xC3,0x03,0x80,0xE3,0xFE,0xC7,0x07,0x00,0x00,0x83,0x6E,0x74,0x02,
11790x89,0x5E,0x10,0x5B,0x89,0x3C,0x89,0x76,0x0C,0xEB,0x89,0x89,0x76,0x0C,0x39,0x76,
11800x10,0x77,0x81,0x72,0x08,0x83,0x3C,0x00,0x74,0x03,0xE9,0x77,0xFF,0xE8,0x0D,0xBE,
11810xE9,0x62,0xFF,0x36,0x89,0x1E,0x84,0x12,0xB0,0x0C,0xE8,0xB5,0xC6,0x33,0xC0,0x8E,
11820xD8,0xC3,0xA1,0x84,0x12,0x3D,0x10,0x00,0x72,0x77,0xBA,0x04,0x01,0x3B,0x06,0x88,
11830x12,0x75,0x06,0xC7,0x06,0x7E,0x12,0x00,0x00,0x8B,0x0E,0xDA,0x12,0xE3,0x0B,0xE8,
11840xD0,0xFE,0x72,0x57,0xC7,0x06,0x7E,0x12,0xFF,0x7F,0x8B,0x0E,0x20,0x13,0xE3,0x0B,
11850xE8,0xA5,0xFD,0x72,0x46,0xC7,0x06,0x7E,0x12,0xFF,0x7F,0x8B,0x0E,0x66,0x13,0xE3,
11860x0B,0xE8,0x94,0xFE,0x72,0x35,0xC7,0x06,0x7E,0x12,0xFF,0x7F,0xA1,0x28,0x01,0xA9,
11870x01,0x00,0x75,0x03,0xE8,0xF9,0xFE,0x80,0x3E,0x8D,0x12,0x00,0x75,0x1D,0xA1,0x84,
11880x12,0x3D,0x20,0x00,0x76,0x15,0x3B,0x06,0x82,0x12,0x76,0x09,0xA1,0x7E,0x12,0x3B,
11890x06,0x80,0x12,0x72,0x0C,0x80,0x0E,0x90,0x12,0x80,0xC3,0xB0,0x80,0xFF,0x16,0x7C,
11900x12,0xC3,0x80,0x0E,0x90,0x12,0x40,0xC3,0x6A,0x00,0x1F,0xC6,0x06,0x93,0x12,0x17,
11910x9C,0x0E,0xE8,0xB7,0xC8,0x6A,0x00,0x1F,0xC6,0x06,0x93,0x12,0x20,0x9C,0x0E,0xE8,
11920xAA,0xC8,0x6A,0x00,0x1F,0xC6,0x06,0x93,0x12,0x16,0x9C,0x0E,0xE8,0x9D,0xC8,0x90,
11930xBA,0x06,0x01,0xEC,0xA8,0x20,0x75,0xCA,0xFB,0x90,0xFA,0xBA,0x04,0x01,0xED,0x90,
11940x90,0x90,0x90,0x90,0x3A,0x06,0x94,0x12,0x77,0xBE,0x33,0xDB,0x8A,0xD8,0xD1,0xE3,
11950x2E,0x8B,0xAF,0x44,0x00,0xC4,0x7E,0x08,0x85,0xFF,0x74,0xB9,0xF6,0xC4,0xC0,0x75,
11960x55,0x32,0xC0,0xC1,0xE0,0x02,0x80,0xE4,0xF0,0x8B,0xF0,0xED,0x90,0x90,0x90,0x90,
11970x90,0x85,0xC0,0x74,0xBB,0x8B,0xC8,0x41,0x80,0xE1,0xFE,0x0B,0xC6,0x8B,0x5E,0x50,
11980x4B,0x4B,0x2B,0xD9,0x78,0x9C,0xAB,0x8B,0xC1,0x40,0x40,0x01,0x46,0x4E,0xD1,0xE9,
11990xF3,0x6D,0x90,0x89,0x5E,0x50,0x89,0x7E,0x08,0x8B,0x46,0x26,0x80,0xE4,0xEF,0x89,
12000x46,0x26,0xF6,0xC4,0x01,0x75,0x0C,0xF7,0x46,0x48,0x0C,0x00,0x75,0x05,0xB0,0x02,
12010xE8,0x7F,0xC5,0xE9,0x7A,0xFF,0x86,0xC4,0x8B,0xC8,0x83,0xE1,0x3F,0x41,0x80,0xE1,
12020xFE,0xE3,0x0A,0x3C,0x80,0x72,0x09,0x24,0x3F,0xB4,0xF0,0xEB,0xB0,0xE9,0x60,0xFF,
12030x25,0x3F,0x00,0x33,0xFF,0x8E,0xC7,0xBF,0x96,0x12,0x8B,0xF7,0xD1,0xE9,0xF3,0x6D,
12040x90,0x8B,0xC8,0xE8,0x48,0xED,0xE9,0x47,0xFF,0x90,0x6A,0x00,0x1F,0xC6,0x06,0x93,
12050x12,0x1B,0x9C,0x0E,0xE8,0xD5,0xC7,0x90,0x60,0x1E,0x06,0x33,0xC0,0x8E,0xD8,0x8E,
12060xC0,0xBA,0x06,0x01,0xEC,0xA8,0x04,0x74,0xE1,0xB0,0x06,0xEE,0xEC,0xA2,0x8C,0x12,
12070xA8,0x40,0x74,0x11,0xA1,0x88,0x12,0xA3,0x84,0x12,0xC6,0x06,0x8D,0x12,0x00,0xE8,
12080x60,0xFE,0xA0,0x8C,0x12,0xA8,0x80,0x74,0x03,0xE8,0x04,0xFF,0xB8,0x00,0x80,0xBA,
12090x22,0xFF,0xEF,0x07,0x1F,0x61,0xCF,0x90,0x6A,0x00,0x1F,0xC6,0x06,0x93,0x12,0x1B,
12100x9C,0x0E,0xE8,0x87,0xC7,0x90,0x60,0x1E,0x06,0x33,0xC0,0x8E,0xD8,0x8E,0xC0,0xBA,
12110x06,0x01,0xEC,0xA8,0x04,0x74,0xE1,0xBA,0x08,0x01,0xEC,0xA2,0x8C,0x12,0xA8,0x40,
12120x74,0x11,0xA1,0x88,0x12,0xA3,0x84,0x12,0xC6,0x06,0x8D,0x12,0x00,0xE8,0x12,0xFE,
12130xA0,0x8C,0x12,0xA8,0x80,0x74,0x03,0xE8,0xB6,0xFE,0xB8,0x00,0x80,0xBA,0x22,0xFF,
12140xEF,0x07,0x1F,0x61,0xCF,0x90,0xEE,0x86,0xE0,0xEE,0x86,0xE0,0xEC,0x86,0xE0,0xEC,
12150x86,0xE0,0x80,0xE1,0xFE,0xF3,0x6C,0x90,0x80,0xE1,0xFE,0xF3,0x6E,0x90,0x05,0x00,
12160x75,0x47,0xA8,0x4B,0x05,0x00,0x75,0x48,0xA8,0x4B,0x05,0x00,0xA3,0x48,0xA8,0x4B,
12170x05,0x00,0x35,0x49,0xA8,0x4B,0x06,0x00,0x98,0x48,0x96,0x4B,0x06,0x00,0xBA,0x48,
12180x96,0x4B,0x06,0x00,0xC3,0x48,0x96,0x4B,0x06,0x00,0xCB,0x48,0x96,0x4B,0x06,0x00,
12190x20,0x49,0x96,0x4B,0x06,0x00,0x28,0x49,0x96,0x4B,0x06,0x00,0x4E,0x4A,0x9C,0x4B,
12200x06,0x00,0x7B,0x4A,0x9C,0x4B,0x05,0x00,0x9E,0x4A,0xA2,0x4B,0x05,0x00,0xEC,0x4A,
12210xA2,0x4B,0x00,0x00,0x1E,0x06,0x83,0x3E,0x44,0x12,0x00,0x74,0x09,0xA0,0x06,0x01,
12220x24,0x30,0x3C,0x30,0x74,0x1A,0x8C,0xC8,0x8E,0xD8,0x8E,0xC0,0xBB,0xAE,0x4B,0x8B,
12230x0F,0xE3,0x0D,0x8B,0x7F,0x02,0x8B,0x77,0x04,0xF3,0xA4,0x83,0xC3,0x06,0xEB,0xEF,
12240x07,0x1F,0xC3,0x90,0x33,0xC0,0xA3,0x3E,0x01,0xB9,0x0C,0x01,0xBE,0x40,0x01,0x8B,
12250xFE,0x81,0xC6,0xB4,0x0F,0x89,0x04,0x8B,0xC6,0x2B,0xF1,0x3B,0xC7,0x77,0xF6,0xA3,
12260x3C,0x01,0xC3,0x90,0x1E,0x06,0x60,0x36,0x8B,0x2E,0x3E,0x01,0x8B,0x5E,0x00,0x3B,
12270xEB,0x74,0x2B,0x8B,0x76,0x02,0x89,0x1C,0x89,0x77,0x02,0x36,0xA1,0x3C,0x01,0x89,
12280x46,0x00,0x36,0x89,0x2E,0x3C,0x01,0x8B,0xEB,0xFF,0x4E,0x06,0x74,0x08,0x8B,0x6E,
12290x00,0xFF,0x4E,0x06,0x75,0xF8,0x36,0x89,0x2E,0x3E,0x01,0x8B,0x66,0x04,0x61,0x07,
12300x1F,0xC3,0x1E,0x06,0x60,0x36,0x8B,0x2E,0x3E,0x01,0x98,0x89,0x46,0x06,0x89,0x66,
12310x04,0x3B,0x6E,0x00,0x74,0x10,0x8B,0x6E,0x00,0xFF,0x4E,0x06,0x75,0xF8,0x36,0x89,
12320x2E,0x3E,0x01,0x8B,0x66,0x04,0x61,0x07,0x1F,0xC3,0xC3,0x90,0x1E,0x06,0x60,0x9C,
12330xFA,0x33,0xED,0x8E,0xDD,0x8B,0x2E,0x3C,0x01,0x85,0xED,0x74,0x3D,0x8B,0x4E,0x00,
12340x89,0x0E,0x3C,0x01,0x8B,0xCC,0x8D,0xA6,0x0A,0x01,0x56,0x1E,0x06,0x60,0x89,0x66,
12350x04,0xC7,0x46,0x08,0x0F,0x1A,0xC7,0x46,0x06,0x01,0x00,0x8B,0x1E,0x3E,0x01,0x85,
12360xDB,0x74,0x1D,0x8B,0xC5,0x87,0x07,0x89,0x46,0x00,0x89,0x5E,0x02,0x8B,0xD8,0x89,
12370x6F,0x02,0x8B,0xE1,0x9D,0x61,0x07,0x1F,0xF8,0xC3,0x9D,0x61,0x07,0x1F,0xF9,0xC3,
12380x89,0x2E,0x3E,0x01,0x89,0x6E,0x00,0x89,0x6E,0x02,0x87,0xE1,0x9D,0x8B,0xE1,0xEB,
12390xE4,0x00,0x0D,0x0A,0x54,0x65,0x72,0x6D,0x69,0x6E,0x61,0x6C,0x73,0x20,0x73,0x75,
12400x70,0x70,0x6F,0x72,0x74,0x65,0x64,0x3A,0x0D,0x0A,0x31,0x29,0x20,0x41,0x4E,0x53,
12410x49,0x20,0x63,0x6F,0x6D,0x70,0x61,0x74,0x69,0x62,0x6C,0x65,0x0D,0x0A,0x32,0x29,
12420x20,0x57,0x79,0x73,0x65,0x20,0x33,0x30,0x0D,0x0A,0x50,0x6C,0x65,0x61,0x73,0x65,
12430x20,0x73,0x65,0x6C,0x65,0x63,0x74,0x3A,0x20,0x00,0x0D,0x0A,0x63,0x6F,0x64,0x65,
12440x20,0x73,0x65,0x67,0x6D,0x65,0x6E,0x74,0x3D,0x00,0x0D,0x0A,0x4D,0x6F,0x6E,0x69,
12450x74,0x6F,0x72,0x20,0x76,0x32,0x2E,0x35,0x0A,0x0D,0x0A,0x3E,0x00,0x0D,0x0A,0x50,
12460x61,0x72,0x64,0x6F,0x6E,0x3F,0x00,0x0D,0x0A,0x4E,0x6F,0x20,0x61,0x64,0x64,0x72,
12470x65,0x73,0x73,0x20,0x73,0x70,0x65,0x63,0x69,0x66,0x69,0x65,0x64,0x00,0x0D,0x0A,
12480x3A,0x00,0x0D,0x0A,0x00,0x4C,0x6F,0x63,0x3D,0x00,0x0D,0x0A,0x46,0x41,0x54,0x41,
12490x4C,0x20,0x45,0x52,0x52,0x4F,0x52,0x3D,0x00,0x0D,0x0A,0x4D,0x6F,0x6E,0x69,0x74,
12500x6F,0x72,0x20,0x63,0x6F,0x6D,0x6D,0x61,0x6E,0x64,0x73,0x3A,0x2D,0x0D,0x0A,0x20,
12510x20,0x20,0x44,0x2C,0x64,0x5B,0x5B,0x78,0x78,0x78,0x78,0x3A,0x5D,0x78,0x78,0x78,
12520x78,0x5D,0x20,0x2D,0x20,0x64,0x75,0x6D,0x70,0x20,0x6D,0x65,0x6D,0x6F,0x72,0x79,
12530x0D,0x0A,0x20,0x20,0x20,0x4C,0x2C,0x6C,0x5B,0x5B,0x78,0x78,0x78,0x78,0x3A,0x5D,
12540x78,0x78,0x78,0x78,0x5D,0x20,0x2D,0x20,0x64,0x75,0x6D,0x70,0x20,0x73,0x69,0x6E,
12550x67,0x6C,0x65,0x20,0x6C,0x69,0x6E,0x65,0x0D,0x0A,0x20,0x20,0x20,0x45,0x2C,0x65,
12560x5B,0x5B,0x78,0x78,0x78,0x78,0x3A,0x5D,0x78,0x78,0x78,0x78,0x5D,0x20,0x2D,0x20,
12570x65,0x64,0x69,0x74,0x20,0x6D,0x65,0x6D,0x6F,0x72,0x79,0x0D,0x0A,0x20,0x20,0x20,
12580x46,0x2C,0x66,0x5B,0x5B,0x78,0x78,0x78,0x78,0x20,0x5D,0x78,0x78,0x78,0x78,0x5D,
12590x20,0x2D,0x20,0x66,0x69,0x6C,0x6C,0x20,0x6D,0x65,0x6D,0x6F,0x72,0x79,0x20,0x70,
12600x61,0x72,0x61,0x67,0x72,0x61,0x70,0x68,0x73,0x0D,0x0A,0x20,0x20,0x20,0x49,0x5B,
12610x78,0x78,0x78,0x78,0x5D,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2D,
12620x20,0x77,0x6F,0x72,0x64,0x20,0x69,0x6E,0x70,0x75,0x74,0x20,0x66,0x72,0x6F,0x6D,
12630x20,0x70,0x6F,0x72,0x74,0x0D,0x0A,0x20,0x20,0x20,0x69,0x5B,0x78,0x78,0x78,0x78,
12640x5D,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2D,0x20,0x62,0x79,0x74,
12650x65,0x20,0x69,0x6E,0x70,0x75,0x74,0x20,0x66,0x72,0x6F,0x6D,0x20,0x70,0x6F,0x72,
12660x74,0x0D,0x0A,0x20,0x20,0x20,0x4F,0x78,0x78,0x78,0x78,0x20,0x78,0x78,0x20,0x20,
12670x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2D,0x20,0x6F,0x75,0x74,0x70,0x75,0x74,0x20,
12680x77,0x6F,0x72,0x64,0x20,0x74,0x6F,0x20,0x70,0x6F,0x72,0x74,0x0D,0x0A,0x20,0x20,
12690x20,0x6F,0x78,0x78,0x78,0x78,0x20,0x78,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
12700x20,0x20,0x2D,0x20,0x6F,0x75,0x74,0x70,0x75,0x74,0x20,0x62,0x79,0x74,0x65,0x20,
12710x74,0x6F,0x20,0x70,0x6F,0x72,0x74,0x0D,0x0A,0x20,0x20,0x20,0x47,0x5B,0x5B,0x78,
12720x78,0x78,0x78,0x3A,0x5D,0x78,0x78,0x78,0x78,0x5D,0x20,0x20,0x20,0x2D,0x20,0x67,
12730x6F,0x74,0x6F,0x20,0x61,0x64,0x64,0x72,0x65,0x73,0x73,0x0D,0x0A,0x20,0x20,0x20,
12740x57,0x5B,0x5B,0x78,0x78,0x78,0x78,0x3A,0x5D,0x78,0x78,0x78,0x78,0x5D,0x20,0x20,
12750x20,0x2D,0x20,0x77,0x61,0x74,0x63,0x68,0x20,0x61,0x20,0x77,0x6F,0x72,0x64,0x0D,
12760x0A,0x20,0x20,0x20,0x43,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
12770x20,0x20,0x20,0x20,0x20,0x2D,0x20,0x69,0x6E,0x74,0x65,0x72,0x72,0x75,0x70,0x74,
12780x73,0x20,0x6F,0x66,0x66,0x0D,0x0A,0x20,0x20,0x20,0x53,0x20,0x20,0x20,0x20,0x20,
12790x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2D,0x20,0x69,0x6E,0x74,
12800x65,0x72,0x72,0x75,0x70,0x74,0x73,0x20,0x6F,0x6E,0x0D,0x0A,0x20,0x20,0x20,0x73,
12810x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
12820x2D,0x20,0x73,0x69,0x6E,0x67,0x6C,0x65,0x20,0x73,0x74,0x65,0x70,0x0D,0x0A,0x20,
12830x20,0x20,0x42,0x78,0x78,0x78,0x78,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
12840x20,0x20,0x20,0x2D,0x20,0x62,0x72,0x65,0x61,0x6B,0x70,0x6F,0x69,0x6E,0x74,0x20,
12850x73,0x65,0x74,0x0D,0x0A,0x20,0x20,0x20,0x62,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
12860x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2D,0x20,0x62,0x72,0x65,0x61,0x6B,
12870x70,0x6F,0x69,0x6E,0x74,0x20,0x63,0x6C,0x65,0x61,0x72,0x0D,0x0A,0x20,0x20,0x20,
12880x52,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
12890x20,0x2D,0x20,0x72,0x65,0x73,0x74,0x61,0x72,0x74,0x20,0x62,0x72,0x65,0x61,0x6B,
12900x70,0x6F,0x69,0x6E,0x74,0x0D,0x0A,0x20,0x20,0x20,0x72,0x20,0x20,0x20,0x20,0x20,
12910x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2D,0x20,0x72,0x65,0x67,
12920x69,0x73,0x74,0x65,0x72,0x73,0x20,0x61,0x74,0x20,0x62,0x72,0x6B,0x70,0x74,0x0D,
12930x0A,0x20,0x20,0x20,0x58,0x2C,0x78,0x20,0x6E,0x20,0x20,0x20,0x20,0x20,0x20,0x20,
12940x20,0x20,0x20,0x20,0x20,0x2D,0x20,0x65,0x78,0x61,0x6D,0x69,0x6E,0x65,0x20,0x63,
12950x68,0x61,0x6E,0x6E,0x65,0x6C,0x20,0x6E,0x0D,0x0A,0x20,0x20,0x20,0x48,0x2C,0x3F,
12960x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x2D,0x20,
12970x74,0x68,0x69,0x73,0x20,0x6D,0x65,0x73,0x73,0x61,0x67,0x65,0x00,0x1B,0x5B,0x32,
12980x4A,0x1B,0x5B,0x31,0x3B,0x31,0x48,0x41,0x4E,0x53,0x49,0x20,0x54,0x65,0x72,0x6D,
12990x69,0x6E,0x61,0x6C,0x0D,0x0A,0x0A,0x00,0x1B,0x5B,0x4B,0x00,0x1B,0x5B,0x4A,0x00,
13000x1B,0x5B,0x32,0x4A,0x1B,0x5B,0x31,0x3B,0x31,0x48,0x00,0x1B,0x5B,0x44,0x20,0x1B,
13010x5B,0x44,0x00,0x1B,0x5B,0x31,0x3B,0x37,0x32,0x48,0x00,0x1B,0x5B,0x00,0x3B,0x00,
13020x48,0x00,0x1B,0x5B,0x73,0x00,0x1B,0x5B,0x75,0x00,0x1B,0x7A,0x2B,0x0B,0x7F,0x1B,
13030x7A,0x2E,0x0C,0x7F,0x1B,0x7A,0x2D,0x08,0x7F,0x1B,0x7A,0x2C,0x0A,0x7F,0x1B,0x7A,
13040x22,0x08,0x7F,0x1A,0x57,0x79,0x73,0x65,0x20,0x33,0x30,0x20,0x54,0x65,0x72,0x6D,
13050x69,0x6E,0x61,0x6C,0x0D,0x0A,0x00,0x1B,0x54,0x00,0x1B,0x59,0x00,0x1A,0x00,0x1E,
13060x00,0x08,0x20,0x08,0x00,0x00,0x1B,0x3D,0x00,0x00,0x00,0x1B,0x46,0x00,0x0D,0x00,
13070x3F,0x44,0x64,0x45,0x65,0x46,0x66,0x47,0x67,0x48,0x68,0x49,0x69,0x4F,0x6F,0x43,
13080x63,0x53,0x73,0x42,0x62,0x52,0x72,0x57,0x77,0x58,0x78,0x4C,0x6C,0x3C,0x60,0xD4,
13090x57,0xD4,0x57,0x50,0x58,0x50,0x58,0xD6,0x59,0xD6,0x59,0xB4,0x59,0xB4,0x59,0x3C,
13100x60,0x3C,0x60,0x6C,0x57,0x48,0x57,0x26,0x57,0x06,0x57,0x90,0x57,0x90,0x57,0x98,
13110x57,0x48,0x5F,0x0C,0x5F,0x58,0x5F,0x33,0x5F,0x40,0x5F,0xA0,0x57,0xA0,0x57,0xFE,
13120x59,0xFE,0x59,0xDC,0x57,0xDC,0x57,0x88,0x61,0x98,0x61,0xC0,0x61,0xCC,0x61,0xD8,
13130x61,0xF6,0x61,0x02,0x62,0x22,0x62,0xF8,0x56,0x4A,0x62,0x58,0x62,0x60,0x59,0x20,
13140x20,0x66,0x6C,0x61,0x67,0x73,0x3D,0x00,0x20,0x20,0x61,0x78,0x3D,0x00,0x20,0x20,
13150x62,0x78,0x3D,0x00,0x20,0x20,0x63,0x78,0x3D,0x00,0x20,0x20,0x64,0x78,0x3D,0x00,
13160x20,0x20,0x63,0x73,0x3D,0x00,0x20,0x20,0x64,0x73,0x3D,0x00,0x20,0x20,0x65,0x73,
13170x3D,0x00,0x20,0x20,0x73,0x73,0x3D,0x00,0x20,0x20,0x64,0x69,0x3D,0x00,0x20,0x20,
13180x73,0x69,0x3D,0x00,0x20,0x20,0x62,0x70,0x3D,0x00,0x20,0x20,0x73,0x70,0x3D,0x00,
13190x20,0x20,0x69,0x70,0x3D,0x00,0x20,0x63,0x68,0x61,0x6E,0x65,0x6C,0x3D,0x00,0x20,
13200x20,0x20,0x20,0x73,0x65,0x67,0x3D,0x00,0x20,0x74,0x69,0x5F,0x73,0x74,0x72,0x3D,
13210x00,0x20,0x74,0x69,0x5F,0x74,0x6F,0x73,0x3D,0x00,0x20,0x74,0x69,0x5F,0x6D,0x61,
13220x78,0x3D,0x00,0x20,0x74,0x69,0x5F,0x62,0x61,0x73,0x3D,0x00,0x20,0x74,0x69,0x5F,
13230x73,0x69,0x7A,0x3D,0x00,0x20,0x74,0x69,0x5F,0x73,0x74,0x66,0x3D,0x00,0x20,0x74,
13240x69,0x5F,0x72,0x6F,0x6F,0x3D,0x00,0x20,0x74,0x69,0x5F,0x66,0x6C,0x67,0x3D,0x00,
13250x20,0x74,0x69,0x5F,0x74,0x6F,0x74,0x3D,0x00,0x20,0x72,0x69,0x5F,0x70,0x63,0x6E,
13260x3D,0x00,0x20,0x72,0x69,0x5F,0x73,0x74,0x72,0x3D,0x00,0x20,0x72,0x69,0x5F,0x73,
13270x74,0x66,0x3D,0x00,0x20,0x72,0x69,0x5F,0x72,0x6F,0x6F,0x3D,0x00,0x20,0x72,0x69,
13280x5F,0x62,0x61,0x73,0x3D,0x00,0x20,0x72,0x69,0x5F,0x73,0x69,0x7A,0x3D,0x00,0x20,
13290x72,0x69,0x5F,0x74,0x6F,0x74,0x3D,0x00,0x20,0x72,0x69,0x5F,0x6D,0x69,0x6E,0x3D,
13300x00,0x20,0x72,0x69,0x5F,0x66,0x6C,0x67,0x3D,0x00,0x20,0x72,0x69,0x5F,0x74,0x6F,
13310x73,0x3D,0x00,0x20,0x72,0x69,0x5F,0x74,0x68,0x72,0x3D,0x00,0x20,0x74,0x68,0x5F,
13320x73,0x74,0x66,0x3D,0x00,0x20,0x74,0x68,0x5F,0x73,0x74,0x72,0x3D,0x00,0x20,0x74,
13330x68,0x5F,0x62,0x61,0x73,0x3D,0x00,0x20,0x74,0x68,0x5F,0x73,0x69,0x7A,0x3D,0x00,
13340x20,0x74,0x68,0x5F,0x74,0x72,0x67,0x3D,0x00,0x20,0x74,0x68,0x5F,0x66,0x6C,0x67,
13350x3D,0x00,0x20,0x74,0x68,0x5F,0x63,0x6E,0x74,0x3D,0x00,0x20,0x72,0x68,0x5F,0x73,
13360x74,0x72,0x3D,0x00,0x20,0x72,0x68,0x5F,0x73,0x74,0x66,0x3D,0x00,0x20,0x72,0x68,
13370x5F,0x62,0x61,0x73,0x3D,0x00,0x20,0x72,0x68,0x5F,0x73,0x69,0x7A,0x3D,0x00,0x20,
13380x72,0x68,0x5F,0x73,0x70,0x61,0x3D,0x00,0x20,0x72,0x68,0x5F,0x61,0x73,0x6F,0x3D,
13390x00,0x20,0x72,0x68,0x5F,0x72,0x6F,0x6F,0x3D,0x00,0x20,0x72,0x68,0x5F,0x66,0x6C,
13400x67,0x3D,0x00,0x20,0x6D,0x5F,0x63,0x61,0x72,0x65,0x3D,0x00,0x20,0x70,0x74,0x5F,
13410x66,0x6C,0x6F,0x3D,0x00,0x20,0x61,0x73,0x5F,0x66,0x6C,0x6F,0x3D,0x00,0x20,0x72,
13420x6D,0x5F,0x66,0x6C,0x6F,0x3D,0x00,0x20,0x20,0x20,0x71,0x5F,0x69,0x6E,0x3D,0x00,
13430x20,0x20,0x71,0x5F,0x6F,0x75,0x74,0x3D,0x00,0x20,0x71,0x5F,0x64,0x72,0x61,0x6E,
13440x3D,0x00,0x20,0x20,0x71,0x5F,0x74,0x69,0x6D,0x3D,0x00,0x20,0x20,0x20,0x71,0x5F,
13450x66,0x63,0x3D,0x00,0x20,0x71,0x5F,0x73,0x74,0x61,0x74,0x3D,0x00,0x20,0x71,0x5F,
13460x64,0x61,0x74,0x61,0x3D,0x00,0x20,0x71,0x5F,0x6D,0x6F,0x64,0x6D,0x3D,0x00,0x20,
13470x68,0x61,0x6E,0x64,0x5F,0x6F,0x3D,0x00,0x20,0x68,0x61,0x6E,0x64,0x5F,0x62,0x3D,
13480x00,0x20,0x68,0x61,0x6E,0x64,0x5F,0x65,0x3D,0x00,0x20,0x68,0x61,0x6E,0x64,0x5F,
13490x69,0x3D,0x00,0x20,0x20,0x6F,0x70,0x6F,0x73,0x74,0x3D,0x00,0x20,0x20,0x74,0x69,
13500x6D,0x65,0x6F,0x3D,0x00,0x20,0x63,0x75,0x73,0x74,0x6D,0x31,0x3D,0x00,0x20,0x63,
13510x75,0x73,0x74,0x6D,0x32,0x3D,0x00,0x20,0x63,0x75,0x73,0x74,0x6D,0x64,0x3D,0x00,
13520x20,0x74,0x78,0x72,0x61,0x74,0x65,0x3D,0x00,0x20,0x72,0x78,0x72,0x61,0x74,0x65,
13530x3D,0x00,0x20,0x20,0x63,0x5F,0x6D,0x61,0x70,0x3D,0x00,0x20,0x63,0x5F,0x61,0x64,
13540x64,0x72,0x3D,0x00,0x20,0x63,0x5F,0x61,0x69,0x73,0x72,0x3D,0x00,0x20,0x63,0x5F,
13550x78,0x74,0x61,0x67,0x3D,0x00,0x20,0x63,0x5F,0x64,0x65,0x66,0x72,0x3D,0x00,0x20,
13560x63,0x5F,0x66,0x6C,0x73,0x68,0x3D,0x00,0x20,0x74,0x78,0x6D,0x61,0x78,0x73,0x3D,
13570x00,0x20,0x72,0x69,0x5F,0x65,0x6D,0x73,0x3D,0x00,0x20,0x20,0x63,0x5F,0x6C,0x73,
13580x72,0x3D,0x00,0x20,0x20,0x63,0x5F,0x69,0x65,0x72,0x3D,0x00,0x20,0x20,0x63,0x5F,
13590x66,0x63,0x72,0x3D,0x00,0x20,0x20,0x63,0x5F,0x6D,0x63,0x72,0x3D,0x00,0x20,0x20,
13600x63,0x5F,0x6C,0x63,0x72,0x3D,0x00,0x20,0x20,0x63,0x5F,0x64,0x73,0x73,0x3D,0x00,
13610x20,0x63,0x5F,0x64,0x73,0x73,0x69,0x3D,0x00,0x20,0x63,0x5F,0x64,0x73,0x73,0x72,
13620x3D,0x00,0x20,0x20,0x63,0x5F,0x69,0x73,0x72,0x3D,0x00,0x20,0x20,0x63,0x5F,0x63,
13630x61,0x72,0x3D,0x00,0x20,0x20,0x63,0x5F,0x65,0x66,0x72,0x3D,0x00,0x20,0x63,0x5F,
13640x65,0x72,0x73,0x74,0x3D,0x00,0x20,0x63,0x5F,0x65,0x63,0x6E,0x74,0x3D,0x00,0x20,
13650x63,0x5F,0x62,0x72,0x6B,0x63,0x3D,0x00,0x20,0x63,0x5F,0x62,0x6F,0x6B,0x63,0x3D,
13660x00,0x20,0x63,0x5F,0x72,0x65,0x70,0x6C,0x3D,0x00,0x20,0x63,0x5F,0x63,0x63,0x73,
13670x72,0x3D,0x00,0x20,0x63,0x5F,0x73,0x74,0x74,0x31,0x3D,0x00,0x20,0x63,0x5F,0x73,
13680x74,0x74,0x32,0x3D,0x00,0x2B,0xC0,0x8E,0xD8,0x8E,0xC0,0xE8,0xC2,0x00,0xE8,0xE5,
13690x00,0xFA,0xBF,0x84,0x00,0xC7,0x05,0xDC,0x56,0x8C,0x4D,0x02,0xBF,0x0C,0x00,0xC7,
13700x05,0x6E,0x5E,0x8C,0x4D,0x02,0xBF,0x04,0x00,0xC7,0x05,0xBA,0x5E,0x8C,0x4D,0x02,
13710xE8,0xF1,0x00,0x90,0xE8,0x49,0x01,0xE8,0x16,0x00,0xF4,0x90,0xE8,0xE5,0x00,0xBE,
13720xBA,0x4D,0xE8,0x09,0x0C,0xA0,0x93,0x12,0xE8,0x5D,0x0C,0xE8,0xC2,0x09,0xEB,0xE4,
13730xE8,0xD5,0x0C,0xE8,0xC4,0x0C,0x0A,0xC0,0x74,0xF6,0x8B,0x1E,0xF8,0x79,0x3C,0x0D,
13740x74,0x2E,0x3C,0x08,0x74,0x17,0x3C,0x7F,0x74,0x13,0x83,0xFB,0x20,0x7F,0xE1,0x88,
13750x87,0xD6,0x79,0x43,0x89,0x1E,0xF8,0x79,0xE8,0x77,0x0C,0xEB,0xD3,0x0B,0xDB,0x74,
13760xCF,0x4B,0x89,0x1E,0xF8,0x79,0x8B,0x36,0x16,0x7A,0xE8,0xC1,0x0B,0xEB,0xC1,0x90,
13770xE8,0x02,0x00,0xEB,0xBB,0xC6,0x87,0xD6,0x79,0x00,0x0B,0xDB,0x74,0x1E,0xA0,0xD6,
13780x79,0xBF,0x60,0x51,0xB9,0x1D,0x00,0x8B,0xD9,0x06,0x0E,0x07,0xF2,0xAE,0x07,0x75,
13790x17,0x41,0x2B,0xD9,0xD1,0xE3,0x2E,0xFF,0x97,0x7D,0x51,0x90,0x33,0xC0,0xA3,0xF8,
13800x79,0xBE,0x89,0x4D,0xE8,0x87,0x0B,0xC3,0xBE,0x8D,0x4D,0xE8,0x80,0x0B,0xEB,0xEC,
13810xBA,0x00,0x02,0xB0,0x93,0xEE,0xB0,0x55,0xEE,0xBA,0x10,0x02,0xB0,0x93,0xEE,0xB0,
13820xAA,0xEE,0xBA,0x00,0x02,0xEC,0x3C,0x55,0x75,0x08,0xBA,0x10,0x02,0xEC,0x3C,0xAA,
13830x74,0x03,0xE8,0x2F,0xF6,0xC3,0xBA,0x04,0x02,0xB0,0x1A,0xEE,0xB0,0x20,0xEE,0xB0,
13840x30,0xEE,0xB0,0x40,0xEE,0xB0,0x80,0xEE,0xBA,0x00,0x02,0xB0,0x13,0xEE,0xB0,0x07,
13850xEE,0xBA,0x08,0x02,0xB0,0x80,0xEE,0xBA,0x02,0x02,0xB0,0xBB,0xEE,0xBA,0x04,0x02,
13860xB0,0x05,0xEE,0xC3,0xC6,0x06,0xCA,0x13,0x01,0xC7,0x06,0xF8,0x79,0x00,0x00,0xC6,
13870x06,0xF6,0x79,0x01,0xC7,0x06,0xD0,0x79,0x00,0x00,0xC7,0x06,0xD2,0x79,0x00,0x00,
13880xC7,0x06,0xD4,0x79,0x00,0x00,0xC7,0x06,0xFA,0x79,0x00,0x00,0xC7,0x06,0xFC,0x79,
13890x00,0x00,0xC7,0x06,0xFE,0x79,0x00,0x00,0xC7,0x06,0x00,0x7A,0x00,0x00,0xC7,0x06,
13900x02,0x7A,0xCE,0x59,0x8C,0x0E,0x04,0x7A,0xC7,0x06,0x06,0x7A,0x00,0x00,0xC7,0x06,
13910x27,0x7A,0x00,0x00,0xC6,0x06,0x29,0x7A,0x00,0xC6,0x06,0x2A,0x7A,0x00,0xC3,0x90,
13920xBE,0x22,0x4D,0xE8,0xC8,0x0A,0xE8,0x3F,0x00,0x2C,0x31,0x3C,0x01,0x77,0xF7,0xE8,
13930x81,0x09,0x8B,0x36,0x0C,0x7A,0xE8,0xB5,0x0A,0xBE,0x6A,0x4D,0xE8,0xAF,0x0A,0x0E,
13940x58,0xE8,0xF8,0x0A,0xBE,0x7A,0x4D,0xE8,0xA4,0x0A,0xC3,0x90,0x60,0xD1,0xE3,0x83,
13950xFB,0x18,0x73,0x11,0x1E,0xBA,0x00,0x00,0x8E,0xDA,0x2E,0xFF,0x97,0xB7,0x51,0x8B,
13960xEC,0x89,0x46,0x10,0x1F,0x61,0xCF,0x90,0xE8,0x4F,0x0B,0x0A,0xC0,0x75,0x05,0xE8,
13970x56,0x0B,0xEB,0xF4,0xC3,0x90,0x83,0x3E,0xF8,0x79,0x01,0x74,0x16,0xBE,0xD7,0x79,
13980xE8,0x31,0x0A,0x8B,0xD0,0xAC,0x3C,0x2C,0x74,0x04,0x3C,0x20,0x75,0x05,0xE8,0x23,
13990x0A,0xEE,0xC3,0xE9,0xD2,0xFE,0x83,0x3E,0xF8,0x79,0x01,0x74,0xF6,0xBE,0xD7,0x79,
14000xE8,0x11,0x0A,0x8B,0xD0,0xAC,0x3C,0x2C,0x74,0x08,0x3C,0x20,0x74,0x04,0xE9,0xB7,
14010xFE,0x90,0xE8,0xFF,0x09,0xEF,0xC3,0x90,0x8B,0x16,0x06,0x7A,0x83,0x3E,0xF8,0x79,
14020x01,0x74,0x0B,0xBE,0xD7,0x79,0xE8,0xEB,0x09,0x8B,0xD0,0xA3,0x06,0x7A,0xB0,0x20,
14030xE8,0x57,0x0B,0x8B,0x16,0x06,0x7A,0xEC,0xE8,0x6F,0x0B,0xC3,0x8B,0x16,0x06,0x7A,
14040x83,0x3E,0xF8,0x79,0x01,0x74,0x0B,0xBE,0xD7,0x79,0xE8,0xC7,0x09,0x8B,0xD0,0xA3,
14050x06,0x7A,0xB0,0x20,0xE8,0x33,0x0B,0x8B,0x16,0x06,0x7A,0xED,0xE8,0x67,0x0B,0xC3,
14060xFA,0xC6,0x06,0xF6,0x79,0x00,0xC3,0x90,0xC6,0x06,0xF6,0x79,0x01,0xFB,0xC3,0x90,
14070x06,0xE8,0x58,0x09,0xB0,0x20,0xE8,0x11,0x0B,0x26,0x8B,0x05,0xE8,0x47,0x0B,0xB0,
14080x08,0xE8,0x06,0x0B,0xE8,0x03,0x0B,0xE8,0x00,0x0B,0xE8,0xFD,0x0A,0xB8,0x01,0x00,
14090xE8,0xCF,0xF4,0xBA,0x02,0x02,0xEC,0x24,0x01,0x75,0x02,0xEB,0xDC,0xBA,0x06,0x02,
14100xEC,0x07,0xC3,0x90,0xC7,0x06,0x08,0x7A,0x10,0x00,0xEB,0x06,0xC7,0x06,0x08,0x7A,
14110x01,0x00,0x06,0x8E,0x06,0xFC,0x79,0x8B,0x3E,0xFA,0x79,0xE8,0x0E,0x09,0xE8,0x0B,
14120x00,0x89,0x3E,0xFA,0x79,0x8C,0x06,0xFC,0x79,0x07,0xC3,0x90,0xBE,0xB2,0x4D,0xE8,
14130x7C,0x09,0x8B,0x16,0x08,0x7A,0x52,0xE8,0x2A,0x09,0xE8,0x0F,0x0A,0xE8,0x0C,0x0A,
14140x33,0xDB,0xB9,0x10,0x00,0x90,0x26,0x8A,0x01,0xE8,0xBC,0x09,0xE8,0xFD,0x09,0x43,
14150xE2,0xF4,0xE8,0xF7,0x09,0xE8,0xF4,0x09,0x33,0xDB,0xB9,0x10,0x00,0x90,0x26,0x8A,
14160x01,0x3C,0x20,0x72,0x05,0x3C,0x7E,0x76,0x03,0x90,0xB0,0x2E,0xE8,0xE3,0x09,0x43,
14170xE2,0xEC,0xBE,0xB2,0x4D,0xE8,0x36,0x09,0x83,0xC7,0x10,0x5A,0x4A,0x75,0xB7,0xC3,
14180x06,0x8E,0x06,0x00,0x7A,0x8B,0x3E,0xFE,0x79,0xE8,0xA0,0x08,0x89,0x3E,0xFE,0x79,
14190x8C,0x06,0x00,0x7A,0x57,0x8B,0x36,0x0E,0x7A,0xE8,0x12,0x09,0xC7,0x06,0x08,0x7A,
14200x10,0x00,0xBA,0x00,0x02,0xE8,0xE8,0x00,0xE8,0x81,0xFF,0x5F,0xBA,0x00,0x00,0xE8,
14210xDE,0x00,0xBE,0xB5,0x4D,0xE8,0xF6,0x08,0x8C,0xC0,0xE8,0x3F,0x09,0xB0,0x3A,0xE8,
14220x90,0x09,0x8B,0xC7,0xE8,0x35,0x09,0xE8,0x7E,0x08,0xE8,0xC3,0x00,0x90,0xE8,0xB7,
14230x09,0xE8,0xA6,0x09,0x0A,0xC0,0x74,0xF6,0x3C,0x0B,0x75,0x06,0x83,0xEF,0x10,0xEB,
14240x19,0x90,0x3C,0x0A,0x75,0x06,0x83,0xC7,0x10,0xEB,0x0F,0x90,0x3C,0x0C,0x75,0x04,
14250x47,0xEB,0x07,0x90,0x3C,0x08,0x75,0x24,0x4F,0x90,0x8B,0x36,0xFE,0x79,0x8B,0xC7,
14260x2B,0xC6,0x3D,0x00,0x01,0x72,0xA5,0x3D,0x10,0x01,0x72,0x04,0x83,0xEE,0x20,0x90,
14270x83,0xC6,0x10,0x89,0x36,0xFE,0x79,0x57,0x8B,0xFE,0xEB,0x80,0x3C,0x2E,0x75,0x08,
14280xBA,0x01,0x13,0xE8,0x6A,0x00,0x07,0xC3,0xC6,0x06,0x0A,0x7A,0x02,0x32,0xC9,0x90,
14290x3C,0x30,0x72,0x4C,0x3C,0x39,0x76,0x0C,0x24,0x5F,0x3C,0x41,0x72,0x42,0x3C,0x46,
14300x77,0x3E,0x2C,0x07,0x2C,0x30,0x50,0xE8,0xCC,0x08,0x58,0x02,0xC8,0xFE,0x0E,0x0A,
14310x7A,0x74,0x0F,0xC0,0xE1,0x04,0xE8,0x2F,0x09,0xE8,0x1E,0x09,0x0A,0xC0,0x74,0xF6,
14320xEB,0xCE,0x26,0x88,0x0D,0xE8,0xE0,0x07,0x8A,0xD0,0xE8,0x23,0x00,0x8A,0xC1,0x3C,
14330x20,0x72,0x05,0x3C,0x7E,0x76,0x03,0x90,0xB0,0x2E,0xE8,0xD5,0x08,0xE9,0x70,0xFF,
14340xE8,0xC5,0x07,0xE8,0x0A,0x00,0x26,0x8A,0x05,0xE8,0x7C,0x08,0xE9,0x1D,0xFF,0x90,
14350xF6,0x06,0x26,0x7A,0x02,0x75,0x02,0x86,0xF2,0x52,0x8B,0x36,0x1A,0x7A,0xE8,0x0D,
14360x08,0x5A,0x52,0x8A,0xC6,0x02,0x06,0x24,0x7A,0xF6,0x06,0x26,0x7A,0x01,0x75,0x06,
14370xE8,0x9F,0x08,0xEB,0x0D,0x90,0x32,0xE4,0xE8,0x0D,0x08,0x8B,0x36,0x1C,0x7A,0xE8,
14380xEC,0x07,0x5A,0x8A,0xC2,0x02,0x06,0x25,0x7A,0xF6,0x06,0x26,0x7A,0x01,0x75,0x06,
14390xE8,0x7F,0x08,0xEB,0x06,0x90,0x32,0xE4,0xE8,0xED,0x07,0x8B,0x36,0x1E,0x7A,0xE8,
14400xCC,0x07,0xC3,0x90,0x06,0x8E,0x06,0x04,0x7A,0x8B,0x3E,0x02,0x7A,0xE8,0x3C,0x07,
14410x89,0x3E,0x02,0x7A,0x8C,0x06,0x04,0x7A,0x07,0xFF,0x1E,0x02,0x7A,0xC3,0xBE,0x97,
14420x4D,0xE8,0xAA,0x07,0xCB,0x90,0x06,0x57,0xBE,0xD7,0x79,0xE8,0x66,0x07,0x8B,0xD8,
14430xE8,0x61,0x07,0x8B,0xC8,0x2B,0xCB,0x78,0x11,0x8E,0xC3,0xBF,0x00,0x00,0xB8,0xFF,
14440xFF,0x51,0xB9,0x08,0x00,0xF3,0xAB,0x59,0xE2,0xF7,0x5F,0x07,0xC3,0x90,0x06,0xBE,
14450xD7,0x79,0xE8,0x3F,0x07,0x8B,0xD8,0xD1,0xE3,0x2E,0x8B,0x9F,0x44,0x00,0xBE,0x26,
14460x52,0xE8,0xF1,0x08,0x8B,0xC3,0xE8,0xDD,0x08,0xB8,0x01,0x00,0xE8,0x73,0xF2,0xE8,
14470xE0,0x08,0xBE,0x2F,0x52,0xE8,0xDD,0x08,0x8B,0x47,0x18,0xE8,0xC8,0x08,0xBE,0x77,
14480x52,0xE8,0xD1,0x08,0x8B,0x47,0x26,0xE8,0xBC,0x08,0xBE,0x53,0x52,0xE8,0xC5,0x08,
14490x8B,0x47,0x1E,0xE8,0xB0,0x08,0xBE,0x5C,0x52,0xE8,0xB9,0x08,0x8B,0x47,0x20,0xE8,
14500xA4,0x08,0xBE,0x6E,0x52,0xE8,0xAD,0x08,0x8B,0x47,0x24,0xE8,0x98,0x08,0xBE,0x80,
14510x52,0xE8,0xA1,0x08,0x8B,0x47,0x2A,0xE8,0x8C,0x08,0xE8,0x95,0x08,0xBE,0x38,0x52,
14520xE8,0x92,0x08,0x8B,0x07,0xE8,0x7E,0x08,0xBE,0x41,0x52,0xE8,0x87,0x08,0x8B,0x47,
14530x1A,0xE8,0x72,0x08,0xBE,0x4A,0x52,0xE8,0x7B,0x08,0x8B,0x47,0x1C,0xE8,0x66,0x08,
14540xBE,0x65,0x52,0xE8,0x6F,0x08,0x8B,0x47,0x22,0xE8,0x5A,0x08,0xE8,0x63,0x08,0xBE,
14550xD1,0x52,0xE8,0x60,0x08,0x8B,0x47,0x38,0xE8,0x4B,0x08,0xBE,0xAD,0x52,0xE8,0x54,
14560x08,0x8B,0x47,0x30,0xE8,0x3F,0x08,0xBE,0xB6,0x52,0xE8,0x48,0x08,0x8B,0x47,0x32,
14570xE8,0x33,0x08,0xBE,0xA4,0x52,0xE8,0x3C,0x08,0x8B,0x47,0x2E,0xE8,0x27,0x08,0xBE,
14580xBF,0x52,0xE8,0x30,0x08,0x8B,0x47,0x34,0xE8,0x1B,0x08,0xE8,0x24,0x08,0xBE,0x89,
14590x52,0xE8,0x21,0x08,0x8B,0x47,0x04,0xE8,0x0C,0x08,0xBE,0x92,0x52,0xE8,0x15,0x08,
14600x8B,0x47,0x14,0xE8,0x00,0x08,0xBE,0x9B,0x52,0xE8,0x09,0x08,0x8B,0x47,0x2C,0xE8,
14610xF4,0x07,0xBE,0xC8,0x52,0xE8,0xFD,0x07,0x8B,0x47,0x36,0xE8,0xE8,0x07,0xBE,0xDA,
14620x52,0xE8,0xF1,0x07,0x8B,0x47,0x3A,0xE8,0xDC,0x07,0xBE,0xE3,0x52,0xE8,0xE5,0x07,
14630x8B,0x47,0x3C,0xE8,0xD0,0x07,0xE8,0xD9,0x07,0xBE,0x19,0x53,0xE8,0xD6,0x07,0x8B,
14640x47,0x48,0xE8,0xC1,0x07,0xBE,0xFE,0x52,0xE8,0xCA,0x07,0x8B,0x47,0x42,0xE8,0xB5,
14650x07,0xBE,0x07,0x53,0xE8,0xBE,0x07,0x8B,0x47,0x44,0xE8,0xA9,0x07,0xBE,0x7C,0x53,
14660xE8,0xB2,0x07,0x8B,0x47,0x4C,0xE8,0x9D,0x07,0xBE,0x85,0x53,0xE8,0xA6,0x07,0x8B,
14670x47,0x4E,0xE8,0x91,0x07,0xBE,0x8E,0x53,0xE8,0x9A,0x07,0x8B,0x47,0x50,0xE8,0x85,
14680x07,0xE8,0x8E,0x07,0xBE,0x22,0x53,0xE8,0x8B,0x07,0x8B,0x47,0x4A,0xE8,0x76,0x07,
14690xBE,0xEC,0x52,0xE8,0x7F,0x07,0x8B,0x47,0x08,0xE8,0x6A,0x07,0xBE,0xF5,0x52,0xE8,
14700x73,0x07,0x8B,0x47,0x40,0xE8,0x5E,0x07,0xBE,0x10,0x53,0xE8,0x67,0x07,0x8B,0x47,
14710x46,0xE8,0x52,0x07,0xE8,0x5B,0x07,0xBE,0x6A,0x53,0xE8,0x58,0x07,0x8B,0x47,0x7A,
14720xE8,0x43,0x07,0xBE,0x3D,0x53,0xE8,0x4C,0x07,0x8B,0x47,0x70,0xE8,0x37,0x07,0xBE,
14730x46,0x53,0xE8,0x40,0x07,0x8B,0x47,0x72,0xE8,0x2B,0x07,0xBE,0x4F,0x53,0xE8,0x34,
14740x07,0x8B,0x47,0x74,0xE8,0x1F,0x07,0xE8,0x28,0x07,0xBE,0x2B,0x53,0xE8,0x25,0x07,
14750x8B,0x47,0x0C,0xE8,0x10,0x07,0xBE,0x34,0x53,0xE8,0x19,0x07,0x8B,0x47,0x10,0xE8,
14760x04,0x07,0xBE,0x58,0x53,0xE8,0x0D,0x07,0x8B,0x47,0x76,0xE8,0xF8,0x06,0xBE,0x61,
14770x53,0xE8,0x01,0x07,0x8B,0x47,0x78,0xE8,0xEC,0x06,0xBE,0x73,0x53,0xE8,0xF5,0x06,
14780x8B,0x47,0x3E,0xE8,0xE0,0x06,0xE8,0xE9,0x06,0xBE,0x97,0x53,0xE8,0xE6,0x06,0x8B,
14790x47,0x52,0xE8,0xD1,0x06,0xBE,0xA0,0x53,0xE8,0xDA,0x06,0x8B,0x47,0x54,0xE8,0xC5,
14800x06,0xBE,0xA9,0x53,0xE8,0xCE,0x06,0x8B,0x47,0x56,0xE8,0xB9,0x06,0xBE,0xB2,0x53,
14810xE8,0xC2,0x06,0x8B,0x47,0x58,0xE8,0xAD,0x06,0xBE,0xBB,0x53,0xE8,0xB6,0x06,0x8B,
14820x47,0x5A,0xE8,0xA1,0x06,0xBE,0xC4,0x53,0xE8,0xAA,0x06,0x8B,0x47,0x5C,0xE8,0x95,
14830x06,0xE8,0x9E,0x06,0xBE,0xCD,0x53,0xE8,0x9B,0x06,0x8B,0x47,0x5E,0xE8,0x86,0x06,
14840xBE,0xD6,0x53,0xE8,0x8F,0x06,0x8B,0x47,0x60,0xE8,0x7A,0x06,0xBE,0xDF,0x53,0xE8,
14850x83,0x06,0x8B,0x47,0x62,0xE8,0x6E,0x06,0xBE,0xE8,0x53,0xE8,0x77,0x06,0x8B,0x47,
14860x7C,0xE8,0x62,0x06,0xBE,0xF1,0x53,0xE8,0x6B,0x06,0x8B,0x47,0x7E,0xE8,0x56,0x06,
14870xBE,0xFA,0x53,0xE8,0x5F,0x06,0x8B,0x87,0x80,0x00,0xE8,0x49,0x06,0xE8,0x52,0x06,
14880xBE,0x42,0x54,0xE8,0x4F,0x06,0x8B,0x87,0x9E,0x00,0xE8,0x39,0x06,0xBE,0x03,0x54,
14890xE8,0x42,0x06,0x8B,0x47,0x64,0xE8,0x2D,0x06,0xBE,0x0C,0x54,0xE8,0x36,0x06,0x8B,
14900x47,0x6E,0xE8,0x21,0x06,0xBE,0x15,0x54,0xE8,0x2A,0x06,0x8B,0x87,0x8E,0x00,0xE8,
14910x14,0x06,0xBE,0x1E,0x54,0xE8,0x1D,0x06,0x8B,0x87,0x90,0x00,0xE8,0x07,0x06,0xBE,
14920x27,0x54,0xE8,0x10,0x06,0x8B,0x87,0x92,0x00,0xE8,0xFA,0x05,0xE8,0x03,0x06,0xBE,
14930x30,0x54,0xE8,0x00,0x06,0x8B,0x87,0x94,0x00,0xE8,0xEA,0x05,0xBE,0x39,0x54,0xE8,
14940xF3,0x05,0x8B,0x87,0x96,0x00,0xE8,0xDD,0x05,0xBE,0x6F,0x54,0xE8,0xE6,0x05,0x8B,
14950x87,0x98,0x00,0xE8,0xD0,0x05,0xBE,0x5D,0x54,0xE8,0xD9,0x05,0x8A,0x87,0xA0,0x00,
14960xE8,0xA7,0x05,0xBE,0x54,0x54,0xE8,0xCC,0x05,0x8A,0x47,0x28,0xE8,0x9B,0x05,0xBE,
14970x66,0x54,0xE8,0xC0,0x05,0x8A,0x87,0xA1,0x00,0xE8,0x8E,0x05,0xE8,0xB3,0x05,0xBE,
14980x78,0x54,0xE8,0xB0,0x05,0x8A,0x87,0xA2,0x00,0xE8,0x7E,0x05,0xBE,0x81,0x54,0xE8,
14990xA3,0x05,0x8A,0x87,0xA3,0x00,0xE8,0x71,0x05,0xBE,0x8A,0x54,0xE8,0x96,0x05,0x8A,
15000x87,0xA4,0x00,0xE8,0x64,0x05,0xBE,0x93,0x54,0xE8,0x89,0x05,0x8A,0x87,0xA5,0x00,
15010xE8,0x57,0x05,0xBE,0x9C,0x54,0xE8,0x7C,0x05,0x8A,0x87,0xA6,0x00,0xE8,0x4A,0x05,
15020xBE,0xA5,0x54,0xE8,0x6F,0x05,0x8A,0x87,0xA7,0x00,0xE8,0x3D,0x05,0xBE,0xAE,0x54,
15030xE8,0x62,0x05,0x8A,0x87,0xA8,0x00,0xE8,0x30,0x05,0xE8,0x55,0x05,0xBE,0xB7,0x54,
15040xE8,0x52,0x05,0x8A,0x87,0xA9,0x00,0xE8,0x20,0x05,0xBE,0xC0,0x54,0xE8,0x45,0x05,
15050x8A,0x87,0xAA,0x00,0xE8,0x13,0x05,0xBE,0xC9,0x54,0xE8,0x38,0x05,0x8A,0x87,0xAB,
15060x00,0xE8,0x06,0x05,0xBE,0xD2,0x54,0xE8,0x2B,0x05,0x8A,0x87,0xAD,0x00,0xE8,0xF9,
15070x04,0xBE,0xDB,0x54,0xE8,0x1E,0x05,0x8A,0x87,0xAE,0x00,0xE8,0xEC,0x04,0xBE,0xE4,
15080x54,0xE8,0x11,0x05,0x8A,0x87,0xAF,0x00,0xE8,0xDF,0x04,0xBE,0xED,0x54,0xE8,0x04,
15090x05,0x8A,0x87,0xB0,0x00,0xE8,0xD2,0x04,0xE8,0xF7,0x04,0xBE,0xF6,0x54,0xE8,0xF4,
15100x04,0x8A,0x87,0xB1,0x00,0xE8,0xC2,0x04,0xBE,0xFF,0x54,0xE8,0xE7,0x04,0x8A,0x87,
15110xB2,0x00,0xE8,0xB5,0x04,0xBE,0x08,0x55,0xE8,0xDA,0x04,0x8A,0x87,0xB3,0x00,0xE8,
15120xA8,0x04,0xBE,0x11,0x55,0xE8,0xCD,0x04,0x8A,0x87,0xBB,0x00,0xE8,0x9B,0x04,0xE8,
15130xC0,0x04,0xBE,0x1A,0x55,0xE8,0xBD,0x04,0x8A,0x87,0xBC,0x00,0xE8,0x8B,0x04,0xBE,
15140x23,0x55,0xE8,0xB0,0x04,0x8A,0x87,0xBE,0x00,0xE8,0x7E,0x04,0xBE,0x2C,0x55,0xE8,
15150xA3,0x04,0x8A,0x87,0xBF,0x00,0xE8,0x71,0x04,0xE8,0x96,0x04,0x07,0xC3,0x60,0x06,
15160x1E,0x16,0x8B,0xEC,0xFF,0x4E,0x16,0xF7,0x46,0x1A,0x00,0x02,0x74,0x01,0xFB,0xB8,
15170x00,0x00,0x8E,0xD8,0x8E,0xC0,0x89,0x2E,0x2D,0x7A,0xE8,0xCB,0x00,0x81,0x66,0x1A,
15180xFF,0xFE,0xC6,0x06,0x2A,0x7A,0x00,0xE8,0xD8,0x00,0xB8,0x00,0x5F,0xA3,0x2B,0x7A,
15190xE8,0x5D,0x00,0x80,0x3E,0x2A,0x7A,0x00,0x74,0x0A,0x81,0x4E,0x1A,0x00,0x01,0xC6,
15200x06,0x2A,0x7A,0x00,0x17,0x1F,0x07,0x61,0xCF,0x90,0x60,0x06,0x1E,0x16,0x8B,0xEC,
15210xF7,0x46,0x1A,0x00,0x02,0x74,0x01,0xFB,0xB8,0x00,0x00,0x8E,0xD8,0x8E,0xC0,0x89,
15220x2E,0x2D,0x7A,0x81,0x66,0x1A,0xFF,0xFE,0xC6,0x06,0x2A,0x7A,0x00,0xE8,0x92,0x00,
15230xB8,0x00,0x5F,0xA3,0x2B,0x7A,0xE8,0x17,0x00,0x80,0x3E,0x2A,0x7A,0x00,0x74,0x0A,
15240x81,0x4E,0x1A,0x00,0x01,0xC6,0x06,0x2A,0x7A,0x00,0x17,0x1F,0x07,0x61,0xCF,0x90,
15250xB8,0xF0,0x00,0xE8,0x8C,0xED,0xFF,0x26,0x2B,0x7A,0xC3,0x90,0x06,0x53,0x56,0x80,
15260x3E,0x29,0x7A,0x00,0x74,0x03,0xE8,0x3F,0x00,0xBE,0xD7,0x79,0xE8,0x25,0x02,0x8B,
15270xD8,0xA3,0x27,0x7A,0x2E,0x8A,0x07,0xA2,0x29,0x7A,0xB0,0xCC,0x2E,0x88,0x07,0x5E,
15280x5B,0x07,0xC3,0xC6,0x06,0x2A,0x7A,0x00,0xB8,0x0A,0x5F,0xA3,0x2B,0x7A,0xC3,0x90,
15290x8B,0x2E,0x2D,0x7A,0xE8,0x2B,0x00,0xC3,0xC6,0x06,0x2A,0x7A,0x01,0xE8,0x08,0x00,
15300xB8,0x0A,0x5F,0xA3,0x2B,0x7A,0xC3,0x90,0x57,0x80,0x3E,0x29,0x7A,0x00,0x74,0x0F,
15310x8B,0x3E,0x27,0x7A,0xA0,0x29,0x7A,0x2E,0x88,0x05,0xC6,0x06,0x29,0x7A,0x00,0x5F,
15320xC3,0x90,0xBE,0xB2,0x4D,0xE8,0x06,0x02,0xBE,0xD8,0x51,0xE8,0x00,0x02,0xFF,0x76,
15330x14,0x58,0xE8,0x47,0x02,0xBE,0xDE,0x51,0xE8,0xF3,0x01,0xFF,0x76,0x0E,0x58,0xE8,
15340x3A,0x02,0xBE,0xE4,0x51,0xE8,0xE6,0x01,0xFF,0x76,0x12,0x58,0xE8,0x2D,0x02,0xBE,
15350xEA,0x51,0xE8,0xD9,0x01,0xFF,0x76,0x10,0x58,0xE8,0x20,0x02,0xBE,0x14,0x52,0xE8,
15360xCC,0x01,0xFF,0x76,0x0A,0x58,0xE8,0x13,0x02,0xBE,0x1A,0x52,0xE8,0xBF,0x01,0xFF,
15370x76,0x0C,0x58,0xE8,0x06,0x02,0xBE,0xCF,0x51,0xE8,0xB2,0x01,0xFF,0x76,0x1A,0x58,
15380xE8,0xF9,0x01,0xBE,0xB2,0x4D,0xE8,0xA5,0x01,0xBE,0xF0,0x51,0xE8,0x9F,0x01,0xFF,
15390x76,0x18,0x58,0xE8,0xE6,0x01,0xBE,0xF6,0x51,0xE8,0x92,0x01,0xFF,0x76,0x02,0x58,
15400xE8,0xD9,0x01,0xBE,0xFC,0x51,0xE8,0x85,0x01,0xFF,0x76,0x04,0x58,0xE8,0xCC,0x01,
15410xBE,0x02,0x52,0xE8,0x78,0x01,0xFF,0x76,0x00,0x58,0xE8,0xBF,0x01,0xBE,0x08,0x52,
15420xE8,0x6B,0x01,0xFF,0x76,0x06,0x58,0xE8,0xB2,0x01,0xBE,0x0E,0x52,0xE8,0x5E,0x01,
15430xFF,0x76,0x08,0x58,0xE8,0xA5,0x01,0xBE,0x20,0x52,0xE8,0x51,0x01,0xFF,0x76,0x16,
15440x58,0xE8,0x98,0x01,0xBE,0x89,0x4D,0xE8,0x44,0x01,0xC3,0x90,0xBE,0xC9,0x4D,0xE8,
15450x3C,0x01,0xC3,0x3C,0x00,0x74,0x05,0x3C,0x01,0x74,0x59,0xC3,0xC7,0x06,0x0C,0x7A,
15460xCD,0x50,0xC7,0x06,0x0E,0x7A,0xF0,0x50,0xC7,0x06,0x10,0x7A,0xE8,0x50,0xC7,0x06,
15470x12,0x7A,0xEC,0x50,0xC7,0x06,0x14,0x7A,0xF4,0x50,0xC7,0x06,0x16,0x7A,0xFB,0x50,
15480xC7,0x06,0x18,0x7A,0x03,0x51,0xC7,0x06,0x1A,0x7A,0x0B,0x51,0xC7,0x06,0x1C,0x7A,
15490x0E,0x51,0xC7,0x06,0x1E,0x7A,0x10,0x51,0xC7,0x06,0x20,0x7A,0x12,0x51,0xC7,0x06,
15500x22,0x7A,0x16,0x51,0xC6,0x06,0x24,0x7A,0x01,0xC6,0x06,0x25,0x7A,0x01,0xC6,0x06,
15510x26,0x7A,0x03,0xC3,0xC7,0x06,0x0C,0x7A,0x1A,0x51,0xC7,0x06,0x0E,0x7A,0x4D,0x51,
15520xC7,0x06,0x10,0x7A,0x47,0x51,0xC7,0x06,0x12,0x7A,0x4A,0x51,0xC7,0x06,0x14,0x7A,
15530x4F,0x51,0xC7,0x06,0x16,0x7A,0x51,0x51,0xC7,0x06,0x18,0x7A,0x55,0x51,0xC7,0x06,
15540x1A,0x7A,0x56,0x51,0xC7,0x06,0x1C,0x7A,0x59,0x51,0xC7,0x06,0x1E,0x7A,0x5A,0x51,
15550xC7,0x06,0x20,0x7A,0x5B,0x51,0xC7,0x06,0x22,0x7A,0x5E,0x51,0xC6,0x06,0x24,0x7A,
15560x20,0xC6,0x06,0x25,0x7A,0x20,0xC6,0x06,0x26,0x7A,0x02,0xC3,0xA1,0xF8,0x79,0x48,
15570x74,0x14,0xBE,0xD7,0x79,0xE8,0x3C,0x00,0x8B,0xF8,0xAC,0x3C,0x3A,0x75,0x07,0x8E,
15580xC7,0xE8,0x30,0x00,0x8B,0xF8,0xC3,0x90,0x8B,0xC7,0x2B,0x06,0xFE,0x79,0x8A,0xF0,
15590x24,0x0F,0x8A,0xD0,0x02,0xD0,0x02,0xD0,0x80,0xC2,0x0B,0xC0,0xEE,0x04,0x80,0xC6,
15600x03,0x04,0x3D,0xC3,0x8C,0xC0,0xE8,0x93,0x00,0xB0,0x3A,0xE8,0xE4,0x00,0x8B,0xC7,
15610xE8,0x89,0x00,0xC3,0x51,0x33,0xC9,0x90,0xAC,0x3C,0x20,0x74,0xFB,0x90,0x0A,0xC0,
15620x74,0x26,0x2C,0x30,0x72,0x22,0x3C,0x09,0x76,0x14,0x3C,0x11,0x72,0x1A,0x2C,0x07,
15630x3C,0x0F,0x76,0x0A,0x3C,0x2A,0x72,0x10,0x2C,0x20,0x3C,0x0F,0x77,0x0A,0x98,0xC1,
15640xE1,0x04,0x03,0xC8,0xAC,0xEB,0xD7,0x90,0x4E,0x8B,0xC1,0x59,0xC3,0x90,0x06,0x8C,
15650xC8,0x8E,0xC0,0xE8,0x02,0x00,0x07,0xC3,0x26,0x8A,0x04,0x46,0x0A,0xC0,0x74,0x06,
15660xE8,0x8F,0x00,0xEB,0xF3,0x90,0xC3,0x90,0x0B,0xC0,0x74,0x7A,0x51,0x33,0xD2,0xB9,
15670xE8,0x03,0xF7,0xF1,0x8B,0xCA,0xE8,0x03,0x00,0x8B,0xC1,0x59,0xBA,0x64,0x00,0xF6,
15680xF2,0xE8,0x0C,0x00,0x8A,0xC4,0x98,0xB2,0x0A,0xF6,0xF2,0xE8,0x02,0x00,0x8A,0xC4,
15690x50,0x0A,0xF0,0x74,0x05,0x04,0x30,0xE8,0x58,0x00,0x58,0xC3,0x86,0xC4,0xE8,0x07,
15700x00,0x86,0xC4,0xE8,0x02,0x00,0xC3,0x90,0xC1,0xC8,0x04,0xE8,0x08,0x00,0xC1,0xC0,
15710x04,0xE8,0x02,0x00,0xC3,0x90,0x53,0x50,0x24,0x0F,0xBB,0xCA,0x62,0x2E,0xD7,0xE8,
15720x30,0x00,0x58,0x5B,0xC3,0x90,0x86,0xC4,0xE8,0x07,0x00,0x86,0xC4,0xE8,0x02,0x00,
15730xC3,0x90,0x50,0xB9,0x08,0x00,0x8A,0xE0,0x32,0xC0,0xD1,0xC0,0x04,0x30,0xE8,0x11,
15740x00,0xE2,0xF5,0x58,0xC3,0x90,0xB0,0x30,0xE8,0x07,0x00,0xC3,0xB0,0x20,0xE8,0x01,
15750x00,0xC3,0x56,0x8B,0x36,0xD0,0x79,0x88,0x84,0xD0,0x77,0x46,0x81,0xE6,0xFF,0x01,
15760xFF,0x06,0xD4,0x79,0x89,0x36,0xD0,0x79,0x81,0x3E,0xD4,0x79,0xFE,0x01,0x75,0x08,
15770x56,0xE8,0x14,0x00,0x5E,0xEB,0xF1,0x90,0x5E,0xC3,0xBA,0x02,0x02,0xEC,0x24,0x01,
15780x74,0x04,0xBA,0x06,0x02,0xEC,0xC3,0x90,0x80,0x3E,0xF6,0x79,0x00,0x74,0x09,0x60,
15790xB8,0x01,0x00,0xE8,0x2C,0xEA,0x61,0x90,0xBA,0x02,0x02,0xEC,0xA8,0x04,0x74,0x28,
15800x8B,0x36,0xD2,0x79,0x83,0x3E,0xD4,0x79,0x00,0x74,0x1D,0x8A,0x84,0xD0,0x77,0x46,
15810x81,0xE6,0xFF,0x01,0x89,0x36,0xD2,0x79,0xFF,0x0E,0xD4,0x79,0xBA,0x06,0x02,0xEE,
15820xBA,0x02,0x02,0xEC,0xA8,0x04,0x75,0xDC,0xA1,0xD4,0x79,0xC3,0x52,0xBA,0x06,0x02,
15830xEE,0x5A,0xC3,0x90,0x52,0x50,0xBA,0x02,0x02,0xEC,0xA8,0x04,0x74,0x08,0x58,0x5A,
15840xE8,0xE9,0xFF,0xF9,0xC3,0x90,0x58,0x5A,0xF8,0xC3,0x52,0x50,0xBA,0x02,0x02,0xEC,
15850xA8,0x04,0x74,0xFB,0x58,0x5A,0xE8,0xD3,0xFF,0xC3,0x30,0x31,0x32,0x33,0x34,0x35,
15860x36,0x37,0x38,0x39,0x41,0x42,0x43,0x44,0x45,0x46,0x53,0x50,0x8A,0xE0,0x80,0xE4,
15870x0F,0xBB,0xCA,0x62,0xC0,0xE8,0x04,0x2E,0xD7,0xE8,0xCE,0xFF,0x8A,0xC4,0x2E,0xD7,
15880xE8,0xC7,0xFF,0x58,0x5B,0xC3,0x86,0xE0,0xE8,0xDF,0xFF,0x86,0xE0,0xE8,0xDA,0xFF,
15890xC3,0x90,0xBE,0xB2,0x4D,0x50,0x2E,0xAC,0x3C,0x00,0x74,0x05,0xE8,0xAB,0xFF,0xEB,
15900xF5,0x58,0xC3,0x90,0xC8,0x08,0x00,0x00,0x56,0x57,0x8B,0x76,0x04,0xBF,0x04,0x00,
15910xC7,0x46,0xFC,0x00,0x00,0xC7,0x46,0xFA,0x00,0x00,0xC7,0x46,0xF8,0x00,0x00,0x83,
15920x7E,0x06,0x00,0x75,0x0E,0x56,0xE8,0xB6,0x0E,0x59,0x0B,0xC0,0x75,0x05,0x8B,0xC7,
15930xE9,0x5B,0x01,0x8B,0x46,0xFC,0x89,0x46,0xFE,0x0B,0xFF,0x75,0x05,0xB8,0x01,0x00,
15940xEB,0x02,0x33,0xC0,0x50,0x56,0xE8,0xA4,0x0D,0x59,0x59,0xB4,0x00,0x89,0x46,0xFC,
15950x8B,0x5E,0xFC,0x83,0xFB,0x08,0x76,0x03,0xE9,0x2B,0x01,0xD1,0xE3,0x2E,0xFF,0xA7,
15960xB2,0x64,0xB8,0x03,0x00,0xE9,0x26,0x01,0x83,0x7E,0xFA,0x00,0x74,0x14,0xC7,0x46,
15970xFA,0x00,0x00,0x8A,0x44,0x58,0x98,0x50,0x8A,0x44,0x59,0x98,0x50,0xE8,0xC2,0x0F,
15980x59,0x59,0x83,0x7E,0xF8,0x00,0x74,0x0A,0xC7,0x46,0xF8,0x00,0x00,0x56,0xE8,0x9B,
15990x08,0x59,0x83,0x7E,0x06,0x00,0x75,0x05,0x8B,0xC7,0xE9,0xF1,0x00,0x83,0xFF,0x04,
16000x75,0x03,0xE9,0xE6,0x00,0x8B,0xC7,0xE9,0xE4,0x00,0x83,0x7E,0xFE,0x00,0x75,0x03,
16010xBF,0x02,0x00,0xE9,0xD5,0x00,0x83,0x7E,0xFE,0x00,0x75,0x03,0xBF,0x01,0x00,0xE9,
16020xC9,0x00,0x8B,0x5E,0xFE,0x83,0xFB,0x07,0x76,0x03,0xE9,0x86,0x00,0xD1,0xE3,0x2E,
16030xFF,0xA7,0xA2,0x64,0x33,0xFF,0xE9,0x7F,0x00,0xBF,0x04,0x00,0x80,0x7C,0x58,0x0F,
16040x74,0x22,0x83,0x7E,0xF8,0x00,0x75,0x1C,0xFE,0x44,0x58,0x6A,0x08,0x56,0xE8,0x7E,
16050x0C,0x59,0x59,0x8A,0x44,0x58,0x04,0x80,0x50,0x56,0xE8,0x72,0x0C,0x59,0x59,0xC7,
16060x46,0xFA,0x01,0x00,0x83,0x7E,0xF8,0x00,0x74,0x0A,0xC7,0x46,0xF8,0x00,0x00,0x56,
16070xE8,0x19,0x08,0x59,0xEB,0x42,0xBF,0x04,0x00,0x80,0x7C,0x58,0x00,0x74,0x22,0x83,
16080x7E,0xF8,0x00,0x75,0x1C,0xFE,0x4C,0x58,0x6A,0x08,0x56,0xE8,0x41,0x0C,0x59,0x59,
16090x8A,0x44,0x58,0x04,0x80,0x50,0x56,0xE8,0x35,0x0C,0x59,0x59,0xC7,0x46,0xFA,0x01,
16100x00,0x83,0x7E,0xF8,0x00,0x74,0x0A,0xC7,0x46,0xF8,0x00,0x00,0x56,0xE8,0xDC,0x07,
16110x59,0xEB,0x05,0xBF,0x04,0x00,0xEB,0x00,0xEB,0x31,0xBF,0x04,0x00,0xEB,0x2C,0xC7,
16120x46,0xF8,0x01,0x00,0x6A,0x08,0x56,0xE8,0x05,0x0C,0x59,0x59,0x80,0x7C,0x58,0x09,
16130x7D,0x04,0xB0,0x0F,0xEB,0x02,0xB0,0x00,0x04,0x80,0x50,0x56,0xE8,0xF0,0x0B,0x59,
16140x59,0xBF,0x04,0x00,0xEB,0x05,0xBF,0x04,0x00,0xEB,0x00,0xE9,0xA5,0xFE,0x5F,0x5E,
16150xC9,0xC3,0xE4,0x63,0x63,0x64,0x63,0x64,0x63,0x64,0x63,0x64,0xE9,0x63,0x26,0x64,
16160x51,0x64,0x78,0x63,0xBA,0x63,0xC6,0x63,0x96,0x64,0xD2,0x63,0x6A,0x64,0x6A,0x64,
16170x6F,0x64,0x72,0x63,0xC8,0x08,0x00,0x00,0x56,0x57,0x8B,0x76,0x04,0x8B,0x7E,0x08,
16180x6A,0x01,0x56,0xE8,0xA9,0x0B,0x59,0x59,0x8A,0x46,0x06,0xC0,0xE0,0x06,0x04,0x80,
16190x50,0x56,0xE8,0x9A,0x0B,0x59,0x59,0xC7,0x46,0xFE,0x00,0x00,0x89,0x7E,0xF8,0xEB,
16200x03,0xFF,0x46,0xFE,0x8B,0x5E,0xF8,0xFF,0x46,0xF8,0x80,0x3F,0x00,0x75,0xF2,0x83,
16210x7E,0xFE,0x10,0x7D,0x25,0xB8,0x10,0x00,0x2B,0x46,0xFE,0xD1,0xF8,0x89,0x46,0xFC,
16220xC7,0x46,0xFA,0x00,0x00,0xEB,0x0B,0x6A,0x20,0x56,0xE8,0x62,0x0B,0x59,0x59,0xFF,
16230x46,0xFA,0x8B,0x46,0xFA,0x3B,0x46,0xFC,0x7C,0xED,0xEB,0x0C,0x8B,0xDF,0x47,0x8A,
16240x07,0x50,0x56,0xE8,0x49,0x0B,0x59,0x59,0x80,0x3D,0x00,0x75,0xEF,0x6A,0x02,0x56,
16250xE8,0x3C,0x0B,0x59,0x59,0xEB,0x00,0x5F,0x5E,0xC9,0xC3,0xC8,0x04,0x00,0x00,0x56,
16260x57,0x8B,0x7E,0x04,0xC7,0x46,0xFE,0x00,0x00,0xBE,0x14,0x00,0xE9,0x09,0x01,0x8B,
16270x5E,0xFE,0x83,0xC3,0x04,0x2B,0xDF,0x8A,0x87,0xAC,0x0B,0x88,0x44,0x5A,0xC6,0x44,
16280x58,0x08,0x8A,0x46,0xFE,0x88,0x44,0x59,0xC7,0x44,0x06,0x00,0x00,0xC6,0x44,0x19,
16290x00,0xC6,0x44,0x1A,0x00,0xC6,0x44,0x1B,0x00,0xC6,0x44,0x1D,0x0D,0xC6,0x44,0x1E,
16300x03,0xC6,0x44,0x1F,0x00,0xC6,0x44,0x20,0x00,0xC6,0x44,0x21,0x00,0xC6,0x44,0x5B,
16310x00,0xC6,0x44,0x5D,0x00,0xC6,0x44,0x5E,0x00,0xC6,0x44,0x5F,0x00,0xC6,0x44,0x60,
16320x00,0xC7,0x46,0xFC,0x00,0x00,0xEB,0x0D,0x8B,0x5E,0xFC,0xD1,0xE3,0xC7,0x40,0x30,
16330x00,0x00,0xFF,0x46,0xFC,0x83,0x7E,0xFC,0x10,0x7C,0xED,0xC7,0x46,0xFC,0x00,0x00,
16340xEB,0x0A,0x8B,0x5E,0xFC,0xC6,0x40,0x50,0x00,0xFF,0x46,0xFC,0x83,0x7E,0xFC,0x04,
16350x7C,0xF0,0xC7,0x44,0x54,0x00,0x00,0xC7,0x44,0x56,0x00,0x00,0x8A,0x44,0x5A,0x98,
16360xBA,0xF8,0x00,0x23,0xD0,0xB8,0x05,0x00,0x0B,0xC2,0x89,0x46,0xFC,0x9C,0xFA,0x8A,
16370x46,0xFC,0xBA,0xFE,0x00,0xEE,0xBA,0x00,0x00,0xEC,0x9D,0x24,0x08,0x88,0x46,0xFC,
16380x83,0x7E,0xFC,0x00,0x75,0x02,0xEB,0x4A,0xFF,0x76,0xFE,0xE8,0x7A,0x0C,0x59,0x68,
16390x35,0x02,0x56,0xE8,0x32,0x0A,0x59,0x59,0x0B,0xC0,0x75,0x34,0x68,0x38,0x02,0x56,
16400xE8,0x25,0x0A,0x59,0x59,0x0B,0xC0,0x75,0x27,0x68,0x42,0x02,0x56,0xE8,0x18,0x0A,
16410x59,0x59,0x0B,0xC0,0x75,0x1A,0x68,0x4C,0x02,0x56,0xE8,0x0B,0x0A,0x59,0x59,0x0B,
16420xC0,0x75,0x0D,0x68,0x56,0x02,0x56,0xE8,0xFE,0x09,0x59,0x59,0x0B,0xC0,0x74,0x02,
16430xEB,0x00,0xFF,0x46,0xFE,0x83,0xC6,0x62,0x39,0x7E,0xFE,0x7D,0x03,0xE9,0xEF,0xFE,
16440xEB,0x00,0x5F,0x5E,0xC9,0xC3,0xC8,0x08,0x00,0x00,0x56,0x57,0x8B,0x46,0x04,0xBA,
16450x62,0x00,0xF7,0xEA,0x05,0x14,0x00,0x8B,0xF0,0x83,0x7E,0x06,0x00,0x74,0x05,0xB8,
16460x10,0x00,0xEB,0x03,0xB8,0x08,0x00,0x89,0x44,0x04,0x8A,0x46,0x08,0x88,0x44,0x5C,
16470x56,0xE8,0x59,0x04,0x59,0x8B,0xF8,0x8B,0xC7,0x89,0x44,0x56,0x89,0x44,0x54,0x8A,
16480x44,0x5D,0x88,0x44,0x2F,0x0B,0xFF,0x75,0x1D,0x68,0xC2,0x0F,0x6A,0x01,0x56,0xE8,
16490x02,0xFE,0x83,0xC4,0x06,0xEB,0x00,0x6A,0x01,0x56,0xE8,0x47,0xFC,0x59,0x59,0x0B,
16500xC0,0x75,0xF4,0xBF,0x01,0x00,0x89,0x7E,0xFA,0xB9,0x05,0x00,0xBB,0xE9,0x6A,0x2E,
16510x8B,0x07,0x3B,0x46,0xFA,0x74,0x07,0x43,0x43,0xE2,0xF4,0xE9,0xA4,0x03,0x2E,0xFF,
16520x67,0x0A,0xC7,0x44,0x06,0x02,0x00,0xC7,0x44,0x08,0xF4,0x08,0x8B,0x5E,0x04,0xD1,
16530xE3,0x8B,0x87,0xFC,0x08,0x89,0x44,0x0A,0x33,0xC0,0x8B,0xF8,0x89,0x44,0x54,0xE9,
16540x80,0x03,0x56,0xE8,0xBB,0x05,0x59,0xBF,0x01,0x00,0x8A,0x44,0x5D,0x88,0x44,0x60,
16550xE9,0x6F,0x03,0x83,0x7C,0x04,0x08,0x75,0x30,0x80,0x7C,0x5C,0x01,0x75,0x15,0x8A,
16560x44,0x5D,0xB4,0x00,0xD1,0xE0,0x8B,0xD8,0xFF,0xB7,0xE4,0x08,0x56,0xE8,0xF7,0x08,
16570x59,0x59,0xEB,0x13,0x8A,0x44,0x5D,0xB4,0x00,0xD1,0xE0,0x8B,0xD8,0xFF,0xB7,0xC4,
16580x08,0x56,0xE8,0xE2,0x08,0x59,0x59,0xEB,0x2E,0x80,0x7C,0x5C,0x01,0x75,0x15,0x8A,
16590x44,0x5D,0xB4,0x00,0xD1,0xE0,0x8B,0xD8,0xFF,0xB7,0xD4,0x08,0x56,0xE8,0xC7,0x08,
16600x59,0x59,0xEB,0x13,0x8A,0x44,0x5D,0xB4,0x00,0xD1,0xE0,0x8B,0xD8,0xFF,0xB7,0xB4,
16610x08,0x56,0xE8,0xB2,0x08,0x59,0x59,0x6A,0x01,0x56,0xE8,0x87,0xFB,0x59,0x59,0x8B,
16620xD8,0x83,0xFB,0x03,0x77,0x2A,0xD1,0xE3,0x2E,0xFF,0xA7,0xE1,0x6A,0xBF,0x01,0x00,
16630x8A,0x44,0x5D,0x88,0x44,0x5E,0xEB,0x18,0x8A,0x44,0x5D,0x04,0xFF,0x24,0x07,0x88,
16640x44,0x5D,0xEB,0x0C,0x8A,0x44,0x5D,0xFE,0xC0,0x24,0x07,0x88,0x44,0x5D,0xEB,0x00,
16650xE9,0xCF,0x02,0x8A,0x44,0x5D,0xB4,0x00,0xD1,0xE0,0x8B,0xD8,0xFF,0xB7,0xFD,0x02,
16660x56,0xE8,0x63,0x08,0x59,0x59,0x68,0x1D,0x03,0x56,0xE8,0x5A,0x08,0x59,0x59,0x6A,
16670x01,0x56,0xE8,0x2F,0xFB,0x59,0x59,0x8B,0xD8,0x83,0xFB,0x03,0x77,0x36,0xD1,0xE3,
16680x2E,0xFF,0xA7,0xD9,0x6A,0xBF,0x01,0x00,0x8A,0x44,0x5D,0x88,0x44,0x5F,0xEB,0x24,
16690x8A,0x44,0x5D,0x04,0xFF,0x8A,0x54,0x04,0x80,0xC2,0xFF,0x22,0xC2,0x88,0x44,0x5D,
16700xEB,0x12,0x8A,0x44,0x5D,0xFE,0xC0,0x8A,0x54,0x04,0x80,0xC2,0xFF,0x22,0xC2,0x88,
16710x44,0x5D,0xEB,0x00,0xE9,0x6B,0x02,0x8B,0x5C,0x06,0x83,0xC3,0xFE,0xD1,0xE3,0x8B,
16720x40,0x08,0x89,0x04,0x8B,0x1C,0xFF,0x77,0x06,0x6A,0x00,0x56,0xE8,0x85,0xFC,0x83,
16730xC4,0x06,0x8B,0x5C,0x06,0x4B,0xD1,0xE3,0x8B,0x40,0x08,0x89,0x44,0x02,0x8B,0x5C,
16740x02,0xFF,0x77,0x06,0x6A,0x01,0x56,0xE8,0x6A,0xFC,0x83,0xC4,0x06,0x6A,0x01,0x56,
16750xE8,0xB1,0xFA,0x59,0x59,0x8B,0xD8,0x83,0xFB,0x03,0x76,0x03,0xE9,0x1F,0x02,0xD1,
16760xE3,0x2E,0xFF,0xA7,0xD1,0x6A,0x8B,0x5C,0x02,0x8B,0x47,0x04,0x89,0x44,0x02,0x8B,
16770x5C,0x02,0x80,0x3F,0x44,0x75,0x0D,0x8B,0x5C,0x02,0x8A,0x47,0x01,0xB4,0x00,0x3B,
16780x44,0x04,0x7D,0xE2,0x8B,0x46,0x04,0xD1,0xE0,0x8B,0x1C,0x03,0xD8,0x8B,0x44,0x02,
16790x89,0x47,0x08,0x8B,0x5C,0x06,0x4B,0xD1,0xE3,0x8B,0x44,0x02,0x89,0x40,0x08,0xE9,
16800xDE,0x01,0x8B,0x5C,0x02,0x8B,0x47,0x02,0x89,0x44,0x02,0x8B,0x5C,0x02,0x80,0x3F,
16810x44,0x75,0x0D,0x8B,0x5C,0x02,0x8A,0x47,0x01,0xB4,0x00,0x3B,0x44,0x04,0x7D,0xE2,
16820x8B,0x46,0x04,0xD1,0xE0,0x8B,0x1C,0x03,0xD8,0x8B,0x44,0x02,0x89,0x47,0x08,0x8B,
16830x5C,0x06,0x4B,0xD1,0xE3,0x8B,0x44,0x02,0x89,0x40,0x08,0xE9,0xA2,0x01,0xBF,0x01,
16840x00,0xE9,0x9C,0x01,0x8B,0x5C,0x02,0x8A,0x07,0xB4,0x00,0x89,0x46,0xF8,0xB9,0x0C,
16850x00,0xBB,0xA1,0x6A,0x2E,0x8B,0x07,0x3B,0x46,0xF8,0x74,0x07,0x43,0x43,0xE2,0xF4,
16860xE9,0x77,0x01,0x2E,0xFF,0x67,0x18,0x8B,0x46,0x04,0xD1,0xE0,0x8B,0x5C,0x02,0x03,
16870xD8,0x8B,0x47,0x08,0x8B,0x5C,0x06,0xFF,0x44,0x06,0xD1,0xE3,0x89,0x40,0x08,0x8B,
16880x1C,0x80,0x7F,0x01,0x00,0x74,0x12,0x8B,0x5C,0x02,0x8A,0x47,0x01,0x8B,0x1C,0x8A,
16890x57,0x01,0xB6,0x00,0x8B,0xDA,0x88,0x40,0x18,0xE9,0x40,0x01,0xFF,0x4C,0x06,0xE9,
16900x3A,0x01,0x8B,0x5C,0x02,0x8A,0x47,0x01,0x8B,0x1C,0x8A,0x57,0x01,0xB6,0x00,0x8B,
16910xDA,0x88,0x40,0x18,0xE9,0x25,0x01,0x8B,0x5C,0x02,0x8A,0x47,0x01,0x8B,0x1C,0x8A,
16920x57,0x01,0xB6,0x00,0x8B,0xDA,0x88,0x40,0x18,0xFF,0x4C,0x06,0xE9,0x0D,0x01,0x8B,
16930x5C,0x02,0x8A,0x47,0x01,0x8B,0x1C,0x8A,0x57,0x01,0xB6,0x00,0x8B,0xDA,0x30,0x40,
16940x18,0xE9,0xF8,0x00,0xB8,0xF0,0x10,0x8B,0xF8,0x89,0x44,0x54,0x8A,0x44,0x5F,0x88,
16950x44,0x5D,0xE9,0xE7,0x00,0x8A,0x44,0x1C,0x98,0x3D,0x02,0x00,0x74,0x07,0x3D,0x03,
16960x00,0x74,0x02,0xEB,0x07,0xC7,0x46,0xFE,0x00,0x00,0xEB,0x2B,0x8A,0x44,0x1C,0x98,
16970xD1,0xE0,0x8B,0xD8,0xFF,0xB7,0x69,0x02,0x56,0xE8,0x6B,0x06,0x59,0x59,0x6A,0x01,
16980x56,0xE8,0x40,0xF9,0x59,0x59,0x89,0x46,0xFE,0x83,0x7E,0xFE,0x00,0x74,0x06,0x83,
16990x7E,0xFE,0x03,0x75,0xE9,0xEB,0x00,0x83,0x7E,0xFE,0x03,0x74,0x62,0x8A,0x44,0x1C,
17000x98,0xD1,0xE0,0x8B,0xD8,0xFF,0xB7,0x6D,0x02,0x56,0xE8,0x3A,0x06,0x59,0x59,0x56,
17010xE8,0x4D,0x97,0x59,0x89,0x46,0xFC,0x8B,0x5E,0xFC,0x83,0xEB,0xFE,0x83,0xFB,0x03,
17020x77,0x33,0xD1,0xE3,0x2E,0xFF,0xA7,0x99,0x6A,0x68,0xAC,0x02,0x56,0xE8,0x17,0x06,
17030x59,0x59,0xEB,0x23,0x68,0x8F,0x02,0x56,0xE8,0x0C,0x06,0x59,0x59,0xEB,0x18,0x68,
17040x75,0x02,0x56,0xE8,0x01,0x06,0x59,0x59,0xEB,0x0D,0x68,0xC6,0x02,0x56,0xE8,0xF6,
17050x05,0x59,0x59,0xEB,0x02,0xEB,0x00,0x6A,0x01,0x56,0xE8,0xC7,0xF8,0x59,0x59,0xBF,
17060x01,0x00,0xEB,0x38,0x68,0xDD,0x02,0x56,0xE8,0xDC,0x05,0x59,0x59,0x6A,0x01,0x56,
17070xE8,0xB1,0xF8,0x59,0x59,0xBF,0x01,0x00,0xEB,0x22,0xB8,0xD0,0x30,0x8B,0xF8,0x89,
17080x44,0x54,0x8A,0x44,0x60,0x88,0x44,0x5D,0xEB,0x12,0xB8,0xE0,0x20,0x8B,0xF8,0x89,
17090x44,0x54,0x8A,0x44,0x5E,0x88,0x44,0x5D,0xEB,0x02,0xEB,0x00,0xEB,0x02,0xEB,0x00,
17100xEB,0x00,0xE9,0x41,0xFC,0x5F,0x5E,0xC9,0xC3,0x19,0x6A,0x24,0x6A,0x2F,0x6A,0x3A,
17110x6A,0x00,0x00,0x01,0x00,0x02,0x00,0x04,0x00,0x41,0x00,0x42,0x00,0x43,0x00,0x44,
17120x00,0x80,0x00,0x81,0x00,0x82,0x00,0xFF,0x00,0x17,0x69,0x54,0x6A,0x7A,0x6A,0xA5,
17130x69,0x52,0x69,0x94,0x69,0x6A,0x6A,0x67,0x69,0x52,0x69,0x7F,0x69,0x67,0x69,0x4C,
17140x69,0xF4,0x68,0x76,0x68,0xB2,0x68,0xEE,0x68,0xF5,0x67,0x00,0x68,0x12,0x68,0xF5,
17150x67,0x9D,0x67,0xA8,0x67,0xB4,0x67,0x9D,0x67,0x00,0x00,0x01,0x00,0xF0,0x10,0xE0,
17160x20,0xD0,0x30,0x27,0x68,0xF2,0x66,0xC3,0x67,0x23,0x67,0x12,0x67,0xC8,0x04,0x00,
17170x00,0x56,0x57,0x8B,0x76,0x04,0x8A,0x44,0x59,0x98,0x89,0x46,0xFC,0x6A,0x09,0x8B,
17180x46,0xFC,0x05,0x84,0x01,0x50,0xE8,0x93,0x08,0x59,0x59,0x8B,0xF8,0x8B,0xC7,0x25,
17190x00,0xF0,0x3D,0x00,0x10,0x75,0x55,0x8B,0xC7,0x25,0xF0,0x00,0x3D,0xF0,0x00,0x75,
17200x4B,0x8B,0xC7,0x25,0x00,0x0F,0xC1,0xF8,0x08,0x89,0x46,0xFE,0x8B,0x44,0x04,0x3B,
17210x46,0xFE,0x7D,0x05,0x33,0xC0,0xE9,0xEF,0x00,0x8B,0xC7,0x25,0x0F,0x00,0xBA,0x0F,
17220x00,0x2B,0xD0,0x3B,0x56,0xFE,0x74,0x05,0x33,0xC0,0xE9,0xDB,0x00,0xC7,0x44,0x02,
17230x04,0x09,0x8A,0x46,0xFE,0x88,0x44,0x5F,0x88,0x44,0x5D,0x8B,0x5E,0xFC,0xD1,0xE3,
17240xC7,0x87,0xFC,0x08,0x04,0x09,0xB8,0xF0,0x10,0xE9,0xBC,0x00,0x8B,0xC7,0x25,0x00,
17250xF0,0x3D,0x00,0x20,0x75,0x52,0x8B,0xC7,0x25,0xF0,0x00,0x3D,0xE0,0x00,0x75,0x48,
17260x8B,0xC7,0x25,0x00,0x0F,0xC1,0xF8,0x08,0x89,0x46,0xFE,0x83,0x7E,0xFE,0x08,0x7E,
17270x05,0x33,0xC0,0xE9,0x92,0x00,0x8B,0xC7,0x25,0x0F,0x00,0xBA,0x0F,0x00,0x2B,0xD0,
17280x3B,0x56,0xFE,0x74,0x05,0x33,0xC0,0xEB,0x7F,0x90,0xC7,0x44,0x02,0x0C,0x09,0x8A,
17290x46,0xFE,0x88,0x44,0x5E,0x88,0x44,0x5D,0x8B,0x5E,0xFC,0xD1,0xE3,0xC7,0x87,0xFC,
17300x08,0x0C,0x09,0xB8,0xE0,0x20,0xEB,0x60,0x8B,0xC7,0x25,0x00,0xF0,0x3D,0x00,0x30,
17310x75,0x52,0x8B,0xC7,0x25,0xF0,0x00,0x3D,0xD0,0x00,0x75,0x48,0x8B,0xC7,0x25,0x00,
17320x0F,0xC1,0xF8,0x08,0x89,0x46,0xFE,0x8B,0x44,0x04,0x3B,0x46,0xFE,0x7D,0x04,0x33,
17330xC0,0xEB,0x35,0x8B,0xC7,0x25,0x0F,0x00,0xBA,0x0F,0x00,0x2B,0xD0,0x3B,0x56,0xFE,
17340x74,0x04,0x33,0xC0,0xEB,0x22,0xC7,0x44,0x02,0x14,0x09,0x8A,0x46,0xFE,0x88,0x44,
17350x60,0x88,0x44,0x5D,0x8B,0x5E,0xFC,0xD1,0xE3,0xC7,0x87,0xFC,0x08,0x14,0x09,0xB8,
17360xD0,0x30,0xEB,0x04,0x33,0xC0,0xEB,0x00,0x5F,0x5E,0xC9,0xC3,0xC8,0x06,0x00,0x00,
17370x56,0x8B,0x76,0x04,0x6A,0x08,0x56,0xE8,0x35,0x04,0x59,0x59,0x8A,0x44,0x58,0x04,
17380x80,0x50,0x56,0xE8,0x29,0x04,0x59,0x59,0x8B,0x44,0x54,0x3B,0x44,0x56,0x75,0x0A,
17390x8A,0x44,0x5D,0x3A,0x44,0x2F,0x75,0x02,0xEB,0x64,0x8B,0x44,0x54,0x89,0x44,0x56,
17400x8B,0x5C,0x02,0x8A,0x47,0x01,0x88,0x44,0x2F,0x8A,0x44,0x5D,0xB4,0x00,0xC1,0xE0,
17410x08,0x8B,0x54,0x54,0x0B,0xD0,0x8A,0x44,0x5D,0xB4,0x00,0xBB,0x0F,0x00,0x2B,0xD8,
17420x0B,0xD3,0x89,0x56,0xFE,0x6A,0x10,0x8A,0x44,0x59,0x98,0x05,0x04,0x00,0x99,0x05,
17430x40,0x01,0x83,0xD2,0x00,0x52,0x50,0xE8,0x54,0x08,0x83,0xC4,0x06,0x89,0x56,0xFC,
17440x89,0x46,0xFA,0x8B,0x46,0xFE,0x09,0x46,0xFA,0x83,0x4E,0xFC,0x00,0x6A,0x19,0xFF,
17450x76,0xFC,0xFF,0x76,0xFA,0xE8,0x73,0x07,0x83,0xC4,0x06,0xE8,0xFE,0x07,0x5E,0xC9,
17460xC3,0xC8,0x1C,0x00,0x00,0x56,0x57,0x8B,0x5E,0x04,0x8A,0x47,0x59,0x98,0x8B,0xF0,
17470x8B,0x5E,0x04,0x8A,0x47,0x5D,0xB4,0x00,0x89,0x46,0xE6,0x83,0x7E,0xE6,0x00,0x7D,
17480x0A,0x8B,0x5E,0x04,0x8B,0x47,0x04,0x48,0x89,0x46,0xE6,0x8B,0x5E,0x04,0x8B,0x47,
17490x04,0x3B,0x46,0xE6,0x7F,0x05,0xC7,0x46,0xE6,0x00,0x00,0x8B,0x5E,0x04,0x8A,0x46,
17500xE6,0x88,0x47,0x5D,0x8B,0xDE,0xD1,0xE3,0x8B,0x9F,0x59,0x02,0xC6,0x47,0x02,0x20,
17510x8B,0xDE,0xD1,0xE3,0x8B,0x9F,0x59,0x02,0xC6,0x47,0x03,0x30,0x8B,0xDE,0xD1,0xE3,
17520x8B,0x9F,0x61,0x02,0xC6,0x47,0x02,0x20,0x8B,0xDE,0xD1,0xE3,0x8B,0x9F,0x61,0x02,
17530xC6,0x47,0x03,0x30,0x8B,0x46,0xE6,0x89,0x46,0xFA,0x83,0x7E,0xFA,0x00,0x74,0x18,
17540x8B,0x46,0xFA,0xBB,0x0A,0x00,0x33,0xD2,0xF7,0xF3,0x80,0xC2,0x30,0x8B,0xDE,0xD1,
17550xE3,0x8B,0x9F,0x59,0x02,0x88,0x57,0x03,0xBB,0x0A,0x00,0x8B,0x46,0xFA,0x33,0xD2,
17560xF7,0xF3,0x89,0x46,0xFA,0x83,0x7E,0xFA,0x00,0x74,0x18,0x8B,0x46,0xFA,0xBB,0x0A,
17570x00,0x33,0xD2,0xF7,0xF3,0x80,0xC2,0x30,0x8B,0xDE,0xD1,0xE3,0x8B,0x9F,0x59,0x02,
17580x88,0x57,0x02,0x8B,0x46,0xE6,0x89,0x46,0xFA,0x83,0x7E,0xFA,0x00,0x74,0x18,0x8B,
17590x46,0xFA,0xBB,0x0A,0x00,0x33,0xD2,0xF7,0xF3,0x80,0xC2,0x30,0x8B,0xDE,0xD1,0xE3,
17600x8B,0x9F,0x61,0x02,0x88,0x57,0x03,0xBB,0x0A,0x00,0x8B,0x46,0xFA,0x33,0xD2,0xF7,
17610xF3,0x89,0x46,0xFA,0x83,0x7E,0xFA,0x00,0x74,0x18,0x8B,0x46,0xFA,0xBB,0x0A,0x00,
17620x33,0xD2,0xF7,0xF3,0x80,0xC2,0x30,0x8B,0xDE,0xD1,0xE3,0x8B,0x9F,0x61,0x02,0x88,
17630x57,0x02,0x8B,0x5E,0xE6,0xD1,0xE3,0xFF,0xB7,0x12,0x02,0x6A,0x00,0xFF,0x76,0x04,
17640xE8,0xD1,0xF6,0x83,0xC4,0x06,0x68,0xD3,0x0F,0x6A,0x01,0xFF,0x76,0x04,0xE8,0xC3,
17650xF6,0x83,0xC4,0x06,0xFF,0x76,0xE6,0x56,0xE8,0x01,0x93,0x59,0x59,0x89,0x56,0xF2,
17660x89,0x46,0xF0,0xFF,0x76,0xE6,0x56,0xE8,0x14,0x93,0x59,0x59,0x89,0x56,0xEE,0x89,
17670x46,0xEC,0x9C,0xFA,0xC4,0x5E,0xF0,0x26,0x8B,0x07,0x89,0x46,0xEA,0xC4,0x5E,0xEC,
17680x26,0x8B,0x07,0x89,0x46,0xE8,0xBA,0x50,0xFF,0xED,0x89,0x46,0xFE,0x9D,0xC7,0x46,
17690xE4,0x01,0x00,0xE8,0xEE,0xA0,0xBA,0x50,0xFF,0xED,0x89,0x46,0xFC,0x8B,0x46,0xFC,
17700x2B,0x46,0xFE,0x3D,0xE8,0x03,0x73,0x03,0xE9,0x80,0x01,0x9C,0xFA,0xBA,0x50,0xFF,
17710xED,0x89,0x46,0xFC,0x8B,0x46,0xFC,0x2B,0x46,0xFE,0x89,0x46,0xF8,0xC4,0x5E,0xF0,
17720x26,0x8B,0x07,0x2B,0x46,0xEA,0x89,0x46,0xF6,0xC4,0x5E,0xF0,0x26,0x8B,0x07,0x89,
17730x46,0xEA,0xC4,0x5E,0xEC,0x26,0x8B,0x07,0x2B,0x46,0xE8,0x89,0x46,0xF4,0xC4,0x5E,
17740xEC,0x26,0x8B,0x07,0x89,0x46,0xE8,0xBA,0x50,0xFF,0xED,0x89,0x46,0xFE,0x9D,0x81,
17750x7E,0xF8,0xE8,0x03,0x76,0x1C,0xFF,0x76,0xF8,0xFF,0x76,0xF6,0xE8,0x76,0x01,0x59,
17760x59,0x89,0x46,0xF6,0xFF,0x76,0xF8,0xFF,0x76,0xF4,0xE8,0x68,0x01,0x59,0x59,0x89,
17770x46,0xF4,0xBF,0x0E,0x00,0xEB,0x17,0x8B,0xDE,0xD1,0xE3,0x8B,0x9F,0x59,0x02,0xC6,
17780x01,0x20,0x8B,0xDE,0xD1,0xE3,0x8B,0x9F,0x61,0x02,0xC6,0x01,0x20,0x47,0x83,0xFF,
17790x11,0x76,0xE4,0x8B,0xDE,0xD1,0xE3,0x8B,0x9F,0x59,0x02,0xC6,0x47,0x0D,0x30,0x8B,
17800xDE,0xD1,0xE3,0x8B,0x9F,0x61,0x02,0xC6,0x47,0x0D,0x30,0x83,0x7E,0xF6,0x09,0x77,
17810x05,0xB8,0x0D,0x00,0xEB,0x26,0x83,0x7E,0xF6,0x63,0x77,0x05,0xB8,0x0E,0x00,0xEB,
17820x1B,0x81,0x7E,0xF6,0xE7,0x03,0x77,0x05,0xB8,0x0F,0x00,0xEB,0x0F,0x81,0x7E,0xF6,
17830x0F,0x27,0x77,0x05,0xB8,0x10,0x00,0xEB,0x03,0xB8,0x11,0x00,0x8B,0xF8,0xEB,0x25,
17840x8B,0x46,0xF6,0xBB,0x0A,0x00,0x33,0xD2,0xF7,0xF3,0x80,0xC2,0x30,0x8B,0xDE,0xD1,
17850xE3,0x8B,0x9F,0x59,0x02,0x88,0x11,0x4F,0xBB,0x0A,0x00,0x8B,0x46,0xF6,0x33,0xD2,
17860xF7,0xF3,0x89,0x46,0xF6,0x83,0x7E,0xF6,0x00,0x75,0xD5,0x83,0x7E,0xF4,0x09,0x77,
17870x05,0xB8,0x0D,0x00,0xEB,0x26,0x83,0x7E,0xF4,0x63,0x77,0x05,0xB8,0x0E,0x00,0xEB,
17880x1B,0x81,0x7E,0xF4,0xE7,0x03,0x77,0x05,0xB8,0x0F,0x00,0xEB,0x0F,0x81,0x7E,0xF4,
17890x0F,0x27,0x77,0x05,0xB8,0x10,0x00,0xEB,0x03,0xB8,0x11,0x00,0x8B,0xF8,0xEB,0x25,
17900x8B,0x46,0xF4,0xBB,0x0A,0x00,0x33,0xD2,0xF7,0xF3,0x80,0xC2,0x30,0x8B,0xDE,0xD1,
17910xE3,0x8B,0x9F,0x61,0x02,0x88,0x11,0x4F,0xBB,0x0A,0x00,0x8B,0x46,0xF4,0x33,0xD2,
17920xF7,0xF3,0x89,0x46,0xF4,0x83,0x7E,0xF4,0x00,0x75,0xD5,0x8B,0xDE,0xD1,0xE3,0xFF,
17930xB7,0x59,0x02,0xFF,0x76,0x04,0xE8,0x6E,0x00,0x59,0x59,0x8B,0xDE,0xD1,0xE3,0xFF,
17940xB7,0x61,0x02,0xFF,0x76,0x04,0xE8,0x5E,0x00,0x59,0x59,0x6A,0x00,0xFF,0x76,0x04,
17950xE8,0x31,0xF3,0x59,0x59,0x8B,0xD8,0x83,0xFB,0x04,0x77,0x1F,0xD1,0xE3,0x2E,0xFF,
17960xA7,0x1B,0x70,0xEB,0x22,0xC7,0x46,0xE4,0x00,0x00,0xFF,0x4E,0xE6,0xEB,0x0C,0xC7,
17970x46,0xE4,0x00,0x00,0xFF,0x46,0xE6,0xEB,0x02,0xEB,0x00,0x83,0x7E,0xE4,0x00,0x74,
17980x03,0xE9,0x2A,0xFE,0xE9,0xD4,0xFC,0x5F,0x5E,0xC9,0xC3,0xF3,0x6F,0xF5,0x6F,0xFF,
17990x6F,0xF3,0x6F,0x09,0x70,0x55,0x8B,0xEC,0x8B,0x46,0x04,0xB9,0xE8,0x03,0xF7,0xE1,
18000x8B,0x4E,0x06,0xF7,0xF1,0x5D,0xC3,0x55,0x8B,0xEC,0x56,0x8B,0x76,0x06,0xEB,0x0E,
18010x8B,0xDE,0x46,0x8A,0x07,0x50,0xFF,0x76,0x04,0xE8,0x33,0x00,0x59,0x59,0x80,0x3C,
18020x00,0x75,0xED,0xEB,0x00,0x5E,0x5D,0xC3,0x55,0x8B,0xEC,0x56,0x8B,0x76,0x06,0xEB,
18030x14,0x8B,0xDE,0x46,0x8A,0x07,0x50,0xFF,0x76,0x04,0xE8,0x45,0x00,0x59,0x59,0x0B,
18040xC0,0x74,0x02,0xEB,0x07,0x80,0x3C,0x00,0x75,0xE7,0xEB,0x00,0x5E,0x5D,0xC3,0xC8,
18050x02,0x00,0x00,0x56,0x8B,0x76,0x04,0x8A,0x44,0x5A,0x98,0x89,0x46,0xFE,0x9C,0xFA,
18060x8A,0x46,0xFE,0xBA,0xFE,0x00,0xEE,0xBA,0x02,0x00,0xEC,0xA8,0x02,0x74,0x06,0x9D,
18070xE8,0x91,0x9E,0xEB,0xE9,0xBA,0x00,0x00,0x8A,0x46,0x06,0xEE,0x9D,0xEB,0x00,0x5E,
18080xC9,0xC3,0xC8,0x04,0x00,0x00,0x56,0x8B,0x76,0x04,0x8A,0x44,0x5A,0x98,0x89,0x46,
18090xFE,0xE8,0xE6,0xA1,0x89,0x46,0xFC,0xE8,0xE0,0xA1,0x2B,0x46,0xFC,0x3D,0xB8,0x0B,
18100x76,0x05,0xB8,0x01,0x00,0xEB,0x23,0x9C,0xFA,0x8A,0x46,0xFE,0xBA,0xFE,0x00,0xEE,
18110xBA,0x02,0x00,0xEC,0xA8,0x02,0x74,0x06,0x9D,0xE8,0x48,0x9E,0xEB,0xD9,0xBA,0x00,
18120x00,0x8A,0x46,0x06,0xEE,0x9D,0x33,0xC0,0xEB,0x00,0x5E,0xC9,0xC3,0xC8,0x04,0x00,
18130x00,0x56,0x57,0x8B,0x76,0x04,0x83,0x7E,0x06,0x00,0x74,0x07,0x56,0xE8,0x03,0x01,
18140x59,0xEB,0x05,0x56,0xE8,0xA2,0x00,0x59,0x88,0x46,0xFF,0x80,0x7E,0xFF,0x08,0x77,
18150x06,0x8A,0x46,0xFF,0xE9,0x84,0x00,0x80,0x7E,0xFF,0x0F,0x76,0x03,0xEB,0x79,0x90,
18160x8A,0x46,0xFF,0xB4,0x00,0x2D,0x0A,0x00,0x8B,0xD8,0x83,0xFB,0x04,0x77,0x67,0xD1,
18170xE3,0x2E,0xFF,0xA7,0xAF,0x71,0xB0,0x00,0xEB,0x61,0x56,0xE8,0x6B,0x00,0x59,0xB4,
18180x00,0x25,0x0F,0x00,0x89,0x46,0xFC,0x56,0xE8,0x5E,0x00,0x59,0xB4,0x00,0x8B,0xF8,
18190x56,0xE8,0x55,0x00,0x59,0xB4,0x00,0xC1,0xE0,0x08,0x8B,0xD7,0x03,0xD0,0x8B,0xFA,
18200x8B,0x5E,0xFC,0xD1,0xE3,0x89,0x78,0x30,0xEB,0x2E,0x56,0xE8,0x3B,0x00,0x59,0x88,
18210x44,0x5B,0xEB,0x24,0x56,0xE8,0x31,0x00,0x59,0x88,0x44,0x50,0x56,0xE8,0x29,0x00,
18220x59,0x88,0x44,0x51,0x56,0xE8,0x21,0x00,0x59,0x88,0x44,0x52,0x56,0xE8,0x19,0x00,
18230x59,0x88,0x44,0x53,0xEB,0x02,0xEB,0x00,0xE9,0x5B,0xFF,0x5F,0x5E,0xC9,0xC3,0x46,
18240x71,0xA6,0x71,0x4A,0x71,0x7A,0x71,0x84,0x71,0xC8,0x04,0x00,0x00,0x56,0x8B,0x76,
18250x04,0x8A,0x44,0x5A,0x98,0x89,0x46,0xFE,0x9C,0xFA,0x8A,0x46,0xFE,0xBA,0xFE,0x00,
18260xEE,0xBA,0x02,0x00,0xEC,0xA8,0x01,0x75,0x06,0x9D,0xE8,0x57,0x9D,0xEB,0xE9,0xBA,
18270x00,0x00,0xEC,0x88,0x46,0xFD,0x9D,0x8A,0x46,0xFD,0xEB,0x00,0x5E,0xC9,0xC3,0xC8,
18280x02,0x00,0x00,0x56,0x8B,0x76,0x04,0x8A,0x44,0x5A,0x98,0x89,0x46,0xFE,0x9C,0xFA,
18290x8A,0x46,0xFE,0xBA,0xFE,0x00,0xEE,0xBA,0x02,0x00,0xEC,0x32,0xE4,0x24,0x01,0x9D,
18300x5E,0xC9,0xC3,0xC8,0x06,0x00,0x00,0x56,0x8B,0x76,0x04,0x8A,0x44,0x5A,0x98,0x89,
18310x46,0xFE,0xE8,0x85,0xA0,0x89,0x46,0xFA,0xE8,0x7F,0xA0,0x2B,0x46,0xFA,0x3D,0xB8,
18320x0B,0x76,0x04,0xB0,0x08,0xEB,0x24,0x9C,0xFA,0x8A,0x46,0xFE,0xBA,0xFE,0x00,0xEE,
18330xBA,0x02,0x00,0xEC,0xA8,0x01,0x75,0x06,0x9D,0xE8,0xE8,0x9C,0xEB,0xDA,0xBA,0x00,
18340x00,0xEC,0x88,0x46,0xFD,0x9D,0x8A,0x46,0xFD,0xEB,0x00,0x5E,0xC9,0xC3,0x55,0x8B,
18350xEC,0x56,0x8B,0x56,0x04,0x8A,0x46,0x06,0xEE,0x33,0xF6,0xEB,0x03,0x50,0x58,0x46,
18360x83,0xFE,0x14,0x7C,0xF8,0x5E,0x5D,0xC3,0xC8,0x02,0x00,0x00,0x56,0x8B,0x56,0x04,
18370xEC,0x88,0x46,0xFF,0x33,0xF6,0xEB,0x03,0x50,0x58,0x46,0x83,0xFE,0x14,0x7C,0xF8,
18380x8A,0x46,0xFF,0xEB,0x00,0x5E,0xC9,0xC3,0xC8,0x02,0x00,0x00,0x56,0x57,0x8B,0x76,
18390x04,0x83,0x3E,0xB0,0x0B,0x00,0x75,0x1F,0xBA,0x88,0x01,0xB0,0x00,0xEE,0xBA,0x86,
18400x01,0xB0,0x00,0xEE,0x6A,0x09,0x6A,0x00,0x68,0x30,0x01,0xE8,0x7D,0x01,0x83,0xC4,
18410x06,0xC7,0x06,0xB0,0x0B,0x01,0x00,0x6A,0x09,0x8B,0xC6,0x05,0x80,0x01,0x50,0xE8,
18420xDA,0x00,0x59,0x59,0x8B,0xF8,0x8B,0xC7,0xC1,0xE8,0x0C,0x25,0x0F,0x00,0x89,0x46,
18430xFE,0x8B,0xC7,0xC1,0xE8,0x08,0x25,0x0F,0x00,0x8B,0x56,0xFE,0x83,0xF2,0x0C,0x3B,
18440xC2,0x75,0x21,0x8B,0xC7,0xC1,0xE8,0x04,0x25,0x0F,0x00,0x8B,0x56,0xFE,0x83,0xF2,
18450x06,0x3B,0xC2,0x75,0x0F,0x8B,0xC7,0x25,0x0F,0x00,0x8B,0x56,0xFE,0x83,0xF2,0x09,
18460x3B,0xC2,0x74,0x0D,0x6A,0x07,0x56,0xE8,0x38,0x00,0x59,0x59,0xC7,0x46,0xFE,0x07,
18470x00,0x8A,0x46,0xFE,0x04,0x80,0xA2,0x33,0x02,0x8B,0xC6,0xBA,0x62,0x00,0xF7,0xEA,
18480x8A,0x56,0xFE,0x8B,0xD8,0x88,0x97,0x6C,0x00,0x68,0x32,0x02,0x8B,0xC6,0xBA,0x62,
18490x00,0xF7,0xEA,0x05,0x14,0x00,0x50,0xE8,0x0E,0xFD,0x59,0x59,0xEB,0x00,0x5F,0x5E,
18500xC9,0xC3,0xC8,0x02,0x00,0x00,0x56,0x8B,0x76,0x06,0x83,0xE6,0x0F,0x8B,0xC6,0xC1,
18510xE0,0x0C,0x8B,0xD6,0x83,0xF2,0x0C,0xC1,0xE2,0x08,0x0B,0xC2,0x8B,0xD6,0x83,0xF2,
18520x06,0xC1,0xE2,0x04,0x0B,0xC2,0x8B,0xD6,0x83,0xF2,0x09,0x0B,0xC2,0x89,0x46,0xFE,
18530x6A,0x19,0x6A,0x10,0x8B,0x46,0x04,0x99,0x05,0x40,0x01,0x83,0xD2,0x00,0x52,0x50,
18540xE8,0x6B,0x01,0x83,0xC4,0x06,0x0B,0x46,0xFE,0x83,0xCA,0x00,0x52,0x50,0xE8,0x9A,
18550x00,0x83,0xC4,0x06,0xE8,0x25,0x01,0xEB,0x00,0x5E,0xC9,0xC3,0x55,0x8B,0xEC,0x56,
18560x57,0x33,0xFF,0x6A,0x01,0x68,0x86,0x01,0xE8,0xA3,0xFE,0x59,0x59,0xB1,0x10,0x2A,
18570x4E,0x06,0xD3,0x66,0x04,0x33,0xF6,0xEB,0x2E,0x81,0x7E,0x04,0x00,0x80,0x72,0x04,
18580xB0,0x01,0xEB,0x02,0xB0,0x00,0x50,0x68,0x88,0x01,0xE8,0x81,0xFE,0x59,0x59,0x6A,
18590x03,0x68,0x86,0x01,0xE8,0x77,0xFE,0x59,0x59,0x6A,0x01,0x68,0x86,0x01,0xE8,0x6D,
18600xFE,0x59,0x59,0xD1,0x66,0x04,0x46,0x3B,0x76,0x06,0x7C,0xCD,0x33,0xF6,0xEB,0x24,
18610xD1,0xE7,0x6A,0x03,0x68,0x86,0x01,0xE8,0x54,0xFE,0x59,0x59,0x6A,0x01,0x68,0x86,
18620x01,0xE8,0x4A,0xFE,0x59,0x59,0x68,0x88,0x01,0xE8,0x5C,0xFE,0x59,0x98,0x25,0x01,
18630x00,0x0B,0xF8,0x46,0x83,0xFE,0x10,0x7C,0xD7,0x6A,0x00,0x68,0x86,0x01,0xE8,0x2D,
18640xFE,0x59,0x59,0x8B,0xC7,0xEB,0x00,0x5F,0x5E,0x5D,0xC3,0x55,0x8B,0xEC,0x56,0x57,
18650x8B,0x7E,0x08,0x6A,0x01,0x68,0x86,0x01,0xE8,0x13,0xFE,0x59,0x59,0xB8,0x20,0x00,
18660x2B,0xC7,0x50,0xFF,0x76,0x06,0xFF,0x76,0x04,0xE8,0xA2,0x00,0x83,0xC4,0x06,0x89,
18670x56,0x06,0x89,0x46,0x04,0x33,0xF6,0xEB,0x47,0x81,0x7E,0x06,0x00,0x80,0x72,0x0C,
18680x75,0x06,0x83,0x7E,0x04,0x00,0x72,0x04,0xB0,0x01,0xEB,0x02,0xB0,0x00,0x50,0x68,
18690x88,0x01,0xE8,0xD9,0xFD,0x59,0x59,0x6A,0x03,0x68,0x86,0x01,0xE8,0xCF,0xFD,0x59,
18700x59,0x6A,0x01,0x68,0x86,0x01,0xE8,0xC5,0xFD,0x59,0x59,0x6A,0x01,0xFF,0x76,0x06,
18710xFF,0x76,0x04,0xE8,0x58,0x00,0x83,0xC4,0x06,0x89,0x56,0x06,0x89,0x46,0x04,0x46,
18720x3B,0xF7,0x7C,0xB5,0x6A,0x00,0x68,0x86,0x01,0xE8,0xA2,0xFD,0x59,0x59,0x6A,0x00,
18730x68,0x86,0x01,0xE8,0x98,0xFD,0x59,0x59,0x5F,0x5E,0x5D,0xC3,0x55,0x8B,0xEC,0x56,
18740x6A,0x01,0x68,0x86,0x01,0xE8,0x86,0xFD,0x59,0x59,0x33,0xF6,0xEB,0x00,0x68,0x88,
18750x01,0xE8,0x94,0xFD,0x59,0xA8,0x01,0x75,0x08,0x8B,0xC6,0x46,0x3D,0x64,0x00,0x7C,
18760xED,0x6A,0x00,0x68,0x86,0x01,0xE8,0x65,0xFD,0x59,0x59,0x5E,0x5D,0xC3,0xC8,0x04,
18770x00,0x00,0x8B,0x46,0x04,0x8B,0x56,0x06,0x8B,0x4E,0x08,0xE3,0x06,0xD1,0xE0,0xD1,
18780xD2,0xE2,0xFA,0x89,0x46,0xFC,0x89,0x56,0xFE,0x8B,0x56,0xFE,0x8B,0x46,0xFC,0xEB,
18790x00,0xC9,0xC3,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18800x50,0x72,0x65,0x76,0x69,0x6F,0x75,0x73,0x20,0x4D,0x65,0x6E,0x75,0x00,0x42,0x65,
18810x67,0x69,0x6E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18820x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18830x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18840x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18850x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18860x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18870x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18880x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18890x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18900x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18910x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18920x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18930x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18940x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18950x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18960x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18970x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18980x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
18990x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
19000x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
19010x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
19020x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
19030x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
19040x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
19050x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x50,0x6F,0x72,0x74,
19060x20,0x30,0x00,0x50,0x6F,0x72,0x74,0x20,0x31,0x00,0x50,0x6F,0x72,0x74,0x20,0x32,
19070x00,0x50,0x6F,0x72,0x74,0x20,0x33,0x00,0x50,0x6F,0x72,0x74,0x20,0x34,0x00,0x50,
19080x6F,0x72,0x74,0x20,0x35,0x00,0x50,0x6F,0x72,0x74,0x20,0x36,0x00,0x50,0x6F,0x72,
19090x74,0x20,0x37,0x00,0x50,0x6F,0x72,0x74,0x20,0x38,0x00,0x50,0x6F,0x72,0x74,0x20,
19100x39,0x00,0x50,0x6F,0x72,0x74,0x20,0x31,0x30,0x00,0x50,0x6F,0x72,0x74,0x20,0x31,
19110x31,0x00,0x50,0x6F,0x72,0x74,0x20,0x31,0x32,0x00,0x50,0x6F,0x72,0x74,0x20,0x31,
19120x33,0x00,0x50,0x6F,0x72,0x74,0x20,0x31,0x34,0x00,0x50,0x6F,0x72,0x74,0x20,0x31,
19130x35,0x00,0x9C,0x01,0xA3,0x01,0xAA,0x01,0xB1,0x01,0xB8,0x01,0xBF,0x01,0xC6,0x01,
19140xCD,0x01,0xD4,0x01,0xDB,0x01,0xE2,0x01,0xEA,0x01,0xF2,0x01,0xFA,0x01,0x02,0x02,
19150x0A,0x02,0x08,0x00,0x00,0x07,0x81,0x00,0x03,0x80,0x80,0x80,0x9F,0x91,0x95,0x91,
19160x9F,0x00,0x03,0x81,0x84,0x8E,0x95,0x84,0x84,0x84,0x84,0x00,0x03,0x82,0x84,0x84,
19170x84,0x84,0x95,0x8E,0x84,0x00,0x04,0x88,0x00,0xB2,0x0B,0xC6,0x0B,0xDA,0x0B,0xEE,
19180x0B,0x02,0x0C,0x16,0x0C,0x2A,0x0C,0x3E,0x0C,0x52,0x0C,0x77,0x0C,0x9C,0x0C,0xBE,
19190x0C,0xE0,0x0C,0x02,0x0D,0x01,0x80,0x20,0x54,0x65,0x73,0x74,0x20,0x50,0x61,0x73,
19200x73,0x65,0x64,0x20,0x1F,0x20,0x50,0x72,0x65,0x73,0x73,0x20,0x80,0x02,0x00,0x01,
19210x80,0x20,0x4D,0x69,0x73,0x73,0x69,0x6E,0x67,0x20,0x52,0x78,0x20,0x44,0x61,0x74,
19220x61,0x1F,0x20,0x50,0x72,0x65,0x73,0x73,0x20,0x80,0x02,0x00,0x01,0x80,0x20,0x42,
19230x61,0x64,0x20,0x52,0x78,0x20,0x44,0x61,0x74,0x61,0x20,0x1F,0x20,0x50,0x72,0x65,
19240x73,0x73,0x20,0x80,0x02,0x00,0x01,0x80,0x20,0x58,0x6D,0x74,0x72,0x20,0x42,0x75,
19250x73,0x79,0x1F,0x20,0x50,0x72,0x65,0x73,0x73,0x20,0x80,0x02,0x00,0x01,0x80,0x20,
19260x6E,0x6F,0x74,0x20,0x63,0x75,0x72,0x72,0x65,0x6E,0x74,0x6C,0x79,0x1F,0x20,0x20,
19270x69,0x6D,0x70,0x6C,0x65,0x6D,0x65,0x6E,0x74,0x65,0x64,0x02,0x00,0x24,0x0D,0x2F,
19280x0D,0x3A,0x0D,0x45,0x0D,0x50,0x0D,0x5B,0x0D,0x66,0x0D,0x71,0x0D,0x7C,0x0D,0x87,
19290x0D,0x92,0x0D,0x9D,0x0D,0xA8,0x0D,0xB3,0x0D,0xBE,0x0D,0xC9,0x0D,0x53,0x80,0x2C,
19300x32,0x54,0x44,0x20,0x53,0x86,0x2C,0x33,0x44,0x54,0x52,0x20,0x53,0x82,0x2C,0x33,
19310x52,0x54,0x53,0x20,0x1F,0x53,0x81,0x2C,0x32,0x52,0x44,0x20,0x53,0x85,0x2C,0x32,
19320x43,0x44,0x20,0x53,0x83,0x2C,0x33,0x43,0x54,0x53,0x20,0x53,0x84,0x2C,0x33,0x44,
19330x53,0x52,0x20,0x53,0x87,0x2C,0x32,0x52,0x49,0x27,0x02,0x00,0x01,0x80,0x20,0x20,
19340x44,0x43,0x44,0x20,0x2D,0x20,0x70,0x69,0x6E,0x20,0x32,0x30,0x1F,0x27,0x53,0x85,
19350x2E,0x31,0x81,0x82,0x63,0x90,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,
19360x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x27,0x02,0x00,0x01,0x80,0x20,0x20,0x44,0x53,0x52,
19370x20,0x2D,0x20,0x70,0x69,0x6E,0x20,0x31,0x31,0x1F,0x27,0x53,0x84,0x2E,0x31,0x81,
19380x82,0x63,0x90,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,
19390x8D,0x8E,0x8F,0x27,0x02,0x00,0x01,0x80,0x20,0x20,0x43,0x54,0x53,0x20,0x2D,0x20,
19400x70,0x69,0x6E,0x20,0x34,0x1F,0x27,0x53,0x83,0x2E,0x31,0x81,0x82,0x63,0x90,0x80,
19410x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x27,
19420x02,0x00,0x01,0x80,0x20,0x20,0x52,0x49,0x20,0x2D,0x20,0x70,0x69,0x6E,0x20,0x32,
19430x32,0x1F,0x27,0x53,0x87,0x2E,0x31,0x81,0x82,0x63,0x90,0x80,0x81,0x82,0x83,0x84,
19440x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x27,0x02,0x00,0x01,0x80,
19450x20,0x20,0x44,0x54,0x52,0x20,0x2D,0x20,0x70,0x69,0x6E,0x20,0x36,0x2F,0x38,0x1F,
19460x27,0x53,0x86,0x2E,0x31,0x81,0x82,0x63,0x90,0x80,0x81,0x82,0x83,0x84,0x85,0x86,
19470x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x27,0x02,0x00,0x01,0x80,0x20,0x20,
19480x52,0x54,0x53,0x20,0x2D,0x20,0x70,0x69,0x6E,0x20,0x35,0x1F,0x27,0x53,0x82,0x2E,
19490x31,0x81,0x82,0x63,0x90,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,
19500x8B,0x8C,0x8D,0x8E,0x8F,0x27,0x02,0x00,0x01,0x80,0x20,0x20,0x52,0x78,0x44,0x20,
19510x2D,0x20,0x70,0x69,0x6E,0x20,0x32,0x1F,0x27,0x53,0x81,0x2E,0x30,0x53,0x4D,0x81,
19520x82,0x63,0x90,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,
19530x8D,0x8E,0x8F,0x27,0x02,0x00,0x01,0x80,0x20,0x20,0x54,0x78,0x44,0x20,0x2D,0x20,
19540x70,0x69,0x6E,0x20,0x33,0x1F,0x27,0x53,0x80,0x2E,0x30,0x53,0x4D,0x81,0x82,0x63,
19550x90,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,
19560x8F,0x27,0x02,0x00,0x01,0x80,0x20,0x20,0x44,0x43,0x44,0x20,0x2D,0x20,0x70,0x69,
19570x6E,0x20,0x35,0x1F,0x27,0x53,0x85,0x2E,0x31,0x81,0x82,0x63,0x90,0x80,0x81,0x82,
19580x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x27,0x02,0x00,
19590x01,0x80,0x20,0x20,0x44,0x53,0x52,0x20,0x2D,0x20,0x70,0x69,0x6E,0x20,0x35,0x1F,
19600x27,0x53,0x84,0x2E,0x31,0x81,0x82,0x63,0x90,0x80,0x81,0x82,0x83,0x84,0x85,0x86,
19610x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x27,0x02,0x00,0x01,0x80,0x20,0x20,
19620x43,0x54,0x53,0x20,0x2D,0x20,0x70,0x69,0x6E,0x20,0x31,0x1F,0x27,0x53,0x83,0x2E,
19630x31,0x81,0x82,0x63,0x90,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,
19640x8B,0x8C,0x8D,0x8E,0x8F,0x27,0x02,0x00,0x01,0x80,0x20,0x20,0x52,0x49,0x20,0x2D,
19650x20,0x28,0x6E,0x2E,0x63,0x2E,0x29,0x1F,0x27,0x53,0x87,0x2E,0x31,0x81,0x82,0x63,
19660x90,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,
19670x8F,0x27,0x02,0x00,0x01,0x80,0x20,0x20,0x44,0x54,0x52,0x20,0x2D,0x20,0x70,0x69,
19680x6E,0x20,0x32,0x1F,0x27,0x53,0x86,0x2E,0x31,0x81,0x82,0x63,0x90,0x80,0x81,0x82,
19690x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x27,0x02,0x00,
19700x01,0x80,0x20,0x20,0x52,0x54,0x53,0x20,0x2D,0x20,0x70,0x69,0x6E,0x20,0x37,0x1F,
19710x27,0x53,0x82,0x2E,0x31,0x81,0x82,0x63,0x90,0x80,0x81,0x82,0x83,0x84,0x85,0x86,
19720x87,0x88,0x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x27,0x02,0x00,0x01,0x80,0x20,0x20,
19730x52,0x78,0x44,0x20,0x2D,0x20,0x70,0x69,0x6E,0x20,0x36,0x1F,0x27,0x53,0x81,0x2E,
19740x30,0x53,0x4D,0x81,0x82,0x63,0x90,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,
19750x89,0x8A,0x8B,0x8C,0x8D,0x8E,0x8F,0x27,0x02,0x00,0x01,0x80,0x20,0x20,0x54,0x78,
19760x44,0x20,0x2D,0x20,0x70,0x69,0x6E,0x20,0x33,0x1F,0x27,0x53,0x80,0x2E,0x30,0x53,
19770x4D,0x81,0x82,0x63,0x90,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x88,0x89,0x8A,
19780x8B,0x8C,0x8D,0x8E,0x8F,0x27,0x02,0x00,0x01,0x80,0x20,0x20,0x44,0x43,0x44,0x20,
19790x2D,0x20,0x70,0x69,0x6E,0x20,0x35,0x1F,0x20,0x20,0x20,0x20,0x27,0x53,0x85,0x2E,
19800x31,0x81,0x82,0x63,0x88,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x27,0x02,0x00,
19810x01,0x80,0x20,0x20,0x44,0x53,0x52,0x20,0x2D,0x20,0x70,0x69,0x6E,0x20,0x35,0x1F,
19820x20,0x20,0x20,0x20,0x27,0x53,0x84,0x2E,0x31,0x81,0x82,0x63,0x88,0x80,0x81,0x82,
19830x83,0x84,0x85,0x86,0x87,0x27,0x02,0x00,0x01,0x80,0x20,0x20,0x43,0x54,0x53,0x20,
19840x2D,0x20,0x70,0x69,0x6E,0x20,0x31,0x1F,0x20,0x20,0x20,0x20,0x27,0x53,0x83,0x2E,
19850x31,0x81,0x82,0x63,0x88,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x27,0x02,0x00,
19860x01,0x80,0x20,0x20,0x52,0x49,0x20,0x2D,0x20,0x28,0x6E,0x2E,0x63,0x2E,0x29,0x1F,
19870x20,0x20,0x20,0x20,0x27,0x53,0x87,0x2E,0x31,0x81,0x82,0x63,0x88,0x80,0x81,0x82,
19880x83,0x84,0x85,0x86,0x87,0x27,0x02,0x00,0x01,0x80,0x20,0x20,0x44,0x54,0x52,0x20,
19890x2D,0x20,0x70,0x69,0x6E,0x20,0x32,0x1F,0x20,0x20,0x20,0x20,0x27,0x53,0x86,0x2E,
19900x31,0x81,0x82,0x63,0x88,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x27,0x02,0x00,
19910x01,0x80,0x20,0x20,0x52,0x54,0x53,0x20,0x2D,0x20,0x70,0x69,0x6E,0x20,0x37,0x1F,
19920x20,0x20,0x20,0x20,0x27,0x53,0x82,0x2E,0x31,0x81,0x82,0x63,0x88,0x80,0x81,0x82,
19930x83,0x84,0x85,0x86,0x87,0x27,0x02,0x00,0x01,0x80,0x20,0x20,0x52,0x78,0x44,0x20,
19940x2D,0x20,0x70,0x69,0x6E,0x20,0x36,0x1F,0x20,0x20,0x20,0x20,0x27,0x53,0x81,0x2E,
19950x30,0x53,0x4D,0x81,0x82,0x63,0x88,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x27,
19960x02,0x00,0x01,0x80,0x20,0x20,0x54,0x78,0x44,0x20,0x2D,0x20,0x70,0x69,0x6E,0x20,
19970x33,0x1F,0x20,0x20,0x20,0x20,0x27,0x53,0x80,0x2E,0x30,0x53,0x4D,0x81,0x82,0x63,
19980x88,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x27,0x02,0x00,0x01,0x80,0x20,0x20,
19990x44,0x43,0x44,0x20,0x2D,0x20,0x70,0x69,0x6E,0x20,0x32,0x30,0x1F,0x20,0x20,0x20,
20000x20,0x27,0x53,0x85,0x2E,0x31,0x81,0x82,0x63,0x88,0x80,0x81,0x82,0x83,0x84,0x85,
20010x86,0x87,0x27,0x02,0x00,0x01,0x80,0x20,0x20,0x44,0x53,0x52,0x20,0x2D,0x20,0x70,
20020x69,0x6E,0x20,0x31,0x31,0x1F,0x20,0x20,0x20,0x20,0x27,0x53,0x84,0x2E,0x31,0x81,
20030x82,0x63,0x88,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x27,0x02,0x00,0x01,0x80,
20040x20,0x20,0x43,0x54,0x53,0x20,0x2D,0x20,0x70,0x69,0x6E,0x20,0x34,0x1F,0x20,0x20,
20050x20,0x20,0x27,0x53,0x83,0x2E,0x31,0x81,0x82,0x63,0x88,0x80,0x81,0x82,0x83,0x84,
20060x85,0x86,0x87,0x27,0x02,0x00,0x01,0x80,0x20,0x20,0x52,0x49,0x20,0x2D,0x20,0x70,
20070x69,0x6E,0x20,0x32,0x32,0x1F,0x20,0x20,0x20,0x20,0x27,0x53,0x87,0x2E,0x31,0x81,
20080x82,0x63,0x88,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x27,0x02,0x00,0x01,0x80,
20090x20,0x20,0x44,0x54,0x52,0x20,0x2D,0x20,0x70,0x69,0x6E,0x20,0x36,0x2F,0x38,0x1F,
20100x20,0x20,0x20,0x20,0x27,0x53,0x86,0x2E,0x31,0x81,0x82,0x63,0x88,0x80,0x81,0x82,
20110x83,0x84,0x85,0x86,0x87,0x27,0x02,0x00,0x01,0x80,0x20,0x20,0x52,0x54,0x53,0x20,
20120x2D,0x20,0x70,0x69,0x6E,0x20,0x35,0x1F,0x20,0x20,0x20,0x20,0x27,0x53,0x82,0x2E,
20130x31,0x81,0x82,0x63,0x88,0x80,0x81,0x82,0x83,0x84,0x85,0x86,0x87,0x27,0x02,0x00,
20140x01,0x80,0x20,0x20,0x52,0x78,0x44,0x20,0x2D,0x20,0x70,0x69,0x6E,0x20,0x32,0x1F,
20150x20,0x20,0x20,0x20,0x27,0x53,0x81,0x2E,0x30,0x53,0x4D,0x81,0x82,0x63,0x88,0x80,
20160x81,0x82,0x83,0x84,0x85,0x86,0x87,0x27,0x02,0x00,0x01,0x80,0x20,0x20,0x54,0x78,
20170x44,0x20,0x2D,0x20,0x70,0x69,0x6E,0x20,0x33,0x1F,0x20,0x20,0x20,0x20,0x27,0x53,
20180x80,0x2E,0x30,0x53,0x4D,0x81,0x82,0x63,0x88,0x80,0x81,0x82,0x83,0x84,0x85,0x86,
20190x87,0x27,0x02,0x00,0x68,0x04,0x96,0x04,0xB6,0x03,0x3C,0x04,0x0E,0x04,0x89,0x03,
20200x5C,0x03,0xE2,0x03,0x60,0x08,0x8A,0x08,0xBE,0x07,0x38,0x08,0x0E,0x08,0x95,0x07,
20210x6C,0x07,0xE6,0x07,0x1C,0x05,0x74,0x05,0xFA,0x05,0xC4,0x04,0xF0,0x04,0xCC,0x05,
20220xA0,0x05,0x48,0x05,0x78,0x06,0xC8,0x06,0x42,0x07,0x28,0x06,0x50,0x06,0x18,0x07,
20230xF0,0x06,0xA0,0x06,0x00,0x00,0xF4,0x08,0xF4,0x08,0xD4,0x0D,0x04,0x09,0x04,0x09,
20240x04,0x09,0x04,0x09,0x42,0x00,0x0C,0x09,0x1C,0x09,0xE5,0x0D,0x02,0x00,0x14,0x09,
20250x04,0x09,0xF4,0x0D,0x43,0x00,0x1C,0x09,0x0C,0x09,0x05,0x0E,0x00,0x04,0x04,0x09,
20260x14,0x09,0x12,0x0E,0x2C,0x09,0x2C,0x09,0x2C,0x09,0x2C,0x09,0x00,0x00,0x3C,0x09,
20270x6C,0x09,0x1E,0x0E,0x74,0x09,0x74,0x09,0x74,0x09,0x74,0x09,0x00,0x01,0x4C,0x09,
20280x2C,0x09,0x2D,0x0E,0x74,0x09,0x74,0x09,0x74,0x09,0x74,0x09,0x00,0x02,0x5C,0x09,
20290x3C,0x09,0x3D,0x0E,0x74,0x09,0x74,0x09,0x74,0x09,0x74,0x09,0x00,0x03,0x6C,0x09,
20300x4C,0x09,0x4D,0x0E,0x74,0x09,0x74,0x09,0x74,0x09,0x74,0x09,0xFF,0x00,0x2C,0x09,
20310x5C,0x09,0x00,0x00,0x00,0x05,0x84,0x09,0xEC,0x09,0x5E,0x0E,0xF4,0x09,0xF4,0x09,
20320xF4,0x09,0xF4,0x09,0x00,0x06,0x94,0x09,0x74,0x09,0x68,0x0E,0xAC,0x0A,0xAC,0x0A,
20330xAC,0x0A,0xAC,0x0A,0x00,0x07,0xA4,0x09,0x84,0x09,0x72,0x0E,0xBC,0x0A,0xBC,0x0A,
20340xBC,0x0A,0xBC,0x0A,0x00,0x08,0xB4,0x09,0x94,0x09,0x7C,0x0E,0xD4,0x0A,0xD4,0x0A,
20350xD4,0x0A,0xD4,0x0A,0x00,0x0B,0xC4,0x09,0xA4,0x09,0x83,0x0E,0xFC,0x0A,0xFC,0x0A,
20360xFC,0x0A,0xFC,0x0A,0x00,0x0C,0xD4,0x09,0xB4,0x09,0x90,0x0E,0x14,0x0B,0x14,0x0B,
20370x14,0x0B,0x14,0x0B,0x00,0x02,0xE4,0x09,0xC4,0x09,0xA0,0x0E,0x2C,0x0B,0x2C,0x0B,
20380x2C,0x0B,0x2C,0x0B,0x04,0x00,0xEC,0x09,0xD4,0x09,0x0E,0x00,0xFF,0x00,0x74,0x09,
20390xE4,0x09,0x00,0x00,0x82,0x01,0xFC,0x09,0xA4,0x0A,0xAC,0x0E,0x82,0x02,0x04,0x0A,
20400xF4,0x09,0xAF,0x0E,0x82,0x03,0x0C,0x0A,0xFC,0x09,0xB2,0x0E,0x82,0x04,0x14,0x0A,
20410x04,0x0A,0xB6,0x0E,0x82,0x05,0x1C,0x0A,0x0C,0x0A,0xBC,0x0E,0x82,0x06,0x24,0x0A,
20420x14,0x0A,0xC0,0x0E,0x82,0x07,0x2C,0x0A,0x1C,0x0A,0xC4,0x0E,0x82,0x08,0x34,0x0A,
20430x24,0x0A,0xC8,0x0E,0x82,0x09,0x3C,0x0A,0x2C,0x0A,0xCC,0x0E,0x82,0x0A,0x44,0x0A,
20440x34,0x0A,0xD1,0x0E,0x82,0x10,0x4C,0x0A,0x3C,0x0A,0xD6,0x0E,0x82,0x0B,0x54,0x0A,
20450x44,0x0A,0xDB,0x0E,0x82,0x11,0x5C,0x0A,0x4C,0x0A,0xE0,0x0E,0x82,0x0C,0x64,0x0A,
20460x54,0x0A,0xE5,0x0E,0x82,0x12,0x6C,0x0A,0x5C,0x0A,0xEA,0x0E,0x82,0x0D,0x74,0x0A,
20470x64,0x0A,0xEF,0x0E,0x82,0x0E,0x7C,0x0A,0x6C,0x0A,0xF4,0x0E,0x82,0x0F,0x84,0x0A,
20480x74,0x0A,0xFB,0x0E,0x82,0x13,0x8C,0x0A,0x7C,0x0A,0x02,0x0F,0x82,0x14,0x94,0x0A,
20490x84,0x0A,0x09,0x0F,0x82,0x15,0x9C,0x0A,0x8C,0x0A,0x10,0x0F,0x82,0x16,0xA4,0x0A,
20500x94,0x0A,0x17,0x0F,0x82,0x17,0xF4,0x09,0x9C,0x0A,0x1E,0x0F,0x82,0x02,0xB4,0x0A,
20510xB4,0x0A,0x26,0x0F,0x82,0x03,0xAC,0x0A,0xAC,0x0A,0x2D,0x0F,0x82,0x00,0xC4,0x0A,
20520xCC,0x0A,0x34,0x0F,0x82,0x01,0xCC,0x0A,0xBC,0x0A,0x3F,0x0F,0x82,0x02,0xBC,0x0A,
20530xC4,0x0A,0x4D,0x0F,0x82,0x00,0xDC,0x0A,0xF4,0x0A,0x59,0x0F,0x82,0x01,0xE4,0x0A,
20540xD4,0x0A,0x63,0x0F,0x82,0x02,0xEC,0x0A,0xDC,0x0A,0x6E,0x0F,0x82,0x03,0xF4,0x0A,
20550xE4,0x0A,0x7A,0x0F,0x82,0x04,0xD4,0x0A,0xEC,0x0A,0x87,0x0F,0x82,0x00,0x04,0x0B,
20560x0C,0x0B,0x93,0x0F,0x82,0x01,0x0C,0x0B,0xFC,0x0A,0x9B,0x0F,0x82,0x02,0xFC,0x0A,
20570x04,0x0B,0xA7,0x0F,0x82,0x00,0x1C,0x0B,0x24,0x0B,0xB0,0x0F,0x82,0x01,0x24,0x0B,
20580x14,0x0B,0xB5,0x0F,0x82,0x02,0x14,0x0B,0x1C,0x0B,0xBE,0x0F,0x44,0x00,0x34,0x0B,
20590xA4,0x0B,0x9C,0x01,0x44,0x01,0x3C,0x0B,0x2C,0x0B,0xA3,0x01,0x44,0x02,0x44,0x0B,
20600x34,0x0B,0xAA,0x01,0x44,0x03,0x4C,0x0B,0x3C,0x0B,0xB1,0x01,0x44,0x04,0x54,0x0B,
20610x44,0x0B,0xB8,0x01,0x44,0x05,0x5C,0x0B,0x4C,0x0B,0xBF,0x01,0x44,0x06,0x64,0x0B,
20620x54,0x0B,0xC6,0x01,0x44,0x07,0x6C,0x0B,0x5C,0x0B,0xCD,0x01,0x44,0x08,0x74,0x0B,
20630x64,0x0B,0xD4,0x01,0x44,0x09,0x7C,0x0B,0x6C,0x0B,0xDB,0x01,0x44,0x0A,0x84,0x0B,
20640x74,0x0B,0xE2,0x01,0x44,0x0B,0x8C,0x0B,0x7C,0x0B,0xEA,0x01,0x44,0x0C,0x94,0x0B,
20650x84,0x0B,0xF2,0x01,0x44,0x0D,0x9C,0x0B,0x8C,0x0B,0xFA,0x01,0x44,0x0E,0xA4,0x0B,
20660x94,0x0B,0x02,0x02,0x44,0x0F,0x2C,0x0B,0x9C,0x0B,0x0A,0x02,0x17,0x1F,0x0F,0x2F,
20670x00,0x00,0x01,0x80,0x78,0x78,0x3A,0x20,0x74,0x78,0x20,0x63,0x70,0x73,0x20,0x2A,
20680x2A,0x2A,0x2A,0x2A,0x02,0x00,0x01,0x80,0x78,0x78,0x3A,0x20,0x74,0x78,0x20,0x63,
20690x70,0x73,0x20,0x2A,0x2A,0x2A,0x2A,0x2A,0x02,0x00,0x01,0x80,0x78,0x78,0x3A,0x20,
20700x74,0x78,0x20,0x63,0x70,0x73,0x20,0x2A,0x2A,0x2A,0x2A,0x2A,0x02,0x00,0x01,0x80,
20710x78,0x78,0x3A,0x20,0x74,0x78,0x20,0x63,0x70,0x73,0x20,0x2A,0x2A,0x2A,0x2A,0x2A,
20720x02,0x00,0x01,0xC0,0x78,0x78,0x3A,0x20,0x72,0x63,0x20,0x63,0x70,0x73,0x20,0x2A,
20730x2A,0x2A,0x2A,0x2A,0x02,0x00,0x01,0xC0,0x78,0x78,0x3A,0x20,0x72,0x63,0x20,0x63,
20740x70,0x73,0x20,0x2A,0x2A,0x2A,0x2A,0x2A,0x02,0x00,0x01,0xC0,0x78,0x78,0x3A,0x20,
20750x72,0x63,0x20,0x63,0x70,0x73,0x20,0x2A,0x2A,0x2A,0x2A,0x2A,0x02,0x00,0x01,0xC0,
20760x78,0x78,0x3A,0x20,0x72,0x63,0x20,0x63,0x70,0x73,0x20,0x2A,0x2A,0x2A,0x2A,0x2A,
20770x02,0x00,0x01,0x80,0x49,0x6E,0x73,0x74,0x61,0x6C,0x6C,0x20,0x4C,0x6F,0x6F,0x70,
20780x62,0x61,0x63,0x6B,0x1F,0x50,0x72,0x65,0x73,0x73,0x20,0x80,0x20,0x74,0x6F,0x20,
20790x73,0x74,0x61,0x72,0x74,0x02,0x00,0x01,0x80,0x20,0x43,0x61,0x62,0x6C,0x65,0x20,
20800x74,0x6F,0x20,0x52,0x65,0x6D,0x6F,0x74,0x65,0x1F,0x50,0x72,0x65,0x73,0x73,0x20,
20810x80,0x20,0x74,0x6F,0x20,0x73,0x74,0x61,0x72,0x74,0x02,0x00,0x01,0x80,0x20,0x4C,
20820x6F,0x63,0x61,0x6C,0x20,0x4C,0x6F,0x6F,0x70,0x62,0x61,0x63,0x6B,0x20,0x1F,0x20,
20830x20,0x52,0x75,0x6E,0x6E,0x69,0x6E,0x67,0x20,0x2E,0x2E,0x2E,0x02,0x00,0x01,0x80,
20840x52,0x65,0x6D,0x6F,0x74,0x65,0x20,0x4C,0x6F,0x6F,0x70,0x62,0x61,0x63,0x6B,0x20,
20850x1F,0x20,0x20,0x52,0x75,0x6E,0x6E,0x69,0x6E,0x67,0x20,0x2E,0x2E,0x2E,0x02,0x00,
20860x01,0x80,0x20,0x49,0x6E,0x74,0x72,0x6E,0x6C,0x20,0x4C,0x6F,0x6F,0x70,0x62,0x61,
20870x63,0x6B,0x1F,0x20,0x20,0x52,0x75,0x6E,0x6E,0x69,0x6E,0x67,0x20,0x2E,0x2E,0x2E,
20880x02,0x00,0x01,0x80,0x54,0x72,0x61,0x6E,0x73,0x6D,0x69,0x74,0x20,0x50,0x61,0x74,
20890x74,0x65,0x72,0x6E,0x1F,0x20,0x20,0x52,0x75,0x6E,0x6E,0x69,0x6E,0x67,0x20,0x2E,
20900x2E,0x2E,0x02,0x00,0x01,0x80,0x20,0x20,0x30,0x3A,0x20,0x27,0x43,0x80,0x00,0x01,
20910x80,0x20,0x20,0x31,0x3A,0x20,0x27,0x43,0x81,0x00,0x01,0x80,0x20,0x20,0x32,0x3A,
20920x20,0x27,0x43,0x82,0x00,0x01,0x80,0x20,0x20,0x33,0x3A,0x20,0x27,0x43,0x83,0x00,
20930x01,0x80,0x20,0x20,0x34,0x3A,0x20,0x27,0x43,0x84,0x00,0x01,0x80,0x20,0x20,0x35,
20940x3A,0x20,0x27,0x43,0x85,0x00,0x01,0x80,0x20,0x20,0x36,0x3A,0x20,0x27,0x43,0x86,
20950x00,0x01,0x80,0x20,0x20,0x37,0x3A,0x20,0x27,0x43,0x87,0x00,0x01,0x80,0x20,0x20,
20960x38,0x3A,0x20,0x27,0x43,0x88,0x00,0x01,0x80,0x20,0x20,0x39,0x3A,0x20,0x27,0x43,
20970x89,0x00,0x01,0x80,0x20,0x31,0x30,0x3A,0x20,0x27,0x43,0x8A,0x00,0x01,0x80,0x20,
20980x31,0x31,0x3A,0x20,0x27,0x43,0x8B,0x00,0x01,0x80,0x20,0x31,0x32,0x3A,0x20,0x27,
20990x43,0x8C,0x00,0x01,0x80,0x20,0x31,0x33,0x3A,0x20,0x27,0x43,0x8D,0x00,0x01,0x80,
21000x20,0x31,0x34,0x3A,0x20,0x27,0x43,0x8E,0x00,0x01,0x80,0x20,0x31,0x35,0x3A,0x20,
21010x27,0x43,0x8F,0x00,0x2A,0x2A,0x20,0x4D,0x61,0x69,0x6E,0x20,0x20,0x4D,0x65,0x6E,
21020x75,0x20,0x2A,0x2A,0x00,0x4D,0x6F,0x6E,0x69,0x74,0x6F,0x72,0x20,0x61,0x20,0x50,
21030x6F,0x72,0x74,0x00,0x4D,0x6F,0x6E,0x69,0x74,0x6F,0x72,0x20,0x61,0x20,0x53,0x69,
21040x67,0x6E,0x61,0x6C,0x00,0x45,0x73,0x74,0x69,0x6D,0x61,0x74,0x65,0x20,0x43,0x50,
21050x53,0x00,0x44,0x69,0x61,0x67,0x6E,0x6F,0x73,0x74,0x69,0x63,0x73,0x00,0x4C,0x6F,
21060x63,0x61,0x6C,0x20,0x4C,0x6F,0x6F,0x70,0x62,0x61,0x63,0x6B,0x00,0x52,0x65,0x6D,
21070x6F,0x74,0x65,0x20,0x4C,0x6F,0x6F,0x70,0x62,0x61,0x63,0x6B,0x00,0x49,0x6E,0x74,
21080x72,0x6E,0x6C,0x20,0x4C,0x6F,0x6F,0x70,0x62,0x61,0x63,0x6B,0x00,0x54,0x72,0x61,
21090x6E,0x73,0x6D,0x69,0x74,0x20,0x50,0x61,0x74,0x74,0x65,0x72,0x6E,0x00,0x42,0x61,
21100x75,0x64,0x20,0x52,0x61,0x74,0x65,0x00,0x44,0x61,0x74,0x61,0x20,0x42,0x69,0x74,
21110x73,0x00,0x53,0x74,0x6F,0x70,0x20,0x42,0x69,0x74,0x73,0x00,0x50,0x61,0x72,0x69,
21120x74,0x79,0x00,0x44,0x61,0x74,0x61,0x20,0x50,0x61,0x74,0x74,0x65,0x72,0x6E,0x00,
21130x54,0x78,0x20,0x46,0x6C,0x6F,0x77,0x20,0x43,0x6F,0x6E,0x74,0x72,0x6F,0x6C,0x00,
21140x50,0x6F,0x72,0x74,0x20,0x4E,0x75,0x6D,0x62,0x65,0x72,0x00,0x35,0x30,0x00,0x37,
21150x35,0x00,0x31,0x31,0x30,0x00,0x31,0x33,0x34,0x2E,0x35,0x00,0x31,0x35,0x30,0x00,
21160x32,0x30,0x30,0x00,0x33,0x30,0x30,0x00,0x36,0x30,0x30,0x00,0x31,0x32,0x30,0x30,
21170x00,0x31,0x38,0x30,0x30,0x00,0x32,0x30,0x30,0x30,0x00,0x32,0x34,0x30,0x30,0x00,
21180x33,0x36,0x30,0x30,0x00,0x34,0x38,0x30,0x30,0x00,0x37,0x32,0x30,0x30,0x00,0x39,
21190x36,0x30,0x30,0x00,0x31,0x39,0x2C,0x32,0x30,0x30,0x00,0x33,0x38,0x2C,0x34,0x30,
21200x30,0x00,0x35,0x36,0x2C,0x30,0x30,0x30,0x00,0x35,0x37,0x2C,0x36,0x30,0x30,0x00,
21210x36,0x34,0x2C,0x30,0x30,0x30,0x00,0x37,0x36,0x2C,0x38,0x30,0x30,0x00,0x31,0x31,
21220x35,0x2C,0x32,0x30,0x30,0x00,0x37,0x20,0x62,0x69,0x74,0x73,0x00,0x38,0x20,0x62,
21230x69,0x74,0x73,0x00,0x31,0x20,0x73,0x74,0x6F,0x70,0x20,0x62,0x69,0x74,0x00,0x31,
21240x2E,0x35,0x20,0x73,0x74,0x6F,0x70,0x20,0x62,0x69,0x74,0x73,0x00,0x32,0x20,0x73,
21250x74,0x6F,0x70,0x20,0x62,0x69,0x74,0x73,0x00,0x6E,0x6F,0x20,0x70,0x61,0x72,0x69,
21260x74,0x79,0x00,0x6F,0x64,0x64,0x20,0x70,0x61,0x72,0x69,0x74,0x79,0x00,0x65,0x76,
21270x65,0x6E,0x20,0x70,0x61,0x72,0x69,0x74,0x79,0x00,0x73,0x70,0x61,0x63,0x65,0x20,
21280x70,0x61,0x72,0x69,0x74,0x79,0x00,0x6D,0x61,0x72,0x6B,0x20,0x70,0x61,0x72,0x69,
21290x74,0x79,0x00,0x43,0x6F,0x6C,0x75,0x6D,0x6E,0x73,0x00,0x42,0x61,0x72,0x62,0x65,
21300x72,0x20,0x50,0x6F,0x6C,0x65,0x00,0x55,0x55,0x55,0x55,0x55,0x2E,0x2E,0x2E,0x00,
21310x4E,0x6F,0x6E,0x65,0x00,0x58,0x6F,0x6E,0x2F,0x58,0x6F,0x66,0x66,0x00,0x43,0x54,
21320x53,0x00,0x50,0x72,0x65,0x73,0x73,0x20,0x80,0x20,0x66,0x6F,0x72,0x20,0x6D,0x65,
21330x6E,0x75,0x00,0x28,0x63,0x6F,0x75,0x6E,0x74,0x69,0x6E,0x67,0x2E,0x2E,0x2E,0x29,
21340x00,0x00,0x65,0x4E,0x64,0x20,0x4F,0x66,0x20,0x43,0x6F,0x44,0x65,0x00,0x00,0x00,
21350x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
21360x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
21370x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
21380x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
21390x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
21400x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
21410x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
21420x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
21430x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
21440x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
21450x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
21460x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
21470x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
21480x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
2149};
diff --git a/drivers/char/ip2/i2lib.c b/drivers/char/ip2/i2lib.c
index 938879cc7bcc..0061e18aff60 100644
--- a/drivers/char/ip2/i2lib.c
+++ b/drivers/char/ip2/i2lib.c
@@ -868,11 +868,11 @@ i2Input(i2ChanStrPtr pCh)
868 amountToMove = count; 868 amountToMove = count;
869 } 869 }
870 // Move the first block 870 // Move the first block
871 pCh->pTTY->ldisc.receive_buf( pCh->pTTY, 871 pCh->pTTY->ldisc.ops->receive_buf( pCh->pTTY,
872 &(pCh->Ibuf[stripIndex]), NULL, amountToMove ); 872 &(pCh->Ibuf[stripIndex]), NULL, amountToMove );
873 // If we needed to wrap, do the second data move 873 // If we needed to wrap, do the second data move
874 if (count > amountToMove) { 874 if (count > amountToMove) {
875 pCh->pTTY->ldisc.receive_buf( pCh->pTTY, 875 pCh->pTTY->ldisc.ops->receive_buf( pCh->pTTY,
876 pCh->Ibuf, NULL, count - amountToMove ); 876 pCh->Ibuf, NULL, count - amountToMove );
877 } 877 }
878 // Bump and wrap the stripIndex all at once by the amount of data read. This 878 // Bump and wrap the stripIndex all at once by the amount of data read. This
diff --git a/drivers/char/ip2/ip2base.c b/drivers/char/ip2/ip2base.c
index 435ccfc74958..8155e247c04b 100644
--- a/drivers/char/ip2/ip2base.c
+++ b/drivers/char/ip2/ip2base.c
@@ -21,10 +21,9 @@
21#endif 21#endif
22 22
23#include "ip2types.h" 23#include "ip2types.h"
24#include "fip_firm.h" // the meat
25 24
26int 25int
27ip2_loadmain(int *, int *, unsigned char *, int ); // ref into ip2main.c 26ip2_loadmain(int *, int *); // ref into ip2main.c
28 27
29/* Note: Add compiled in defaults to these arrays, not to the structure 28/* Note: Add compiled in defaults to these arrays, not to the structure
30 in ip2.h any longer. That structure WILL get overridden 29 in ip2.h any longer. That structure WILL get overridden
@@ -52,7 +51,7 @@ static int __init ip2_init(void)
52 irq[0] = irq[1] = irq[2] = irq[3] = 0; 51 irq[0] = irq[1] = irq[2] = irq[3] = 0;
53 } 52 }
54 53
55 return ip2_loadmain(io,irq,(unsigned char *)fip_firm,sizeof(fip_firm)); 54 return ip2_loadmain(io, irq);
56} 55}
57module_init(ip2_init); 56module_init(ip2_init);
58 57
diff --git a/drivers/char/ip2/ip2main.c b/drivers/char/ip2/ip2main.c
index 70957acaa960..5dc74404058f 100644
--- a/drivers/char/ip2/ip2main.c
+++ b/drivers/char/ip2/ip2main.c
@@ -98,6 +98,9 @@
98#include <linux/major.h> 98#include <linux/major.h>
99#include <linux/wait.h> 99#include <linux/wait.h>
100#include <linux/device.h> 100#include <linux/device.h>
101#include <linux/smp_lock.h>
102#include <linux/firmware.h>
103#include <linux/platform_device.h>
101 104
102#include <linux/tty.h> 105#include <linux/tty.h>
103#include <linux/tty_flip.h> 106#include <linux/tty_flip.h>
@@ -155,9 +158,7 @@ static char *pcDriver_name = "ip2";
155static char *pcIpl = "ip2ipl"; 158static char *pcIpl = "ip2ipl";
156 159
157// cheezy kludge or genius - you decide? 160// cheezy kludge or genius - you decide?
158int ip2_loadmain(int *, int *, unsigned char *, int); 161int ip2_loadmain(int *, int *);
159static unsigned char *Fip_firmware;
160static int Fip_firmware_size;
161 162
162/***********************/ 163/***********************/
163/* Function Prototypes */ 164/* Function Prototypes */
@@ -208,7 +209,7 @@ static int ip2_ipl_open(struct inode *, struct file *);
208static int DumpTraceBuffer(char __user *, int); 209static int DumpTraceBuffer(char __user *, int);
209static int DumpFifoBuffer( char __user *, int); 210static int DumpFifoBuffer( char __user *, int);
210 211
211static void ip2_init_board(int); 212static void ip2_init_board(int, const struct firmware *);
212static unsigned short find_eisa_board(int); 213static unsigned short find_eisa_board(int);
213 214
214/***************/ 215/***************/
@@ -346,27 +347,6 @@ have_requested_irq( char irq )
346} 347}
347 348
348/******************************************************************************/ 349/******************************************************************************/
349/* Function: init_module() */
350/* Parameters: None */
351/* Returns: Success (0) */
352/* */
353/* Description: */
354/* This is a required entry point for an installable module. It simply calls */
355/* the driver initialisation function and returns what it returns. */
356/******************************************************************************/
357#ifdef MODULE
358static int __init
359ip2_init_module(void)
360{
361#ifdef IP2DEBUG_INIT
362 printk (KERN_DEBUG "Loading module ...\n" );
363#endif
364 return 0;
365}
366module_init(ip2_init_module);
367#endif /* MODULE */
368
369/******************************************************************************/
370/* Function: cleanup_module() */ 350/* Function: cleanup_module() */
371/* Parameters: None */ 351/* Parameters: None */
372/* Returns: Nothing */ 352/* Returns: Nothing */
@@ -495,8 +475,27 @@ static const struct tty_operations ip2_ops = {
495/* SA_RANDOM - can be source for cert. random number generators */ 475/* SA_RANDOM - can be source for cert. random number generators */
496#define IP2_SA_FLAGS 0 476#define IP2_SA_FLAGS 0
497 477
478
479static const struct firmware *ip2_request_firmware(void)
480{
481 struct platform_device *pdev;
482 const struct firmware *fw;
483
484 pdev = platform_device_register_simple("ip2", 0, NULL, 0);
485 if (IS_ERR(pdev)) {
486 printk(KERN_ERR "Failed to register platform device for ip2\n");
487 return NULL;
488 }
489 if (request_firmware(&fw, "intelliport2.bin", &pdev->dev)) {
490 printk(KERN_ERR "Failed to load firmware 'intelliport2.bin'\n");
491 fw = NULL;
492 }
493 platform_device_unregister(pdev);
494 return fw;
495}
496
498int 497int
499ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize) 498ip2_loadmain(int *iop, int *irqp)
500{ 499{
501 int i, j, box; 500 int i, j, box;
502 int err = 0; 501 int err = 0;
@@ -504,6 +503,7 @@ ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize)
504 i2eBordStrPtr pB = NULL; 503 i2eBordStrPtr pB = NULL;
505 int rc = -1; 504 int rc = -1;
506 static struct pci_dev *pci_dev_i = NULL; 505 static struct pci_dev *pci_dev_i = NULL;
506 const struct firmware *fw = NULL;
507 507
508 ip2trace (ITRC_NO_PORT, ITRC_INIT, ITRC_ENTER, 0 ); 508 ip2trace (ITRC_NO_PORT, ITRC_INIT, ITRC_ENTER, 0 );
509 509
@@ -537,9 +537,6 @@ ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize)
537 } 537 }
538 poll_only = !poll_only; 538 poll_only = !poll_only;
539 539
540 Fip_firmware = firmware;
541 Fip_firmware_size = firmsize;
542
543 /* Announce our presence */ 540 /* Announce our presence */
544 printk( KERN_INFO "%s version %s\n", pcName, pcVersion ); 541 printk( KERN_INFO "%s version %s\n", pcName, pcVersion );
545 542
@@ -659,10 +656,18 @@ ip2_loadmain(int *iop, int *irqp, unsigned char *firmware, int firmsize)
659 } 656 }
660 } 657 }
661 for ( i = 0; i < IP2_MAX_BOARDS; ++i ) { 658 for ( i = 0; i < IP2_MAX_BOARDS; ++i ) {
659 /* We don't want to request the firmware unless we have at
660 least one board */
662 if ( i2BoardPtrTable[i] != NULL ) { 661 if ( i2BoardPtrTable[i] != NULL ) {
663 ip2_init_board( i ); 662 if (!fw)
663 fw = ip2_request_firmware();
664 if (!fw)
665 break;
666 ip2_init_board(i, fw);
664 } 667 }
665 } 668 }
669 if (fw)
670 release_firmware(fw);
666 671
667 ip2trace (ITRC_NO_PORT, ITRC_INIT, 2, 0 ); 672 ip2trace (ITRC_NO_PORT, ITRC_INIT, 2, 0 );
668 673
@@ -779,8 +784,6 @@ out:
779 return err; 784 return err;
780} 785}
781 786
782EXPORT_SYMBOL(ip2_loadmain);
783
784/******************************************************************************/ 787/******************************************************************************/
785/* Function: ip2_init_board() */ 788/* Function: ip2_init_board() */
786/* Parameters: Index of board in configuration structure */ 789/* Parameters: Index of board in configuration structure */
@@ -792,7 +795,7 @@ EXPORT_SYMBOL(ip2_loadmain);
792/* are reported on the console. */ 795/* are reported on the console. */
793/******************************************************************************/ 796/******************************************************************************/
794static void 797static void
795ip2_init_board( int boardnum ) 798ip2_init_board(int boardnum, const struct firmware *fw)
796{ 799{
797 int i; 800 int i;
798 int nports = 0, nboxes = 0; 801 int nports = 0, nboxes = 0;
@@ -812,7 +815,7 @@ ip2_init_board( int boardnum )
812 goto err_initialize; 815 goto err_initialize;
813 } 816 }
814 817
815 if ( iiDownloadAll ( pB, (loadHdrStrPtr)Fip_firmware, 1, Fip_firmware_size ) 818 if ( iiDownloadAll ( pB, (loadHdrStrPtr)fw->data, 1, fw->size )
816 != II_DOWN_GOOD ) { 819 != II_DOWN_GOOD ) {
817 printk ( KERN_ERR "IP2: failed to download loadware\n" ); 820 printk ( KERN_ERR "IP2: failed to download loadware\n" );
818 goto err_release_region; 821 goto err_release_region;
@@ -1286,11 +1289,12 @@ static void do_input(struct work_struct *work)
1286// code duplicated from n_tty (ldisc) 1289// code duplicated from n_tty (ldisc)
1287static inline void isig(int sig, struct tty_struct *tty, int flush) 1290static inline void isig(int sig, struct tty_struct *tty, int flush)
1288{ 1291{
1292 /* FIXME: This is completely bogus */
1289 if (tty->pgrp) 1293 if (tty->pgrp)
1290 kill_pgrp(tty->pgrp, sig, 1); 1294 kill_pgrp(tty->pgrp, sig, 1);
1291 if (flush || !L_NOFLSH(tty)) { 1295 if (flush || !L_NOFLSH(tty)) {
1292 if ( tty->ldisc.flush_buffer ) 1296 if ( tty->ldisc.ops->flush_buffer )
1293 tty->ldisc.flush_buffer(tty); 1297 tty->ldisc.ops->flush_buffer(tty);
1294 i2InputFlush( tty->driver_data ); 1298 i2InputFlush( tty->driver_data );
1295 } 1299 }
1296} 1300}
@@ -1339,7 +1343,7 @@ static void do_status(struct work_struct *work)
1339 } 1343 }
1340 tmp = pCh->pTTY->real_raw; 1344 tmp = pCh->pTTY->real_raw;
1341 pCh->pTTY->real_raw = 0; 1345 pCh->pTTY->real_raw = 0;
1342 pCh->pTTY->ldisc.receive_buf( pCh->pTTY, &brkc, &brkf, 1 ); 1346 pCh->pTTY->ldisc->ops.receive_buf( pCh->pTTY, &brkc, &brkf, 1 );
1343 pCh->pTTY->real_raw = tmp; 1347 pCh->pTTY->real_raw = tmp;
1344 } 1348 }
1345#endif /* NEVER_HAPPENS_AS_SETUP_XXX */ 1349#endif /* NEVER_HAPPENS_AS_SETUP_XXX */
@@ -2931,42 +2935,11 @@ ip2_ipl_ioctl ( struct inode *pInode, struct file *pFile, UINT cmd, ULONG arg )
2931static int 2935static int
2932ip2_ipl_open( struct inode *pInode, struct file *pFile ) 2936ip2_ipl_open( struct inode *pInode, struct file *pFile )
2933{ 2937{
2934 unsigned int iplminor = iminor(pInode);
2935 i2eBordStrPtr pB;
2936 i2ChanStrPtr pCh;
2937 2938
2938#ifdef IP2DEBUG_IPL 2939#ifdef IP2DEBUG_IPL
2939 printk (KERN_DEBUG "IP2IPL: open\n" ); 2940 printk (KERN_DEBUG "IP2IPL: open\n" );
2940#endif 2941#endif
2941 2942 cycle_kernel_lock();
2942 switch(iplminor) {
2943 // These are the IPL devices
2944 case 0:
2945 case 4:
2946 case 8:
2947 case 12:
2948 break;
2949
2950 // These are the status devices
2951 case 1:
2952 case 5:
2953 case 9:
2954 case 13:
2955 break;
2956
2957 // These are the debug devices
2958 case 2:
2959 case 6:
2960 case 10:
2961 case 14:
2962 pB = i2BoardPtrTable[iplminor / 4];
2963 pCh = (i2ChanStrPtr) pB->i2eChannelPtr;
2964 break;
2965
2966 // This is the trace device
2967 case 3:
2968 break;
2969 }
2970 return 0; 2943 return 0;
2971} 2944}
2972 2945
diff --git a/drivers/char/ip27-rtc.c b/drivers/char/ip27-rtc.c
index 86e6538a77b0..ec9d0443d92c 100644
--- a/drivers/char/ip27-rtc.c
+++ b/drivers/char/ip27-rtc.c
@@ -27,6 +27,7 @@
27#include <linux/bcd.h> 27#include <linux/bcd.h>
28#include <linux/module.h> 28#include <linux/module.h>
29#include <linux/kernel.h> 29#include <linux/kernel.h>
30#include <linux/smp_lock.h>
30#include <linux/types.h> 31#include <linux/types.h>
31#include <linux/miscdevice.h> 32#include <linux/miscdevice.h>
32#include <linux/ioport.h> 33#include <linux/ioport.h>
@@ -163,15 +164,18 @@ static long rtc_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
163 164
164static int rtc_open(struct inode *inode, struct file *file) 165static int rtc_open(struct inode *inode, struct file *file)
165{ 166{
167 lock_kernel();
166 spin_lock_irq(&rtc_lock); 168 spin_lock_irq(&rtc_lock);
167 169
168 if (rtc_status & RTC_IS_OPEN) { 170 if (rtc_status & RTC_IS_OPEN) {
169 spin_unlock_irq(&rtc_lock); 171 spin_unlock_irq(&rtc_lock);
172 unlock_kernel();
170 return -EBUSY; 173 return -EBUSY;
171 } 174 }
172 175
173 rtc_status |= RTC_IS_OPEN; 176 rtc_status |= RTC_IS_OPEN;
174 spin_unlock_irq(&rtc_lock); 177 spin_unlock_irq(&rtc_lock);
178 unlock_kernel();
175 179
176 return 0; 180 return 0;
177} 181}
diff --git a/drivers/char/ipmi/ipmi_devintf.c b/drivers/char/ipmi/ipmi_devintf.c
index 0246a2b8ce48..c11a40483459 100644
--- a/drivers/char/ipmi/ipmi_devintf.c
+++ b/drivers/char/ipmi/ipmi_devintf.c
@@ -43,6 +43,7 @@
43#include <linux/init.h> 43#include <linux/init.h>
44#include <linux/device.h> 44#include <linux/device.h>
45#include <linux/compat.h> 45#include <linux/compat.h>
46#include <linux/smp_lock.h>
46 47
47struct ipmi_file_private 48struct ipmi_file_private
48{ 49{
@@ -100,7 +101,9 @@ static int ipmi_fasync(int fd, struct file *file, int on)
100 struct ipmi_file_private *priv = file->private_data; 101 struct ipmi_file_private *priv = file->private_data;
101 int result; 102 int result;
102 103
104 lock_kernel(); /* could race against open() otherwise */
103 result = fasync_helper(fd, file, on, &priv->fasync_queue); 105 result = fasync_helper(fd, file, on, &priv->fasync_queue);
106 unlock_kernel();
104 107
105 return (result); 108 return (result);
106} 109}
@@ -121,6 +124,7 @@ static int ipmi_open(struct inode *inode, struct file *file)
121 if (!priv) 124 if (!priv)
122 return -ENOMEM; 125 return -ENOMEM;
123 126
127 lock_kernel();
124 priv->file = file; 128 priv->file = file;
125 129
126 rv = ipmi_create_user(if_num, 130 rv = ipmi_create_user(if_num,
@@ -129,7 +133,7 @@ static int ipmi_open(struct inode *inode, struct file *file)
129 &(priv->user)); 133 &(priv->user));
130 if (rv) { 134 if (rv) {
131 kfree(priv); 135 kfree(priv);
132 return rv; 136 goto out;
133 } 137 }
134 138
135 file->private_data = priv; 139 file->private_data = priv;
@@ -144,7 +148,9 @@ static int ipmi_open(struct inode *inode, struct file *file)
144 priv->default_retries = -1; 148 priv->default_retries = -1;
145 priv->default_retry_time_ms = 0; 149 priv->default_retry_time_ms = 0;
146 150
147 return 0; 151out:
152 unlock_kernel();
153 return rv;
148} 154}
149 155
150static int ipmi_release(struct inode *inode, struct file *file) 156static int ipmi_release(struct inode *inode, struct file *file)
diff --git a/drivers/char/ipmi/ipmi_watchdog.c b/drivers/char/ipmi/ipmi_watchdog.c
index 1b9a87047817..235fab0bdf79 100644
--- a/drivers/char/ipmi/ipmi_watchdog.c
+++ b/drivers/char/ipmi/ipmi_watchdog.c
@@ -35,6 +35,7 @@
35#include <linux/moduleparam.h> 35#include <linux/moduleparam.h>
36#include <linux/ipmi.h> 36#include <linux/ipmi.h>
37#include <linux/ipmi_smi.h> 37#include <linux/ipmi_smi.h>
38#include <linux/smp_lock.h>
38#include <linux/watchdog.h> 39#include <linux/watchdog.h>
39#include <linux/miscdevice.h> 40#include <linux/miscdevice.h>
40#include <linux/init.h> 41#include <linux/init.h>
@@ -755,9 +756,8 @@ static ssize_t ipmi_write(struct file *file,
755 rv = ipmi_heartbeat(); 756 rv = ipmi_heartbeat();
756 if (rv) 757 if (rv)
757 return rv; 758 return rv;
758 return 1;
759 } 759 }
760 return 0; 760 return len;
761} 761}
762 762
763static ssize_t ipmi_read(struct file *file, 763static ssize_t ipmi_read(struct file *file,
@@ -819,6 +819,8 @@ static int ipmi_open(struct inode *ino, struct file *filep)
819 if (test_and_set_bit(0, &ipmi_wdog_open)) 819 if (test_and_set_bit(0, &ipmi_wdog_open))
820 return -EBUSY; 820 return -EBUSY;
821 821
822 cycle_kernel_lock();
823
822 /* 824 /*
823 * Don't start the timer now, let it start on the 825 * Don't start the timer now, let it start on the
824 * first heartbeat. 826 * first heartbeat.
diff --git a/drivers/char/isicom.c b/drivers/char/isicom.c
index 4f3cefa8eb0e..d4281df10c22 100644
--- a/drivers/char/isicom.c
+++ b/drivers/char/isicom.c
@@ -198,17 +198,10 @@ struct isi_board {
198 198
199struct isi_port { 199struct isi_port {
200 unsigned short magic; 200 unsigned short magic;
201 unsigned int flags; 201 struct tty_port port;
202 int count;
203 int blocked_open;
204 int close_delay;
205 u16 channel; 202 u16 channel;
206 u16 status; 203 u16 status;
207 u16 closing_wait;
208 struct isi_board *card; 204 struct isi_board *card;
209 struct tty_struct *tty;
210 wait_queue_head_t close_wait;
211 wait_queue_head_t open_wait;
212 unsigned char *xmit_buf; 205 unsigned char *xmit_buf;
213 int xmit_head; 206 int xmit_head;
214 int xmit_tail; 207 int xmit_tail;
@@ -430,11 +423,11 @@ static void isicom_tx(unsigned long _data)
430 423
431 for (; count > 0; count--, port++) { 424 for (; count > 0; count--, port++) {
432 /* port not active or tx disabled to force flow control */ 425 /* port not active or tx disabled to force flow control */
433 if (!(port->flags & ASYNC_INITIALIZED) || 426 if (!(port->port.flags & ASYNC_INITIALIZED) ||
434 !(port->status & ISI_TXOK)) 427 !(port->status & ISI_TXOK))
435 continue; 428 continue;
436 429
437 tty = port->tty; 430 tty = port->port.tty;
438 431
439 if (tty == NULL) 432 if (tty == NULL)
440 continue; 433 continue;
@@ -458,7 +451,7 @@ static void isicom_tx(unsigned long _data)
458 if (residue == YES) { 451 if (residue == YES) {
459 residue = NO; 452 residue = NO;
460 if (cnt > 0) { 453 if (cnt > 0) {
461 wrd |= (port->xmit_buf[port->xmit_tail] 454 wrd |= (port->port.xmit_buf[port->xmit_tail]
462 << 8); 455 << 8);
463 port->xmit_tail = (port->xmit_tail + 1) 456 port->xmit_tail = (port->xmit_tail + 1)
464 & (SERIAL_XMIT_SIZE - 1); 457 & (SERIAL_XMIT_SIZE - 1);
@@ -474,14 +467,14 @@ static void isicom_tx(unsigned long _data)
474 if (cnt <= 0) 467 if (cnt <= 0)
475 break; 468 break;
476 word_count = cnt >> 1; 469 word_count = cnt >> 1;
477 outsw(base, port->xmit_buf+port->xmit_tail, word_count); 470 outsw(base, port->port.xmit_buf+port->xmit_tail, word_count);
478 port->xmit_tail = (port->xmit_tail 471 port->xmit_tail = (port->xmit_tail
479 + (word_count << 1)) & (SERIAL_XMIT_SIZE - 1); 472 + (word_count << 1)) & (SERIAL_XMIT_SIZE - 1);
480 txcount -= (word_count << 1); 473 txcount -= (word_count << 1);
481 port->xmit_cnt -= (word_count << 1); 474 port->xmit_cnt -= (word_count << 1);
482 if (cnt & 0x0001) { 475 if (cnt & 0x0001) {
483 residue = YES; 476 residue = YES;
484 wrd = port->xmit_buf[port->xmit_tail]; 477 wrd = port->port.xmit_buf[port->xmit_tail];
485 port->xmit_tail = (port->xmit_tail + 1) 478 port->xmit_tail = (port->xmit_tail + 1)
486 & (SERIAL_XMIT_SIZE - 1); 479 & (SERIAL_XMIT_SIZE - 1);
487 port->xmit_cnt--; 480 port->xmit_cnt--;
@@ -548,13 +541,13 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id)
548 return IRQ_HANDLED; 541 return IRQ_HANDLED;
549 } 542 }
550 port = card->ports + channel; 543 port = card->ports + channel;
551 if (!(port->flags & ASYNC_INITIALIZED)) { 544 if (!(port->port.flags & ASYNC_INITIALIZED)) {
552 outw(0x0000, base+0x04); /* enable interrupts */ 545 outw(0x0000, base+0x04); /* enable interrupts */
553 spin_unlock(&card->card_lock); 546 spin_unlock(&card->card_lock);
554 return IRQ_HANDLED; 547 return IRQ_HANDLED;
555 } 548 }
556 549
557 tty = port->tty; 550 tty = port->port.tty;
558 if (tty == NULL) { 551 if (tty == NULL) {
559 word_count = byte_count >> 1; 552 word_count = byte_count >> 1;
560 while (byte_count > 1) { 553 while (byte_count > 1) {
@@ -572,7 +565,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id)
572 header = inw(base); 565 header = inw(base);
573 switch (header & 0xff) { 566 switch (header & 0xff) {
574 case 0: /* Change in EIA signals */ 567 case 0: /* Change in EIA signals */
575 if (port->flags & ASYNC_CHECK_CD) { 568 if (port->port.flags & ASYNC_CHECK_CD) {
576 if (port->status & ISI_DCD) { 569 if (port->status & ISI_DCD) {
577 if (!(header & ISI_DCD)) { 570 if (!(header & ISI_DCD)) {
578 /* Carrier has been lost */ 571 /* Carrier has been lost */
@@ -585,7 +578,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id)
585 /* Carrier has been detected */ 578 /* Carrier has been detected */
586 pr_dbg("interrupt: DCD->high.\n"); 579 pr_dbg("interrupt: DCD->high.\n");
587 port->status |= ISI_DCD; 580 port->status |= ISI_DCD;
588 wake_up_interruptible(&port->open_wait); 581 wake_up_interruptible(&port->port.open_wait);
589 } 582 }
590 } else { 583 } else {
591 if (header & ISI_DCD) 584 if (header & ISI_DCD)
@@ -594,17 +587,17 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id)
594 port->status &= ~ISI_DCD; 587 port->status &= ~ISI_DCD;
595 } 588 }
596 589
597 if (port->flags & ASYNC_CTS_FLOW) { 590 if (port->port.flags & ASYNC_CTS_FLOW) {
598 if (port->tty->hw_stopped) { 591 if (port->port.tty->hw_stopped) {
599 if (header & ISI_CTS) { 592 if (header & ISI_CTS) {
600 port->tty->hw_stopped = 0; 593 port->port.tty->hw_stopped = 0;
601 /* start tx ing */ 594 /* start tx ing */
602 port->status |= (ISI_TXOK 595 port->status |= (ISI_TXOK
603 | ISI_CTS); 596 | ISI_CTS);
604 tty_wakeup(tty); 597 tty_wakeup(tty);
605 } 598 }
606 } else if (!(header & ISI_CTS)) { 599 } else if (!(header & ISI_CTS)) {
607 port->tty->hw_stopped = 1; 600 port->port.tty->hw_stopped = 1;
608 /* stop tx ing */ 601 /* stop tx ing */
609 port->status &= ~(ISI_TXOK | ISI_CTS); 602 port->status &= ~(ISI_TXOK | ISI_CTS);
610 } 603 }
@@ -629,7 +622,7 @@ static irqreturn_t isicom_interrupt(int irq, void *dev_id)
629 622
630 case 1: /* Received Break !!! */ 623 case 1: /* Received Break !!! */
631 tty_insert_flip_char(tty, 0, TTY_BREAK); 624 tty_insert_flip_char(tty, 0, TTY_BREAK);
632 if (port->flags & ASYNC_SAK) 625 if (port->port.flags & ASYNC_SAK)
633 do_SAK(tty); 626 do_SAK(tty);
634 tty_flip_buffer_push(tty); 627 tty_flip_buffer_push(tty);
635 break; 628 break;
@@ -681,7 +674,7 @@ static void isicom_config_port(struct isi_port *port)
681 shift_count = card->shift_count; 674 shift_count = card->shift_count;
682 unsigned char flow_ctrl; 675 unsigned char flow_ctrl;
683 676
684 tty = port->tty; 677 tty = port->port.tty;
685 678
686 if (tty == NULL) 679 if (tty == NULL)
687 return; 680 return;
@@ -697,7 +690,7 @@ static void isicom_config_port(struct isi_port *port)
697 690
698 /* 1,2,3,4 => 57.6, 115.2, 230, 460 kbps resp. */ 691 /* 1,2,3,4 => 57.6, 115.2, 230, 460 kbps resp. */
699 if (baud < 1 || baud > 4) 692 if (baud < 1 || baud > 4)
700 port->tty->termios->c_cflag &= ~CBAUDEX; 693 port->port.tty->termios->c_cflag &= ~CBAUDEX;
701 else 694 else
702 baud += 15; 695 baud += 15;
703 } 696 }
@@ -708,13 +701,13 @@ static void isicom_config_port(struct isi_port *port)
708 * the 'setserial' utility. 701 * the 'setserial' utility.
709 */ 702 */
710 703
711 if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) 704 if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
712 baud++; /* 57.6 Kbps */ 705 baud++; /* 57.6 Kbps */
713 if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) 706 if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
714 baud += 2; /* 115 Kbps */ 707 baud += 2; /* 115 Kbps */
715 if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) 708 if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
716 baud += 3; /* 230 kbps*/ 709 baud += 3; /* 230 kbps*/
717 if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) 710 if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
718 baud += 4; /* 460 kbps*/ 711 baud += 4; /* 460 kbps*/
719 } 712 }
720 if (linuxb_to_isib[baud] == -1) { 713 if (linuxb_to_isib[baud] == -1) {
@@ -754,15 +747,15 @@ static void isicom_config_port(struct isi_port *port)
754 InterruptTheCard(base); 747 InterruptTheCard(base);
755 } 748 }
756 if (C_CLOCAL(tty)) 749 if (C_CLOCAL(tty))
757 port->flags &= ~ASYNC_CHECK_CD; 750 port->port.flags &= ~ASYNC_CHECK_CD;
758 else 751 else
759 port->flags |= ASYNC_CHECK_CD; 752 port->port.flags |= ASYNC_CHECK_CD;
760 753
761 /* flow control settings ...*/ 754 /* flow control settings ...*/
762 flow_ctrl = 0; 755 flow_ctrl = 0;
763 port->flags &= ~ASYNC_CTS_FLOW; 756 port->port.flags &= ~ASYNC_CTS_FLOW;
764 if (C_CRTSCTS(tty)) { 757 if (C_CRTSCTS(tty)) {
765 port->flags |= ASYNC_CTS_FLOW; 758 port->port.flags |= ASYNC_CTS_FLOW;
766 flow_ctrl |= ISICOM_CTSRTS; 759 flow_ctrl |= ISICOM_CTSRTS;
767 } 760 }
768 if (I_IXON(tty)) 761 if (I_IXON(tty))
@@ -809,23 +802,15 @@ static int isicom_setup_port(struct isi_port *port)
809 struct isi_board *card = port->card; 802 struct isi_board *card = port->card;
810 unsigned long flags; 803 unsigned long flags;
811 804
812 if (port->flags & ASYNC_INITIALIZED) 805 if (port->port.flags & ASYNC_INITIALIZED)
813 return 0; 806 return 0;
814 if (!port->xmit_buf) { 807 if (tty_port_alloc_xmit_buf(&port->port) < 0)
815 /* Relies on BKL */ 808 return -ENOMEM;
816 unsigned long page = get_zeroed_page(GFP_KERNEL);
817 if (page == 0)
818 return -ENOMEM;
819 if (port->xmit_buf)
820 free_page(page);
821 else
822 port->xmit_buf = (unsigned char *) page;
823 }
824 809
825 spin_lock_irqsave(&card->card_lock, flags); 810 spin_lock_irqsave(&card->card_lock, flags);
826 if (port->tty) 811 if (port->port.tty)
827 clear_bit(TTY_IO_ERROR, &port->tty->flags); 812 clear_bit(TTY_IO_ERROR, &port->port.tty->flags);
828 if (port->count == 1) 813 if (port->port.count == 1)
829 card->count++; 814 card->count++;
830 815
831 port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; 816 port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
@@ -839,7 +824,7 @@ static int isicom_setup_port(struct isi_port *port)
839 } 824 }
840 825
841 isicom_config_port(port); 826 isicom_config_port(port);
842 port->flags |= ASYNC_INITIALIZED; 827 port->port.flags |= ASYNC_INITIALIZED;
843 spin_unlock_irqrestore(&card->card_lock, flags); 828 spin_unlock_irqrestore(&card->card_lock, flags);
844 829
845 return 0; 830 return 0;
@@ -855,10 +840,10 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
855 840
856 /* block if port is in the process of being closed */ 841 /* block if port is in the process of being closed */
857 842
858 if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) { 843 if (tty_hung_up_p(filp) || port->port.flags & ASYNC_CLOSING) {
859 pr_dbg("block_til_ready: close in progress.\n"); 844 pr_dbg("block_til_ready: close in progress.\n");
860 interruptible_sleep_on(&port->close_wait); 845 interruptible_sleep_on(&port->port.close_wait);
861 if (port->flags & ASYNC_HUP_NOTIFY) 846 if (port->port.flags & ASYNC_HUP_NOTIFY)
862 return -EAGAIN; 847 return -EAGAIN;
863 else 848 else
864 return -ERESTARTSYS; 849 return -ERESTARTSYS;
@@ -869,7 +854,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
869 if ((filp->f_flags & O_NONBLOCK) || 854 if ((filp->f_flags & O_NONBLOCK) ||
870 (tty->flags & (1 << TTY_IO_ERROR))) { 855 (tty->flags & (1 << TTY_IO_ERROR))) {
871 pr_dbg("block_til_ready: non-block mode.\n"); 856 pr_dbg("block_til_ready: non-block mode.\n");
872 port->flags |= ASYNC_NORMAL_ACTIVE; 857 port->port.flags |= ASYNC_NORMAL_ACTIVE;
873 return 0; 858 return 0;
874 } 859 }
875 860
@@ -879,26 +864,26 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
879 /* block waiting for DCD to be asserted, and while 864 /* block waiting for DCD to be asserted, and while
880 callout dev is busy */ 865 callout dev is busy */
881 retval = 0; 866 retval = 0;
882 add_wait_queue(&port->open_wait, &wait); 867 add_wait_queue(&port->port.open_wait, &wait);
883 868
884 spin_lock_irqsave(&card->card_lock, flags); 869 spin_lock_irqsave(&card->card_lock, flags);
885 if (!tty_hung_up_p(filp)) 870 if (!tty_hung_up_p(filp))
886 port->count--; 871 port->port.count--;
887 port->blocked_open++; 872 port->port.blocked_open++;
888 spin_unlock_irqrestore(&card->card_lock, flags); 873 spin_unlock_irqrestore(&card->card_lock, flags);
889 874
890 while (1) { 875 while (1) {
891 raise_dtr_rts(port); 876 raise_dtr_rts(port);
892 877
893 set_current_state(TASK_INTERRUPTIBLE); 878 set_current_state(TASK_INTERRUPTIBLE);
894 if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)) { 879 if (tty_hung_up_p(filp) || !(port->port.flags & ASYNC_INITIALIZED)) {
895 if (port->flags & ASYNC_HUP_NOTIFY) 880 if (port->port.flags & ASYNC_HUP_NOTIFY)
896 retval = -EAGAIN; 881 retval = -EAGAIN;
897 else 882 else
898 retval = -ERESTARTSYS; 883 retval = -ERESTARTSYS;
899 break; 884 break;
900 } 885 }
901 if (!(port->flags & ASYNC_CLOSING) && 886 if (!(port->port.flags & ASYNC_CLOSING) &&
902 (do_clocal || (port->status & ISI_DCD))) { 887 (do_clocal || (port->status & ISI_DCD))) {
903 break; 888 break;
904 } 889 }
@@ -909,15 +894,15 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
909 schedule(); 894 schedule();
910 } 895 }
911 set_current_state(TASK_RUNNING); 896 set_current_state(TASK_RUNNING);
912 remove_wait_queue(&port->open_wait, &wait); 897 remove_wait_queue(&port->port.open_wait, &wait);
913 spin_lock_irqsave(&card->card_lock, flags); 898 spin_lock_irqsave(&card->card_lock, flags);
914 if (!tty_hung_up_p(filp)) 899 if (!tty_hung_up_p(filp))
915 port->count++; 900 port->port.count++;
916 port->blocked_open--; 901 port->port.blocked_open--;
917 spin_unlock_irqrestore(&card->card_lock, flags); 902 spin_unlock_irqrestore(&card->card_lock, flags);
918 if (retval) 903 if (retval)
919 return retval; 904 return retval;
920 port->flags |= ASYNC_NORMAL_ACTIVE; 905 port->port.flags |= ASYNC_NORMAL_ACTIVE;
921 return 0; 906 return 0;
922} 907}
923 908
@@ -947,9 +932,9 @@ static int isicom_open(struct tty_struct *tty, struct file *filp)
947 932
948 isicom_setup_board(card); 933 isicom_setup_board(card);
949 934
950 port->count++; 935 port->port.count++;
951 tty->driver_data = port; 936 tty->driver_data = port;
952 port->tty = tty; 937 port->port.tty = tty;
953 error = isicom_setup_port(port); 938 error = isicom_setup_port(port);
954 if (error == 0) 939 if (error == 0)
955 error = block_til_ready(tty, filp, port); 940 error = block_til_ready(tty, filp, port);
@@ -970,18 +955,15 @@ static void isicom_shutdown_port(struct isi_port *port)
970 struct isi_board *card = port->card; 955 struct isi_board *card = port->card;
971 struct tty_struct *tty; 956 struct tty_struct *tty;
972 957
973 tty = port->tty; 958 tty = port->port.tty;
974 959
975 if (!(port->flags & ASYNC_INITIALIZED)) 960 if (!(port->port.flags & ASYNC_INITIALIZED))
976 return; 961 return;
977 962
978 if (port->xmit_buf) { 963 tty_port_free_xmit_buf(&port->port);
979 free_page((unsigned long) port->xmit_buf); 964 port->port.flags &= ~ASYNC_INITIALIZED;
980 port->xmit_buf = NULL;
981 }
982 port->flags &= ~ASYNC_INITIALIZED;
983 /* 3rd October 2000 : Vinayak P Risbud */ 965 /* 3rd October 2000 : Vinayak P Risbud */
984 port->tty = NULL; 966 port->port.tty = NULL;
985 967
986 /*Fix done by Anil .S on 30-04-2001 968 /*Fix done by Anil .S on 30-04-2001
987 remote login through isi port has dtr toggle problem 969 remote login through isi port has dtr toggle problem
@@ -1046,33 +1028,33 @@ static void isicom_close(struct tty_struct *tty, struct file *filp)
1046 return; 1028 return;
1047 } 1029 }
1048 1030
1049 if (tty->count == 1 && port->count != 1) { 1031 if (tty->count == 1 && port->port.count != 1) {
1050 printk(KERN_WARNING "ISICOM:(0x%lx) isicom_close: bad port " 1032 printk(KERN_WARNING "ISICOM:(0x%lx) isicom_close: bad port "
1051 "count tty->count = 1 port count = %d.\n", 1033 "count tty->count = 1 port count = %d.\n",
1052 card->base, port->count); 1034 card->base, port->port.count);
1053 port->count = 1; 1035 port->port.count = 1;
1054 } 1036 }
1055 if (--port->count < 0) { 1037 if (--port->port.count < 0) {
1056 printk(KERN_WARNING "ISICOM:(0x%lx) isicom_close: bad port " 1038 printk(KERN_WARNING "ISICOM:(0x%lx) isicom_close: bad port "
1057 "count for channel%d = %d", card->base, port->channel, 1039 "count for channel%d = %d", card->base, port->channel,
1058 port->count); 1040 port->port.count);
1059 port->count = 0; 1041 port->port.count = 0;
1060 } 1042 }
1061 1043
1062 if (port->count) { 1044 if (port->port.count) {
1063 spin_unlock_irqrestore(&card->card_lock, flags); 1045 spin_unlock_irqrestore(&card->card_lock, flags);
1064 return; 1046 return;
1065 } 1047 }
1066 port->flags |= ASYNC_CLOSING; 1048 port->port.flags |= ASYNC_CLOSING;
1067 tty->closing = 1; 1049 tty->closing = 1;
1068 spin_unlock_irqrestore(&card->card_lock, flags); 1050 spin_unlock_irqrestore(&card->card_lock, flags);
1069 1051
1070 if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE) 1052 if (port->port.closing_wait != ASYNC_CLOSING_WAIT_NONE)
1071 tty_wait_until_sent(tty, port->closing_wait); 1053 tty_wait_until_sent(tty, port->port.closing_wait);
1072 /* indicate to the card that no more data can be received 1054 /* indicate to the card that no more data can be received
1073 on this port */ 1055 on this port */
1074 spin_lock_irqsave(&card->card_lock, flags); 1056 spin_lock_irqsave(&card->card_lock, flags);
1075 if (port->flags & ASYNC_INITIALIZED) { 1057 if (port->port.flags & ASYNC_INITIALIZED) {
1076 card->port_status &= ~(1 << port->channel); 1058 card->port_status &= ~(1 << port->channel);
1077 outw(card->port_status, card->base + 0x02); 1059 outw(card->port_status, card->base + 0x02);
1078 } 1060 }
@@ -1085,18 +1067,18 @@ static void isicom_close(struct tty_struct *tty, struct file *filp)
1085 spin_lock_irqsave(&card->card_lock, flags); 1067 spin_lock_irqsave(&card->card_lock, flags);
1086 tty->closing = 0; 1068 tty->closing = 0;
1087 1069
1088 if (port->blocked_open) { 1070 if (port->port.blocked_open) {
1089 spin_unlock_irqrestore(&card->card_lock, flags); 1071 spin_unlock_irqrestore(&card->card_lock, flags);
1090 if (port->close_delay) { 1072 if (port->port.close_delay) {
1091 pr_dbg("scheduling until time out.\n"); 1073 pr_dbg("scheduling until time out.\n");
1092 msleep_interruptible( 1074 msleep_interruptible(
1093 jiffies_to_msecs(port->close_delay)); 1075 jiffies_to_msecs(port->port.close_delay));
1094 } 1076 }
1095 spin_lock_irqsave(&card->card_lock, flags); 1077 spin_lock_irqsave(&card->card_lock, flags);
1096 wake_up_interruptible(&port->open_wait); 1078 wake_up_interruptible(&port->port.open_wait);
1097 } 1079 }
1098 port->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING); 1080 port->port.flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
1099 wake_up_interruptible(&port->close_wait); 1081 wake_up_interruptible(&port->port.close_wait);
1100 spin_unlock_irqrestore(&card->card_lock, flags); 1082 spin_unlock_irqrestore(&card->card_lock, flags);
1101} 1083}
1102 1084
@@ -1112,9 +1094,6 @@ static int isicom_write(struct tty_struct *tty, const unsigned char *buf,
1112 if (isicom_paranoia_check(port, tty->name, "isicom_write")) 1094 if (isicom_paranoia_check(port, tty->name, "isicom_write"))
1113 return 0; 1095 return 0;
1114 1096
1115 if (!port->xmit_buf)
1116 return 0;
1117
1118 spin_lock_irqsave(&card->card_lock, flags); 1097 spin_lock_irqsave(&card->card_lock, flags);
1119 1098
1120 while (1) { 1099 while (1) {
@@ -1123,7 +1102,7 @@ static int isicom_write(struct tty_struct *tty, const unsigned char *buf,
1123 if (cnt <= 0) 1102 if (cnt <= 0)
1124 break; 1103 break;
1125 1104
1126 memcpy(port->xmit_buf + port->xmit_head, buf, cnt); 1105 memcpy(port->port.xmit_buf + port->xmit_head, buf, cnt);
1127 port->xmit_head = (port->xmit_head + cnt) & (SERIAL_XMIT_SIZE 1106 port->xmit_head = (port->xmit_head + cnt) & (SERIAL_XMIT_SIZE
1128 - 1); 1107 - 1);
1129 port->xmit_cnt += cnt; 1108 port->xmit_cnt += cnt;
@@ -1147,16 +1126,13 @@ static int isicom_put_char(struct tty_struct *tty, unsigned char ch)
1147 if (isicom_paranoia_check(port, tty->name, "isicom_put_char")) 1126 if (isicom_paranoia_check(port, tty->name, "isicom_put_char"))
1148 return 0; 1127 return 0;
1149 1128
1150 if (!port->xmit_buf)
1151 return 0;
1152
1153 spin_lock_irqsave(&card->card_lock, flags); 1129 spin_lock_irqsave(&card->card_lock, flags);
1154 if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) { 1130 if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) {
1155 spin_unlock_irqrestore(&card->card_lock, flags); 1131 spin_unlock_irqrestore(&card->card_lock, flags);
1156 return 0; 1132 return 0;
1157 } 1133 }
1158 1134
1159 port->xmit_buf[port->xmit_head++] = ch; 1135 port->port.xmit_buf[port->xmit_head++] = ch;
1160 port->xmit_head &= (SERIAL_XMIT_SIZE - 1); 1136 port->xmit_head &= (SERIAL_XMIT_SIZE - 1);
1161 port->xmit_cnt++; 1137 port->xmit_cnt++;
1162 spin_unlock_irqrestore(&card->card_lock, flags); 1138 spin_unlock_irqrestore(&card->card_lock, flags);
@@ -1172,7 +1148,7 @@ static void isicom_flush_chars(struct tty_struct *tty)
1172 return; 1148 return;
1173 1149
1174 if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || 1150 if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped ||
1175 !port->xmit_buf) 1151 !port->port.xmit_buf)
1176 return; 1152 return;
1177 1153
1178 /* this tells the transmitter to consider this port for 1154 /* this tells the transmitter to consider this port for
@@ -1274,23 +1250,23 @@ static int isicom_set_serial_info(struct isi_port *port,
1274 1250
1275 lock_kernel(); 1251 lock_kernel();
1276 1252
1277 reconfig_port = ((port->flags & ASYNC_SPD_MASK) != 1253 reconfig_port = ((port->port.flags & ASYNC_SPD_MASK) !=
1278 (newinfo.flags & ASYNC_SPD_MASK)); 1254 (newinfo.flags & ASYNC_SPD_MASK));
1279 1255
1280 if (!capable(CAP_SYS_ADMIN)) { 1256 if (!capable(CAP_SYS_ADMIN)) {
1281 if ((newinfo.close_delay != port->close_delay) || 1257 if ((newinfo.close_delay != port->port.close_delay) ||
1282 (newinfo.closing_wait != port->closing_wait) || 1258 (newinfo.closing_wait != port->port.closing_wait) ||
1283 ((newinfo.flags & ~ASYNC_USR_MASK) != 1259 ((newinfo.flags & ~ASYNC_USR_MASK) !=
1284 (port->flags & ~ASYNC_USR_MASK))) { 1260 (port->port.flags & ~ASYNC_USR_MASK))) {
1285 unlock_kernel(); 1261 unlock_kernel();
1286 return -EPERM; 1262 return -EPERM;
1287 } 1263 }
1288 port->flags = ((port->flags & ~ASYNC_USR_MASK) | 1264 port->port.flags = ((port->port.flags & ~ASYNC_USR_MASK) |
1289 (newinfo.flags & ASYNC_USR_MASK)); 1265 (newinfo.flags & ASYNC_USR_MASK));
1290 } else { 1266 } else {
1291 port->close_delay = newinfo.close_delay; 1267 port->port.close_delay = newinfo.close_delay;
1292 port->closing_wait = newinfo.closing_wait; 1268 port->port.closing_wait = newinfo.closing_wait;
1293 port->flags = ((port->flags & ~ASYNC_FLAGS) | 1269 port->port.flags = ((port->port.flags & ~ASYNC_FLAGS) |
1294 (newinfo.flags & ASYNC_FLAGS)); 1270 (newinfo.flags & ASYNC_FLAGS));
1295 } 1271 }
1296 if (reconfig_port) { 1272 if (reconfig_port) {
@@ -1314,10 +1290,10 @@ static int isicom_get_serial_info(struct isi_port *port,
1314 out_info.line = port - isi_ports; 1290 out_info.line = port - isi_ports;
1315 out_info.port = port->card->base; 1291 out_info.port = port->card->base;
1316 out_info.irq = port->card->irq; 1292 out_info.irq = port->card->irq;
1317 out_info.flags = port->flags; 1293 out_info.flags = port->port.flags;
1318/* out_info.baud_base = ? */ 1294/* out_info.baud_base = ? */
1319 out_info.close_delay = port->close_delay; 1295 out_info.close_delay = port->port.close_delay;
1320 out_info.closing_wait = port->closing_wait; 1296 out_info.closing_wait = port->port.closing_wait;
1321 unlock_kernel(); 1297 unlock_kernel();
1322 if (copy_to_user(info, &out_info, sizeof(out_info))) 1298 if (copy_to_user(info, &out_info, sizeof(out_info)))
1323 return -EFAULT; 1299 return -EFAULT;
@@ -1454,10 +1430,10 @@ static void isicom_hangup(struct tty_struct *tty)
1454 isicom_shutdown_port(port); 1430 isicom_shutdown_port(port);
1455 spin_unlock_irqrestore(&port->card->card_lock, flags); 1431 spin_unlock_irqrestore(&port->card->card_lock, flags);
1456 1432
1457 port->count = 0; 1433 port->port.count = 0;
1458 port->flags &= ~ASYNC_NORMAL_ACTIVE; 1434 port->port.flags &= ~ASYNC_NORMAL_ACTIVE;
1459 port->tty = NULL; 1435 port->port.tty = NULL;
1460 wake_up_interruptible(&port->open_wait); 1436 wake_up_interruptible(&port->port.open_wait);
1461} 1437}
1462 1438
1463 1439
@@ -1736,6 +1712,12 @@ static int __devinit isicom_probe(struct pci_dev *pdev,
1736 if (card_count >= BOARD_COUNT) 1712 if (card_count >= BOARD_COUNT)
1737 goto err; 1713 goto err;
1738 1714
1715 retval = pci_enable_device(pdev);
1716 if (retval) {
1717 dev_err(&pdev->dev, "failed to enable\n");
1718 goto err;
1719 }
1720
1739 dev_info(&pdev->dev, "ISI PCI Card(Device ID 0x%x)\n", ent->device); 1721 dev_info(&pdev->dev, "ISI PCI Card(Device ID 0x%x)\n", ent->device);
1740 1722
1741 /* allot the first empty slot in the array */ 1723 /* allot the first empty slot in the array */
@@ -1790,6 +1772,7 @@ errunrr:
1790errdec: 1772errdec:
1791 board->base = 0; 1773 board->base = 0;
1792 card_count--; 1774 card_count--;
1775 pci_disable_device(pdev);
1793err: 1776err:
1794 return retval; 1777 return retval;
1795} 1778}
@@ -1806,6 +1789,7 @@ static void __devexit isicom_remove(struct pci_dev *pdev)
1806 pci_release_region(pdev, 3); 1789 pci_release_region(pdev, 3);
1807 board->base = 0; 1790 board->base = 0;
1808 card_count--; 1791 card_count--;
1792 pci_disable_device(pdev);
1809} 1793}
1810 1794
1811static int __init isicom_init(void) 1795static int __init isicom_init(void)
@@ -1818,14 +1802,13 @@ static int __init isicom_init(void)
1818 isi_card[idx].ports = port; 1802 isi_card[idx].ports = port;
1819 spin_lock_init(&isi_card[idx].card_lock); 1803 spin_lock_init(&isi_card[idx].card_lock);
1820 for (channel = 0; channel < 16; channel++, port++) { 1804 for (channel = 0; channel < 16; channel++, port++) {
1805 tty_port_init(&port->port);
1821 port->magic = ISICOM_MAGIC; 1806 port->magic = ISICOM_MAGIC;
1822 port->card = &isi_card[idx]; 1807 port->card = &isi_card[idx];
1823 port->channel = channel; 1808 port->channel = channel;
1824 port->close_delay = 50 * HZ/100; 1809 port->port.close_delay = 50 * HZ/100;
1825 port->closing_wait = 3000 * HZ/100; 1810 port->port.closing_wait = 3000 * HZ/100;
1826 port->status = 0; 1811 port->status = 0;
1827 init_waitqueue_head(&port->open_wait);
1828 init_waitqueue_head(&port->close_wait);
1829 /* . . . */ 1812 /* . . . */
1830 } 1813 }
1831 isi_card[idx].base = 0; 1814 isi_card[idx].base = 0;
diff --git a/drivers/char/istallion.c b/drivers/char/istallion.c
index 7c8b62f162bf..6ef1c565705c 100644
--- a/drivers/char/istallion.c
+++ b/drivers/char/istallion.c
@@ -735,8 +735,8 @@ static void stli_cleanup_ports(struct stlibrd *brdp)
735 for (j = 0; j < STL_MAXPORTS; j++) { 735 for (j = 0; j < STL_MAXPORTS; j++) {
736 portp = brdp->ports[j]; 736 portp = brdp->ports[j];
737 if (portp != NULL) { 737 if (portp != NULL) {
738 if (portp->tty != NULL) 738 if (portp->port.tty != NULL)
739 tty_hangup(portp->tty); 739 tty_hangup(portp->port.tty);
740 kfree(portp); 740 kfree(portp);
741 } 741 }
742 } 742 }
@@ -811,9 +811,9 @@ static int stli_open(struct tty_struct *tty, struct file *filp)
811 * The sleep here does not need interrupt protection since the wakeup 811 * The sleep here does not need interrupt protection since the wakeup
812 * for it is done with the same context. 812 * for it is done with the same context.
813 */ 813 */
814 if (portp->flags & ASYNC_CLOSING) { 814 if (portp->port.flags & ASYNC_CLOSING) {
815 interruptible_sleep_on(&portp->close_wait); 815 interruptible_sleep_on(&portp->port.close_wait);
816 if (portp->flags & ASYNC_HUP_NOTIFY) 816 if (portp->port.flags & ASYNC_HUP_NOTIFY)
817 return -EAGAIN; 817 return -EAGAIN;
818 return -ERESTARTSYS; 818 return -ERESTARTSYS;
819 } 819 }
@@ -824,7 +824,7 @@ static int stli_open(struct tty_struct *tty, struct file *filp)
824 * requires several commands to the board we will need to wait for any 824 * requires several commands to the board we will need to wait for any
825 * other open that is already initializing the port. 825 * other open that is already initializing the port.
826 */ 826 */
827 portp->tty = tty; 827 portp->port.tty = tty;
828 tty->driver_data = portp; 828 tty->driver_data = portp;
829 portp->refcount++; 829 portp->refcount++;
830 830
@@ -833,10 +833,10 @@ static int stli_open(struct tty_struct *tty, struct file *filp)
833 if (signal_pending(current)) 833 if (signal_pending(current))
834 return -ERESTARTSYS; 834 return -ERESTARTSYS;
835 835
836 if ((portp->flags & ASYNC_INITIALIZED) == 0) { 836 if ((portp->port.flags & ASYNC_INITIALIZED) == 0) {
837 set_bit(ST_INITIALIZING, &portp->state); 837 set_bit(ST_INITIALIZING, &portp->state);
838 if ((rc = stli_initopen(brdp, portp)) >= 0) { 838 if ((rc = stli_initopen(brdp, portp)) >= 0) {
839 portp->flags |= ASYNC_INITIALIZED; 839 portp->port.flags |= ASYNC_INITIALIZED;
840 clear_bit(TTY_IO_ERROR, &tty->flags); 840 clear_bit(TTY_IO_ERROR, &tty->flags);
841 } 841 }
842 clear_bit(ST_INITIALIZING, &portp->state); 842 clear_bit(ST_INITIALIZING, &portp->state);
@@ -851,9 +851,9 @@ static int stli_open(struct tty_struct *tty, struct file *filp)
851 * The sleep here does not need interrupt protection since the wakeup 851 * The sleep here does not need interrupt protection since the wakeup
852 * for it is done with the same context. 852 * for it is done with the same context.
853 */ 853 */
854 if (portp->flags & ASYNC_CLOSING) { 854 if (portp->port.flags & ASYNC_CLOSING) {
855 interruptible_sleep_on(&portp->close_wait); 855 interruptible_sleep_on(&portp->port.close_wait);
856 if (portp->flags & ASYNC_HUP_NOTIFY) 856 if (portp->port.flags & ASYNC_HUP_NOTIFY)
857 return -EAGAIN; 857 return -EAGAIN;
858 return -ERESTARTSYS; 858 return -ERESTARTSYS;
859 } 859 }
@@ -867,7 +867,7 @@ static int stli_open(struct tty_struct *tty, struct file *filp)
867 if ((rc = stli_waitcarrier(brdp, portp, filp)) != 0) 867 if ((rc = stli_waitcarrier(brdp, portp, filp)) != 0)
868 return rc; 868 return rc;
869 } 869 }
870 portp->flags |= ASYNC_NORMAL_ACTIVE; 870 portp->port.flags |= ASYNC_NORMAL_ACTIVE;
871 return 0; 871 return 0;
872} 872}
873 873
@@ -895,7 +895,7 @@ static void stli_close(struct tty_struct *tty, struct file *filp)
895 return; 895 return;
896 } 896 }
897 897
898 portp->flags |= ASYNC_CLOSING; 898 portp->port.flags |= ASYNC_CLOSING;
899 899
900/* 900/*
901 * May want to wait for data to drain before closing. The BUSY flag 901 * May want to wait for data to drain before closing. The BUSY flag
@@ -911,7 +911,7 @@ static void stli_close(struct tty_struct *tty, struct file *filp)
911 if (portp->closing_wait != ASYNC_CLOSING_WAIT_NONE) 911 if (portp->closing_wait != ASYNC_CLOSING_WAIT_NONE)
912 tty_wait_until_sent(tty, portp->closing_wait); 912 tty_wait_until_sent(tty, portp->closing_wait);
913 913
914 portp->flags &= ~ASYNC_INITIALIZED; 914 portp->port.flags &= ~ASYNC_INITIALIZED;
915 brdp = stli_brds[portp->brdnr]; 915 brdp = stli_brds[portp->brdnr];
916 stli_rawclose(brdp, portp, 0, 0); 916 stli_rawclose(brdp, portp, 0, 0);
917 if (tty->termios->c_cflag & HUPCL) { 917 if (tty->termios->c_cflag & HUPCL) {
@@ -931,16 +931,16 @@ static void stli_close(struct tty_struct *tty, struct file *filp)
931 stli_flushbuffer(tty); 931 stli_flushbuffer(tty);
932 932
933 tty->closing = 0; 933 tty->closing = 0;
934 portp->tty = NULL; 934 portp->port.tty = NULL;
935 935
936 if (portp->openwaitcnt) { 936 if (portp->openwaitcnt) {
937 if (portp->close_delay) 937 if (portp->close_delay)
938 msleep_interruptible(jiffies_to_msecs(portp->close_delay)); 938 msleep_interruptible(jiffies_to_msecs(portp->close_delay));
939 wake_up_interruptible(&portp->open_wait); 939 wake_up_interruptible(&portp->port.open_wait);
940 } 940 }
941 941
942 portp->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); 942 portp->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
943 wake_up_interruptible(&portp->close_wait); 943 wake_up_interruptible(&portp->port.close_wait);
944} 944}
945 945
946/*****************************************************************************/ 946/*****************************************************************************/
@@ -970,7 +970,7 @@ static int stli_initopen(struct stlibrd *brdp, struct stliport *portp)
970 sizeof(asynotify_t), 0)) < 0) 970 sizeof(asynotify_t), 0)) < 0)
971 return rc; 971 return rc;
972 972
973 tty = portp->tty; 973 tty = portp->port.tty;
974 if (tty == NULL) 974 if (tty == NULL)
975 return -ENODEV; 975 return -ENODEV;
976 stli_mkasyport(portp, &aport, tty->termios); 976 stli_mkasyport(portp, &aport, tty->termios);
@@ -1169,7 +1169,7 @@ static int stli_setport(struct stliport *portp)
1169 1169
1170 if (portp == NULL) 1170 if (portp == NULL)
1171 return -ENODEV; 1171 return -ENODEV;
1172 if (portp->tty == NULL) 1172 if (portp->port.tty == NULL)
1173 return -ENODEV; 1173 return -ENODEV;
1174 if (portp->brdnr >= stli_nrbrds) 1174 if (portp->brdnr >= stli_nrbrds)
1175 return -ENODEV; 1175 return -ENODEV;
@@ -1177,7 +1177,7 @@ static int stli_setport(struct stliport *portp)
1177 if (brdp == NULL) 1177 if (brdp == NULL)
1178 return -ENODEV; 1178 return -ENODEV;
1179 1179
1180 stli_mkasyport(portp, &aport, portp->tty->termios); 1180 stli_mkasyport(portp, &aport, portp->port.tty->termios);
1181 return(stli_cmdwait(brdp, portp, A_SETPORT, &aport, sizeof(asyport_t), 0)); 1181 return(stli_cmdwait(brdp, portp, A_SETPORT, &aport, sizeof(asyport_t), 0));
1182} 1182}
1183 1183
@@ -1196,7 +1196,7 @@ static int stli_waitcarrier(struct stlibrd *brdp, struct stliport *portp, struct
1196 rc = 0; 1196 rc = 0;
1197 doclocal = 0; 1197 doclocal = 0;
1198 1198
1199 if (portp->tty->termios->c_cflag & CLOCAL) 1199 if (portp->port.tty->termios->c_cflag & CLOCAL)
1200 doclocal++; 1200 doclocal++;
1201 1201
1202 spin_lock_irqsave(&stli_lock, flags); 1202 spin_lock_irqsave(&stli_lock, flags);
@@ -1211,14 +1211,14 @@ static int stli_waitcarrier(struct stlibrd *brdp, struct stliport *portp, struct
1211 &portp->asig, sizeof(asysigs_t), 0)) < 0) 1211 &portp->asig, sizeof(asysigs_t), 0)) < 0)
1212 break; 1212 break;
1213 if (tty_hung_up_p(filp) || 1213 if (tty_hung_up_p(filp) ||
1214 ((portp->flags & ASYNC_INITIALIZED) == 0)) { 1214 ((portp->port.flags & ASYNC_INITIALIZED) == 0)) {
1215 if (portp->flags & ASYNC_HUP_NOTIFY) 1215 if (portp->port.flags & ASYNC_HUP_NOTIFY)
1216 rc = -EBUSY; 1216 rc = -EBUSY;
1217 else 1217 else
1218 rc = -ERESTARTSYS; 1218 rc = -ERESTARTSYS;
1219 break; 1219 break;
1220 } 1220 }
1221 if (((portp->flags & ASYNC_CLOSING) == 0) && 1221 if (((portp->port.flags & ASYNC_CLOSING) == 0) &&
1222 (doclocal || (portp->sigs & TIOCM_CD))) { 1222 (doclocal || (portp->sigs & TIOCM_CD))) {
1223 break; 1223 break;
1224 } 1224 }
@@ -1226,7 +1226,7 @@ static int stli_waitcarrier(struct stlibrd *brdp, struct stliport *portp, struct
1226 rc = -ERESTARTSYS; 1226 rc = -ERESTARTSYS;
1227 break; 1227 break;
1228 } 1228 }
1229 interruptible_sleep_on(&portp->open_wait); 1229 interruptible_sleep_on(&portp->port.open_wait);
1230 } 1230 }
1231 1231
1232 spin_lock_irqsave(&stli_lock, flags); 1232 spin_lock_irqsave(&stli_lock, flags);
@@ -1548,7 +1548,7 @@ static int stli_getserial(struct stliport *portp, struct serial_struct __user *s
1548 sio.type = PORT_UNKNOWN; 1548 sio.type = PORT_UNKNOWN;
1549 sio.line = portp->portnr; 1549 sio.line = portp->portnr;
1550 sio.irq = 0; 1550 sio.irq = 0;
1551 sio.flags = portp->flags; 1551 sio.flags = portp->port.flags;
1552 sio.baud_base = portp->baud_base; 1552 sio.baud_base = portp->baud_base;
1553 sio.close_delay = portp->close_delay; 1553 sio.close_delay = portp->close_delay;
1554 sio.closing_wait = portp->closing_wait; 1554 sio.closing_wait = portp->closing_wait;
@@ -1583,11 +1583,11 @@ static int stli_setserial(struct stliport *portp, struct serial_struct __user *s
1583 if ((sio.baud_base != portp->baud_base) || 1583 if ((sio.baud_base != portp->baud_base) ||
1584 (sio.close_delay != portp->close_delay) || 1584 (sio.close_delay != portp->close_delay) ||
1585 ((sio.flags & ~ASYNC_USR_MASK) != 1585 ((sio.flags & ~ASYNC_USR_MASK) !=
1586 (portp->flags & ~ASYNC_USR_MASK))) 1586 (portp->port.flags & ~ASYNC_USR_MASK)))
1587 return -EPERM; 1587 return -EPERM;
1588 } 1588 }
1589 1589
1590 portp->flags = (portp->flags & ~ASYNC_USR_MASK) | 1590 portp->port.flags = (portp->port.flags & ~ASYNC_USR_MASK) |
1591 (sio.flags & ASYNC_USR_MASK); 1591 (sio.flags & ASYNC_USR_MASK);
1592 portp->baud_base = sio.baud_base; 1592 portp->baud_base = sio.baud_base;
1593 portp->close_delay = sio.close_delay; 1593 portp->close_delay = sio.close_delay;
@@ -1751,7 +1751,7 @@ static void stli_settermios(struct tty_struct *tty, struct ktermios *old)
1751 if ((old->c_cflag & CRTSCTS) && ((tiosp->c_cflag & CRTSCTS) == 0)) 1751 if ((old->c_cflag & CRTSCTS) && ((tiosp->c_cflag & CRTSCTS) == 0))
1752 tty->hw_stopped = 0; 1752 tty->hw_stopped = 0;
1753 if (((old->c_cflag & CLOCAL) == 0) && (tiosp->c_cflag & CLOCAL)) 1753 if (((old->c_cflag & CLOCAL) == 0) && (tiosp->c_cflag & CLOCAL))
1754 wake_up_interruptible(&portp->open_wait); 1754 wake_up_interruptible(&portp->port.open_wait);
1755} 1755}
1756 1756
1757/*****************************************************************************/ 1757/*****************************************************************************/
@@ -1834,7 +1834,7 @@ static void stli_hangup(struct tty_struct *tty)
1834 if (brdp == NULL) 1834 if (brdp == NULL)
1835 return; 1835 return;
1836 1836
1837 portp->flags &= ~ASYNC_INITIALIZED; 1837 portp->port.flags &= ~ASYNC_INITIALIZED;
1838 1838
1839 if (!test_bit(ST_CLOSING, &portp->state)) 1839 if (!test_bit(ST_CLOSING, &portp->state))
1840 stli_rawclose(brdp, portp, 0, 0); 1840 stli_rawclose(brdp, portp, 0, 0);
@@ -1855,12 +1855,12 @@ static void stli_hangup(struct tty_struct *tty)
1855 clear_bit(ST_TXBUSY, &portp->state); 1855 clear_bit(ST_TXBUSY, &portp->state);
1856 clear_bit(ST_RXSTOP, &portp->state); 1856 clear_bit(ST_RXSTOP, &portp->state);
1857 set_bit(TTY_IO_ERROR, &tty->flags); 1857 set_bit(TTY_IO_ERROR, &tty->flags);
1858 portp->tty = NULL; 1858 portp->port.tty = NULL;
1859 portp->flags &= ~ASYNC_NORMAL_ACTIVE; 1859 portp->port.flags &= ~ASYNC_NORMAL_ACTIVE;
1860 portp->refcount = 0; 1860 portp->refcount = 0;
1861 spin_unlock_irqrestore(&stli_lock, flags); 1861 spin_unlock_irqrestore(&stli_lock, flags);
1862 1862
1863 wake_up_interruptible(&portp->open_wait); 1863 wake_up_interruptible(&portp->port.open_wait);
1864} 1864}
1865 1865
1866/*****************************************************************************/ 1866/*****************************************************************************/
@@ -2188,7 +2188,7 @@ static void stli_read(struct stlibrd *brdp, struct stliport *portp)
2188 2188
2189 if (test_bit(ST_RXSTOP, &portp->state)) 2189 if (test_bit(ST_RXSTOP, &portp->state))
2190 return; 2190 return;
2191 tty = portp->tty; 2191 tty = portp->port.tty;
2192 if (tty == NULL) 2192 if (tty == NULL)
2193 return; 2193 return;
2194 2194
@@ -2362,7 +2362,7 @@ static int stli_hostcmd(struct stlibrd *brdp, struct stliport *portp)
2362 if (ap->notify) { 2362 if (ap->notify) {
2363 nt = ap->changed; 2363 nt = ap->changed;
2364 ap->notify = 0; 2364 ap->notify = 0;
2365 tty = portp->tty; 2365 tty = portp->port.tty;
2366 2366
2367 if (nt.signal & SG_DCD) { 2367 if (nt.signal & SG_DCD) {
2368 oldsigs = portp->sigs; 2368 oldsigs = portp->sigs;
@@ -2370,10 +2370,10 @@ static int stli_hostcmd(struct stlibrd *brdp, struct stliport *portp)
2370 clear_bit(ST_GETSIGS, &portp->state); 2370 clear_bit(ST_GETSIGS, &portp->state);
2371 if ((portp->sigs & TIOCM_CD) && 2371 if ((portp->sigs & TIOCM_CD) &&
2372 ((oldsigs & TIOCM_CD) == 0)) 2372 ((oldsigs & TIOCM_CD) == 0))
2373 wake_up_interruptible(&portp->open_wait); 2373 wake_up_interruptible(&portp->port.open_wait);
2374 if ((oldsigs & TIOCM_CD) && 2374 if ((oldsigs & TIOCM_CD) &&
2375 ((portp->sigs & TIOCM_CD) == 0)) { 2375 ((portp->sigs & TIOCM_CD) == 0)) {
2376 if (portp->flags & ASYNC_CHECK_CD) { 2376 if (portp->port.flags & ASYNC_CHECK_CD) {
2377 if (tty) 2377 if (tty)
2378 tty_hangup(tty); 2378 tty_hangup(tty);
2379 } 2379 }
@@ -2392,7 +2392,7 @@ static int stli_hostcmd(struct stlibrd *brdp, struct stliport *portp)
2392 if ((nt.data & DT_RXBREAK) && (portp->rxmarkmsk & BRKINT)) { 2392 if ((nt.data & DT_RXBREAK) && (portp->rxmarkmsk & BRKINT)) {
2393 if (tty != NULL) { 2393 if (tty != NULL) {
2394 tty_insert_flip_char(tty, 0, TTY_BREAK); 2394 tty_insert_flip_char(tty, 0, TTY_BREAK);
2395 if (portp->flags & ASYNC_SAK) { 2395 if (portp->port.flags & ASYNC_SAK) {
2396 do_SAK(tty); 2396 do_SAK(tty);
2397 EBRDENABLE(brdp); 2397 EBRDENABLE(brdp);
2398 } 2398 }
@@ -2542,17 +2542,17 @@ static void stli_mkasyport(struct stliport *portp, asyport_t *pp, struct ktermio
2542/* 2542/*
2543 * Start of by setting the baud, char size, parity and stop bit info. 2543 * Start of by setting the baud, char size, parity and stop bit info.
2544 */ 2544 */
2545 pp->baudout = tty_get_baud_rate(portp->tty); 2545 pp->baudout = tty_get_baud_rate(portp->port.tty);
2546 if ((tiosp->c_cflag & CBAUD) == B38400) { 2546 if ((tiosp->c_cflag & CBAUD) == B38400) {
2547 if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) 2547 if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
2548 pp->baudout = 57600; 2548 pp->baudout = 57600;
2549 else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) 2549 else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
2550 pp->baudout = 115200; 2550 pp->baudout = 115200;
2551 else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) 2551 else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
2552 pp->baudout = 230400; 2552 pp->baudout = 230400;
2553 else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) 2553 else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
2554 pp->baudout = 460800; 2554 pp->baudout = 460800;
2555 else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) 2555 else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)
2556 pp->baudout = (portp->baud_base / portp->custom_divisor); 2556 pp->baudout = (portp->baud_base / portp->custom_divisor);
2557 } 2557 }
2558 if (pp->baudout > STL_MAXBAUD) 2558 if (pp->baudout > STL_MAXBAUD)
@@ -2625,9 +2625,9 @@ static void stli_mkasyport(struct stliport *portp, asyport_t *pp, struct ktermio
2625 * Set up clocal processing as required. 2625 * Set up clocal processing as required.
2626 */ 2626 */
2627 if (tiosp->c_cflag & CLOCAL) 2627 if (tiosp->c_cflag & CLOCAL)
2628 portp->flags &= ~ASYNC_CHECK_CD; 2628 portp->port.flags &= ~ASYNC_CHECK_CD;
2629 else 2629 else
2630 portp->flags |= ASYNC_CHECK_CD; 2630 portp->port.flags |= ASYNC_CHECK_CD;
2631 2631
2632/* 2632/*
2633 * Transfer any persistent flags into the asyport structure. 2633 * Transfer any persistent flags into the asyport structure.
@@ -2703,8 +2703,8 @@ static int stli_initports(struct stlibrd *brdp)
2703 portp->baud_base = STL_BAUDBASE; 2703 portp->baud_base = STL_BAUDBASE;
2704 portp->close_delay = STL_CLOSEDELAY; 2704 portp->close_delay = STL_CLOSEDELAY;
2705 portp->closing_wait = 30 * HZ; 2705 portp->closing_wait = 30 * HZ;
2706 init_waitqueue_head(&portp->open_wait); 2706 init_waitqueue_head(&portp->port.open_wait);
2707 init_waitqueue_head(&portp->close_wait); 2707 init_waitqueue_head(&portp->port.close_wait);
2708 init_waitqueue_head(&portp->raw_wait); 2708 init_waitqueue_head(&portp->raw_wait);
2709 panelport++; 2709 panelport++;
2710 if (panelport >= brdp->panels[panelnr]) { 2710 if (panelport >= brdp->panels[panelnr]) {
@@ -4246,18 +4246,18 @@ static int stli_portcmdstats(struct stliport *portp)
4246 stli_comstats.panel = portp->panelnr; 4246 stli_comstats.panel = portp->panelnr;
4247 stli_comstats.port = portp->portnr; 4247 stli_comstats.port = portp->portnr;
4248 stli_comstats.state = portp->state; 4248 stli_comstats.state = portp->state;
4249 stli_comstats.flags = portp->flags; 4249 stli_comstats.flags = portp->port.flag;
4250 4250
4251 spin_lock_irqsave(&brd_lock, flags); 4251 spin_lock_irqsave(&brd_lock, flags);
4252 if (portp->tty != NULL) { 4252 if (portp->port.tty != NULL) {
4253 if (portp->tty->driver_data == portp) { 4253 if (portp->port.tty->driver_data == portp) {
4254 stli_comstats.ttystate = portp->tty->flags; 4254 stli_comstats.ttystate = portp->port.tty->flags;
4255 stli_comstats.rxbuffered = -1; 4255 stli_comstats.rxbuffered = -1;
4256 if (portp->tty->termios != NULL) { 4256 if (portp->port.tty->termios != NULL) {
4257 stli_comstats.cflags = portp->tty->termios->c_cflag; 4257 stli_comstats.cflags = portp->port.tty->termios->c_cflag;
4258 stli_comstats.iflags = portp->tty->termios->c_iflag; 4258 stli_comstats.iflags = portp->port.tty->termios->c_iflag;
4259 stli_comstats.oflags = portp->tty->termios->c_oflag; 4259 stli_comstats.oflags = portp->port.tty->termios->c_oflag;
4260 stli_comstats.lflags = portp->tty->termios->c_lflag; 4260 stli_comstats.lflags = portp->port.tty->termios->c_lflag;
4261 } 4261 }
4262 } 4262 }
4263 } 4263 }
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c
index d0369e05490a..7b3a212c86b1 100644
--- a/drivers/char/keyboard.c
+++ b/drivers/char/keyboard.c
@@ -679,12 +679,7 @@ static void k_deadunicode(struct vc_data *vc, unsigned int value, char up_flag)
679 679
680static void k_self(struct vc_data *vc, unsigned char value, char up_flag) 680static void k_self(struct vc_data *vc, unsigned char value, char up_flag)
681{ 681{
682 unsigned int uni; 682 k_unicode(vc, conv_8bit_to_uni(value), up_flag);
683 if (kbd->kbdmode == VC_UNICODE)
684 uni = value;
685 else
686 uni = conv_8bit_to_uni(value);
687 k_unicode(vc, uni, up_flag);
688} 683}
689 684
690static void k_dead2(struct vc_data *vc, unsigned char value, char up_flag) 685static void k_dead2(struct vc_data *vc, unsigned char value, char up_flag)
diff --git a/drivers/char/lcd.c b/drivers/char/lcd.c
index 4fe9206f84de..1c29b20e4f4c 100644
--- a/drivers/char/lcd.c
+++ b/drivers/char/lcd.c
@@ -20,6 +20,7 @@
20#include <linux/mc146818rtc.h> 20#include <linux/mc146818rtc.h>
21#include <linux/netdevice.h> 21#include <linux/netdevice.h>
22#include <linux/sched.h> 22#include <linux/sched.h>
23#include <linux/smp_lock.h>
23#include <linux/delay.h> 24#include <linux/delay.h>
24 25
25#include <asm/io.h> 26#include <asm/io.h>
@@ -414,6 +415,8 @@ static int lcd_ioctl(struct inode *inode, struct file *file,
414 415
415static int lcd_open(struct inode *inode, struct file *file) 416static int lcd_open(struct inode *inode, struct file *file)
416{ 417{
418 cycle_kernel_lock();
419
417 if (!lcd_present) 420 if (!lcd_present)
418 return -ENXIO; 421 return -ENXIO;
419 else 422 else
diff --git a/drivers/char/lp.c b/drivers/char/lp.c
index 60ac642752be..71abb4c33aa2 100644
--- a/drivers/char/lp.c
+++ b/drivers/char/lp.c
@@ -126,6 +126,7 @@
126#include <linux/device.h> 126#include <linux/device.h>
127#include <linux/wait.h> 127#include <linux/wait.h>
128#include <linux/jiffies.h> 128#include <linux/jiffies.h>
129#include <linux/smp_lock.h>
129 130
130#include <linux/parport.h> 131#include <linux/parport.h>
131#undef LP_STATS 132#undef LP_STATS
@@ -489,14 +490,21 @@ static ssize_t lp_read(struct file * file, char __user * buf,
489static int lp_open(struct inode * inode, struct file * file) 490static int lp_open(struct inode * inode, struct file * file)
490{ 491{
491 unsigned int minor = iminor(inode); 492 unsigned int minor = iminor(inode);
493 int ret = 0;
492 494
493 if (minor >= LP_NO) 495 lock_kernel();
494 return -ENXIO; 496 if (minor >= LP_NO) {
495 if ((LP_F(minor) & LP_EXIST) == 0) 497 ret = -ENXIO;
496 return -ENXIO; 498 goto out;
497 if (test_and_set_bit(LP_BUSY_BIT_POS, &LP_F(minor))) 499 }
498 return -EBUSY; 500 if ((LP_F(minor) & LP_EXIST) == 0) {
499 501 ret = -ENXIO;
502 goto out;
503 }
504 if (test_and_set_bit(LP_BUSY_BIT_POS, &LP_F(minor))) {
505 ret = -EBUSY;
506 goto out;
507 }
500 /* If ABORTOPEN is set and the printer is offline or out of paper, 508 /* If ABORTOPEN is set and the printer is offline or out of paper,
501 we may still want to open it to perform ioctl()s. Therefore we 509 we may still want to open it to perform ioctl()s. Therefore we
502 have commandeered O_NONBLOCK, even though it is being used in 510 have commandeered O_NONBLOCK, even though it is being used in
@@ -510,21 +518,25 @@ static int lp_open(struct inode * inode, struct file * file)
510 if (status & LP_POUTPA) { 518 if (status & LP_POUTPA) {
511 printk(KERN_INFO "lp%d out of paper\n", minor); 519 printk(KERN_INFO "lp%d out of paper\n", minor);
512 LP_F(minor) &= ~LP_BUSY; 520 LP_F(minor) &= ~LP_BUSY;
513 return -ENOSPC; 521 ret = -ENOSPC;
522 goto out;
514 } else if (!(status & LP_PSELECD)) { 523 } else if (!(status & LP_PSELECD)) {
515 printk(KERN_INFO "lp%d off-line\n", minor); 524 printk(KERN_INFO "lp%d off-line\n", minor);
516 LP_F(minor) &= ~LP_BUSY; 525 LP_F(minor) &= ~LP_BUSY;
517 return -EIO; 526 ret = -EIO;
527 goto out;
518 } else if (!(status & LP_PERRORP)) { 528 } else if (!(status & LP_PERRORP)) {
519 printk(KERN_ERR "lp%d printer error\n", minor); 529 printk(KERN_ERR "lp%d printer error\n", minor);
520 LP_F(minor) &= ~LP_BUSY; 530 LP_F(minor) &= ~LP_BUSY;
521 return -EIO; 531 ret = -EIO;
532 goto out;
522 } 533 }
523 } 534 }
524 lp_table[minor].lp_buffer = kmalloc(LP_BUFFER_SIZE, GFP_KERNEL); 535 lp_table[minor].lp_buffer = kmalloc(LP_BUFFER_SIZE, GFP_KERNEL);
525 if (!lp_table[minor].lp_buffer) { 536 if (!lp_table[minor].lp_buffer) {
526 LP_F(minor) &= ~LP_BUSY; 537 LP_F(minor) &= ~LP_BUSY;
527 return -ENOMEM; 538 ret = -ENOMEM;
539 goto out;
528 } 540 }
529 /* Determine if the peripheral supports ECP mode */ 541 /* Determine if the peripheral supports ECP mode */
530 lp_claim_parport_or_block (&lp_table[minor]); 542 lp_claim_parport_or_block (&lp_table[minor]);
@@ -540,7 +552,9 @@ static int lp_open(struct inode * inode, struct file * file)
540 parport_negotiate (lp_table[minor].dev->port, IEEE1284_MODE_COMPAT); 552 parport_negotiate (lp_table[minor].dev->port, IEEE1284_MODE_COMPAT);
541 lp_release_parport (&lp_table[minor]); 553 lp_release_parport (&lp_table[minor]);
542 lp_table[minor].current_mode = IEEE1284_MODE_COMPAT; 554 lp_table[minor].current_mode = IEEE1284_MODE_COMPAT;
543 return 0; 555out:
556 unlock_kernel();
557 return ret;
544} 558}
545 559
546static int lp_release(struct inode * inode, struct file * file) 560static int lp_release(struct inode * inode, struct file * file)
diff --git a/drivers/char/mbcs.c b/drivers/char/mbcs.c
index f4716ad7348a..acd8e9ed474a 100644
--- a/drivers/char/mbcs.c
+++ b/drivers/char/mbcs.c
@@ -24,6 +24,7 @@
24#include <linux/mm.h> 24#include <linux/mm.h>
25#include <linux/uio.h> 25#include <linux/uio.h>
26#include <linux/mutex.h> 26#include <linux/mutex.h>
27#include <linux/smp_lock.h>
27#include <asm/io.h> 28#include <asm/io.h>
28#include <asm/uaccess.h> 29#include <asm/uaccess.h>
29#include <asm/system.h> 30#include <asm/system.h>
@@ -382,15 +383,19 @@ static int mbcs_open(struct inode *ip, struct file *fp)
382 struct mbcs_soft *soft; 383 struct mbcs_soft *soft;
383 int minor; 384 int minor;
384 385
386 lock_kernel();
385 minor = iminor(ip); 387 minor = iminor(ip);
386 388
389 /* Nothing protects access to this list... */
387 list_for_each_entry(soft, &soft_list, list) { 390 list_for_each_entry(soft, &soft_list, list) {
388 if (soft->nasid == minor) { 391 if (soft->nasid == minor) {
389 fp->private_data = soft->cxdev; 392 fp->private_data = soft->cxdev;
393 unlock_kernel();
390 return 0; 394 return 0;
391 } 395 }
392 } 396 }
393 397
398 unlock_kernel();
394 return -ENODEV; 399 return -ENODEV;
395} 400}
396 401
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index 934ffafedaea..070e22e8ea9e 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -26,6 +26,7 @@
26#include <linux/bootmem.h> 26#include <linux/bootmem.h>
27#include <linux/splice.h> 27#include <linux/splice.h>
28#include <linux/pfn.h> 28#include <linux/pfn.h>
29#include <linux/smp_lock.h>
29 30
30#include <asm/uaccess.h> 31#include <asm/uaccess.h>
31#include <asm/io.h> 32#include <asm/io.h>
@@ -889,6 +890,9 @@ static const struct file_operations kmsg_fops = {
889 890
890static int memory_open(struct inode * inode, struct file * filp) 891static int memory_open(struct inode * inode, struct file * filp)
891{ 892{
893 int ret = 0;
894
895 lock_kernel();
892 switch (iminor(inode)) { 896 switch (iminor(inode)) {
893 case 1: 897 case 1:
894 filp->f_op = &mem_fops; 898 filp->f_op = &mem_fops;
@@ -932,11 +936,13 @@ static int memory_open(struct inode * inode, struct file * filp)
932 break; 936 break;
933#endif 937#endif
934 default: 938 default:
939 unlock_kernel();
935 return -ENXIO; 940 return -ENXIO;
936 } 941 }
937 if (filp->f_op && filp->f_op->open) 942 if (filp->f_op && filp->f_op->open)
938 return filp->f_op->open(inode,filp); 943 ret = filp->f_op->open(inode,filp);
939 return 0; 944 unlock_kernel();
945 return ret;
940} 946}
941 947
942static const struct file_operations memory_fops = { 948static const struct file_operations memory_fops = {
diff --git a/drivers/char/misc.c b/drivers/char/misc.c
index eaace0db0ff4..6e1563c3d30a 100644
--- a/drivers/char/misc.c
+++ b/drivers/char/misc.c
@@ -49,6 +49,7 @@
49#include <linux/device.h> 49#include <linux/device.h>
50#include <linux/tty.h> 50#include <linux/tty.h>
51#include <linux/kmod.h> 51#include <linux/kmod.h>
52#include <linux/smp_lock.h>
52 53
53/* 54/*
54 * Head entry for the doubly linked miscdevice list 55 * Head entry for the doubly linked miscdevice list
@@ -118,6 +119,7 @@ static int misc_open(struct inode * inode, struct file * file)
118 int err = -ENODEV; 119 int err = -ENODEV;
119 const struct file_operations *old_fops, *new_fops = NULL; 120 const struct file_operations *old_fops, *new_fops = NULL;
120 121
122 lock_kernel();
121 mutex_lock(&misc_mtx); 123 mutex_lock(&misc_mtx);
122 124
123 list_for_each_entry(c, &misc_list, list) { 125 list_for_each_entry(c, &misc_list, list) {
@@ -155,6 +157,7 @@ static int misc_open(struct inode * inode, struct file * file)
155 fops_put(old_fops); 157 fops_put(old_fops);
156fail: 158fail:
157 mutex_unlock(&misc_mtx); 159 mutex_unlock(&misc_mtx);
160 unlock_kernel();
158 return err; 161 return err;
159} 162}
160 163
diff --git a/drivers/char/moxa.c b/drivers/char/moxa.c
index d57d3a61919b..2bba250ffc8e 100644
--- a/drivers/char/moxa.c
+++ b/drivers/char/moxa.c
@@ -130,17 +130,13 @@ struct moxaq_str {
130}; 130};
131 131
132struct moxa_port { 132struct moxa_port {
133 struct tty_port port;
133 struct moxa_board_conf *board; 134 struct moxa_board_conf *board;
134 struct tty_struct *tty;
135 void __iomem *tableAddr; 135 void __iomem *tableAddr;
136 136
137 int type; 137 int type;
138 int close_delay;
139 unsigned int count;
140 int asyncflags;
141 int cflag; 138 int cflag;
142 unsigned long statusflags; 139 unsigned long statusflags;
143 wait_queue_head_t open_wait;
144 140
145 u8 DCDState; 141 u8 DCDState;
146 u8 lineCtrl; 142 u8 lineCtrl;
@@ -348,10 +344,10 @@ static int moxa_ioctl(struct tty_struct *tty, struct file *file,
348 if (status & 4) 344 if (status & 4)
349 tmp.dcd = 1; 345 tmp.dcd = 1;
350 346
351 if (!p->tty || !p->tty->termios) 347 if (!p->port.tty || !p->port.tty->termios)
352 tmp.cflag = p->cflag; 348 tmp.cflag = p->cflag;
353 else 349 else
354 tmp.cflag = p->tty->termios->c_cflag; 350 tmp.cflag = p->port.tty->termios->c_cflag;
355copy: 351copy:
356 if (copy_to_user(argm, &tmp, sizeof(tmp))) { 352 if (copy_to_user(argm, &tmp, sizeof(tmp))) {
357 mutex_unlock(&moxa_openlock); 353 mutex_unlock(&moxa_openlock);
@@ -721,7 +717,7 @@ static int moxa_load_code(struct moxa_board_conf *brd, const void *ptr,
721 717
722static int moxa_load_fw(struct moxa_board_conf *brd, const struct firmware *fw) 718static int moxa_load_fw(struct moxa_board_conf *brd, const struct firmware *fw)
723{ 719{
724 void *ptr = fw->data; 720 const void *ptr = fw->data;
725 char rsn[64]; 721 char rsn[64];
726 u16 lens[5]; 722 u16 lens[5];
727 size_t len; 723 size_t len;
@@ -734,7 +730,7 @@ static int moxa_load_fw(struct moxa_board_conf *brd, const struct firmware *fw)
734 u8 model; /* C218T=1, C320T=2, CP204=3 */ 730 u8 model; /* C218T=1, C320T=2, CP204=3 */
735 u8 reserved2[8]; 731 u8 reserved2[8];
736 __le16 len[5]; 732 __le16 len[5];
737 } *hdr = ptr; 733 } const *hdr = ptr;
738 734
739 BUILD_BUG_ON(ARRAY_SIZE(hdr->len) != ARRAY_SIZE(lens)); 735 BUILD_BUG_ON(ARRAY_SIZE(hdr->len) != ARRAY_SIZE(lens));
740 736
@@ -825,10 +821,9 @@ static int moxa_init_board(struct moxa_board_conf *brd, struct device *dev)
825 } 821 }
826 822
827 for (i = 0, p = brd->ports; i < MAX_PORTS_PER_BOARD; i++, p++) { 823 for (i = 0, p = brd->ports; i < MAX_PORTS_PER_BOARD; i++, p++) {
824 tty_port_init(&p->port);
828 p->type = PORT_16550A; 825 p->type = PORT_16550A;
829 p->close_delay = 5 * HZ / 10;
830 p->cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL; 826 p->cflag = B9600 | CS8 | CREAD | CLOCAL | HUPCL;
831 init_waitqueue_head(&p->open_wait);
832 } 827 }
833 828
834 switch (brd->boardType) { 829 switch (brd->boardType) {
@@ -884,12 +879,12 @@ static void moxa_board_deinit(struct moxa_board_conf *brd)
884 879
885 /* pci hot-un-plug support */ 880 /* pci hot-un-plug support */
886 for (a = 0; a < brd->numPorts; a++) 881 for (a = 0; a < brd->numPorts; a++)
887 if (brd->ports[a].asyncflags & ASYNC_INITIALIZED) 882 if (brd->ports[a].port.flags & ASYNC_INITIALIZED)
888 tty_hangup(brd->ports[a].tty); 883 tty_hangup(brd->ports[a].port.tty);
889 while (1) { 884 while (1) {
890 opened = 0; 885 opened = 0;
891 for (a = 0; a < brd->numPorts; a++) 886 for (a = 0; a < brd->numPorts; a++)
892 if (brd->ports[a].asyncflags & ASYNC_INITIALIZED) 887 if (brd->ports[a].port.flags & ASYNC_INITIALIZED)
893 opened++; 888 opened++;
894 mutex_unlock(&moxa_openlock); 889 mutex_unlock(&moxa_openlock);
895 if (!opened) 890 if (!opened)
@@ -1104,9 +1099,9 @@ static void moxa_close_port(struct moxa_port *ch)
1104{ 1099{
1105 moxa_shut_down(ch); 1100 moxa_shut_down(ch);
1106 MoxaPortFlushData(ch, 2); 1101 MoxaPortFlushData(ch, 2);
1107 ch->asyncflags &= ~ASYNC_NORMAL_ACTIVE; 1102 ch->port.flags &= ~ASYNC_NORMAL_ACTIVE;
1108 ch->tty->driver_data = NULL; 1103 ch->port.tty->driver_data = NULL;
1109 ch->tty = NULL; 1104 ch->port.tty = NULL;
1110} 1105}
1111 1106
1112static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp, 1107static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp,
@@ -1117,7 +1112,7 @@ static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp,
1117 u8 dcd; 1112 u8 dcd;
1118 1113
1119 while (1) { 1114 while (1) {
1120 prepare_to_wait(&ch->open_wait, &wait, TASK_INTERRUPTIBLE); 1115 prepare_to_wait(&ch->port.open_wait, &wait, TASK_INTERRUPTIBLE);
1121 if (tty_hung_up_p(filp)) { 1116 if (tty_hung_up_p(filp)) {
1122#ifdef SERIAL_DO_RESTART 1117#ifdef SERIAL_DO_RESTART
1123 retval = -ERESTARTSYS; 1118 retval = -ERESTARTSYS;
@@ -1138,7 +1133,7 @@ static int moxa_block_till_ready(struct tty_struct *tty, struct file *filp,
1138 } 1133 }
1139 schedule(); 1134 schedule();
1140 } 1135 }
1141 finish_wait(&ch->open_wait, &wait); 1136 finish_wait(&ch->port.open_wait, &wait);
1142 1137
1143 return retval; 1138 return retval;
1144} 1139}
@@ -1163,16 +1158,16 @@ static int moxa_open(struct tty_struct *tty, struct file *filp)
1163 } 1158 }
1164 1159
1165 ch = &brd->ports[port % MAX_PORTS_PER_BOARD]; 1160 ch = &brd->ports[port % MAX_PORTS_PER_BOARD];
1166 ch->count++; 1161 ch->port.count++;
1167 tty->driver_data = ch; 1162 tty->driver_data = ch;
1168 ch->tty = tty; 1163 ch->port.tty = tty;
1169 if (!(ch->asyncflags & ASYNC_INITIALIZED)) { 1164 if (!(ch->port.flags & ASYNC_INITIALIZED)) {
1170 ch->statusflags = 0; 1165 ch->statusflags = 0;
1171 moxa_set_tty_param(tty, tty->termios); 1166 moxa_set_tty_param(tty, tty->termios);
1172 MoxaPortLineCtrl(ch, 1, 1); 1167 MoxaPortLineCtrl(ch, 1, 1);
1173 MoxaPortEnable(ch); 1168 MoxaPortEnable(ch);
1174 MoxaSetFifo(ch, ch->type == PORT_16550A); 1169 MoxaSetFifo(ch, ch->type == PORT_16550A);
1175 ch->asyncflags |= ASYNC_INITIALIZED; 1170 ch->port.flags |= ASYNC_INITIALIZED;
1176 } 1171 }
1177 mutex_unlock(&moxa_openlock); 1172 mutex_unlock(&moxa_openlock);
1178 1173
@@ -1181,11 +1176,11 @@ static int moxa_open(struct tty_struct *tty, struct file *filp)
1181 retval = moxa_block_till_ready(tty, filp, ch); 1176 retval = moxa_block_till_ready(tty, filp, ch);
1182 mutex_lock(&moxa_openlock); 1177 mutex_lock(&moxa_openlock);
1183 if (retval) { 1178 if (retval) {
1184 if (ch->count) /* 0 means already hung up... */ 1179 if (ch->port.count) /* 0 means already hung up... */
1185 if (--ch->count == 0) 1180 if (--ch->port.count == 0)
1186 moxa_close_port(ch); 1181 moxa_close_port(ch);
1187 } else 1182 } else
1188 ch->asyncflags |= ASYNC_NORMAL_ACTIVE; 1183 ch->port.flags |= ASYNC_NORMAL_ACTIVE;
1189 mutex_unlock(&moxa_openlock); 1184 mutex_unlock(&moxa_openlock);
1190 1185
1191 return retval; 1186 return retval;
@@ -1204,21 +1199,21 @@ static void moxa_close(struct tty_struct *tty, struct file *filp)
1204 ch = tty->driver_data; 1199 ch = tty->driver_data;
1205 if (ch == NULL) 1200 if (ch == NULL)
1206 goto unlock; 1201 goto unlock;
1207 if (tty->count == 1 && ch->count != 1) { 1202 if (tty->count == 1 && ch->port.count != 1) {
1208 printk(KERN_WARNING "moxa_close: bad serial port count; " 1203 printk(KERN_WARNING "moxa_close: bad serial port count; "
1209 "tty->count is 1, ch->count is %d\n", ch->count); 1204 "tty->count is 1, ch->port.count is %d\n", ch->port.count);
1210 ch->count = 1; 1205 ch->port.count = 1;
1211 } 1206 }
1212 if (--ch->count < 0) { 1207 if (--ch->port.count < 0) {
1213 printk(KERN_WARNING "moxa_close: bad serial port count, " 1208 printk(KERN_WARNING "moxa_close: bad serial port count, "
1214 "device=%s\n", tty->name); 1209 "device=%s\n", tty->name);
1215 ch->count = 0; 1210 ch->port.count = 0;
1216 } 1211 }
1217 if (ch->count) 1212 if (ch->port.count)
1218 goto unlock; 1213 goto unlock;
1219 1214
1220 ch->cflag = tty->termios->c_cflag; 1215 ch->cflag = tty->termios->c_cflag;
1221 if (ch->asyncflags & ASYNC_INITIALIZED) { 1216 if (ch->port.flags & ASYNC_INITIALIZED) {
1222 moxa_setup_empty_event(tty); 1217 moxa_setup_empty_event(tty);
1223 tty_wait_until_sent(tty, 30 * HZ); /* 30 seconds timeout */ 1218 tty_wait_until_sent(tty, 30 * HZ); /* 30 seconds timeout */
1224 } 1219 }
@@ -1374,7 +1369,7 @@ static void moxa_set_termios(struct tty_struct *tty,
1374 return; 1369 return;
1375 moxa_set_tty_param(tty, old_termios); 1370 moxa_set_tty_param(tty, old_termios);
1376 if (!(old_termios->c_cflag & CLOCAL) && C_CLOCAL(tty)) 1371 if (!(old_termios->c_cflag & CLOCAL) && C_CLOCAL(tty))
1377 wake_up_interruptible(&ch->open_wait); 1372 wake_up_interruptible(&ch->port.open_wait);
1378} 1373}
1379 1374
1380static void moxa_stop(struct tty_struct *tty) 1375static void moxa_stop(struct tty_struct *tty)
@@ -1412,20 +1407,20 @@ static void moxa_hangup(struct tty_struct *tty)
1412 mutex_unlock(&moxa_openlock); 1407 mutex_unlock(&moxa_openlock);
1413 return; 1408 return;
1414 } 1409 }
1415 ch->count = 0; 1410 ch->port.count = 0;
1416 moxa_close_port(ch); 1411 moxa_close_port(ch);
1417 mutex_unlock(&moxa_openlock); 1412 mutex_unlock(&moxa_openlock);
1418 1413
1419 wake_up_interruptible(&ch->open_wait); 1414 wake_up_interruptible(&ch->port.open_wait);
1420} 1415}
1421 1416
1422static void moxa_new_dcdstate(struct moxa_port *p, u8 dcd) 1417static void moxa_new_dcdstate(struct moxa_port *p, u8 dcd)
1423{ 1418{
1424 dcd = !!dcd; 1419 dcd = !!dcd;
1425 1420
1426 if (dcd != p->DCDState && p->tty && C_CLOCAL(p->tty)) { 1421 if (dcd != p->DCDState && p->port.tty && C_CLOCAL(p->port.tty)) {
1427 if (!dcd) 1422 if (!dcd)
1428 tty_hangup(p->tty); 1423 tty_hangup(p->port.tty);
1429 } 1424 }
1430 p->DCDState = dcd; 1425 p->DCDState = dcd;
1431} 1426}
@@ -1433,9 +1428,9 @@ static void moxa_new_dcdstate(struct moxa_port *p, u8 dcd)
1433static int moxa_poll_port(struct moxa_port *p, unsigned int handle, 1428static int moxa_poll_port(struct moxa_port *p, unsigned int handle,
1434 u16 __iomem *ip) 1429 u16 __iomem *ip)
1435{ 1430{
1436 struct tty_struct *tty = p->tty; 1431 struct tty_struct *tty = p->port.tty;
1437 void __iomem *ofsAddr; 1432 void __iomem *ofsAddr;
1438 unsigned int inited = p->asyncflags & ASYNC_INITIALIZED; 1433 unsigned int inited = p->port.flags & ASYNC_INITIALIZED;
1439 u16 intr; 1434 u16 intr;
1440 1435
1441 if (tty) { 1436 if (tty) {
@@ -1566,9 +1561,9 @@ static void moxa_setup_empty_event(struct tty_struct *tty)
1566 1561
1567static void moxa_shut_down(struct moxa_port *ch) 1562static void moxa_shut_down(struct moxa_port *ch)
1568{ 1563{
1569 struct tty_struct *tp = ch->tty; 1564 struct tty_struct *tp = ch->port.tty;
1570 1565
1571 if (!(ch->asyncflags & ASYNC_INITIALIZED)) 1566 if (!(ch->port.flags & ASYNC_INITIALIZED))
1572 return; 1567 return;
1573 1568
1574 MoxaPortDisable(ch); 1569 MoxaPortDisable(ch);
@@ -1580,7 +1575,7 @@ static void moxa_shut_down(struct moxa_port *ch)
1580 MoxaPortLineCtrl(ch, 0, 0); 1575 MoxaPortLineCtrl(ch, 0, 0);
1581 1576
1582 spin_lock_bh(&moxa_lock); 1577 spin_lock_bh(&moxa_lock);
1583 ch->asyncflags &= ~ASYNC_INITIALIZED; 1578 ch->port.flags &= ~ASYNC_INITIALIZED;
1584 spin_unlock_bh(&moxa_lock); 1579 spin_unlock_bh(&moxa_lock);
1585} 1580}
1586 1581
@@ -1975,7 +1970,7 @@ static int MoxaPortWriteData(struct moxa_port *port,
1975 c = (head > tail) ? (head - tail - 1) : (head - tail + tx_mask); 1970 c = (head > tail) ? (head - tail - 1) : (head - tail + tx_mask);
1976 if (c > len) 1971 if (c > len)
1977 c = len; 1972 c = len;
1978 moxaLog.txcnt[port->tty->index] += c; 1973 moxaLog.txcnt[port->port.tty->index] += c;
1979 total = c; 1974 total = c;
1980 if (spage == epage) { 1975 if (spage == epage) {
1981 bufhead = readw(ofsAddr + Ofs_txb); 1976 bufhead = readw(ofsAddr + Ofs_txb);
@@ -2017,7 +2012,7 @@ static int MoxaPortWriteData(struct moxa_port *port,
2017 2012
2018static int MoxaPortReadData(struct moxa_port *port) 2013static int MoxaPortReadData(struct moxa_port *port)
2019{ 2014{
2020 struct tty_struct *tty = port->tty; 2015 struct tty_struct *tty = port->port.tty;
2021 unsigned char *dst; 2016 unsigned char *dst;
2022 void __iomem *baseAddr, *ofsAddr, *ofs; 2017 void __iomem *baseAddr, *ofsAddr, *ofs;
2023 unsigned int count, len, total; 2018 unsigned int count, len, total;
@@ -2124,10 +2119,10 @@ static int moxa_get_serial_info(struct moxa_port *info,
2124{ 2119{
2125 struct serial_struct tmp = { 2120 struct serial_struct tmp = {
2126 .type = info->type, 2121 .type = info->type,
2127 .line = info->tty->index, 2122 .line = info->port.tty->index,
2128 .flags = info->asyncflags, 2123 .flags = info->port.flags,
2129 .baud_base = 921600, 2124 .baud_base = 921600,
2130 .close_delay = info->close_delay 2125 .close_delay = info->port.close_delay
2131 }; 2126 };
2132 return copy_to_user(retinfo, &tmp, sizeof(*retinfo)) ? -EFAULT : 0; 2127 return copy_to_user(retinfo, &tmp, sizeof(*retinfo)) ? -EFAULT : 0;
2133} 2128}
@@ -2148,13 +2143,13 @@ static int moxa_set_serial_info(struct moxa_port *info,
2148 2143
2149 if (!capable(CAP_SYS_ADMIN)) { 2144 if (!capable(CAP_SYS_ADMIN)) {
2150 if (((new_serial.flags & ~ASYNC_USR_MASK) != 2145 if (((new_serial.flags & ~ASYNC_USR_MASK) !=
2151 (info->asyncflags & ~ASYNC_USR_MASK))) 2146 (info->port.flags & ~ASYNC_USR_MASK)))
2152 return -EPERM; 2147 return -EPERM;
2153 } else 2148 } else
2154 info->close_delay = new_serial.close_delay * HZ / 100; 2149 info->port.close_delay = new_serial.close_delay * HZ / 100;
2155 2150
2156 new_serial.flags = (new_serial.flags & ~ASYNC_FLAGS); 2151 new_serial.flags = (new_serial.flags & ~ASYNC_FLAGS);
2157 new_serial.flags |= (info->asyncflags & ASYNC_FLAGS); 2152 new_serial.flags |= (info->port.flags & ASYNC_FLAGS);
2158 2153
2159 MoxaSetFifo(info, new_serial.type == PORT_16550A); 2154 MoxaSetFifo(info, new_serial.type == PORT_16550A);
2160 2155
diff --git a/drivers/char/mwave/mwavedd.c b/drivers/char/mwave/mwavedd.c
index 8d14823b0514..50243fcd87e8 100644
--- a/drivers/char/mwave/mwavedd.c
+++ b/drivers/char/mwave/mwavedd.c
@@ -56,6 +56,7 @@
56#include <linux/serial.h> 56#include <linux/serial.h>
57#include <linux/sched.h> 57#include <linux/sched.h>
58#include <linux/spinlock.h> 58#include <linux/spinlock.h>
59#include <linux/smp_lock.h>
59#include <linux/delay.h> 60#include <linux/delay.h>
60#include <linux/serial_8250.h> 61#include <linux/serial_8250.h>
61#include "smapi.h" 62#include "smapi.h"
@@ -100,6 +101,7 @@ static int mwave_open(struct inode *inode, struct file *file)
100 PRINTK_2(TRACE_MWAVE, 101 PRINTK_2(TRACE_MWAVE,
101 "mwavedd::mwave_open, exit return retval %x\n", retval); 102 "mwavedd::mwave_open, exit return retval %x\n", retval);
102 103
104 cycle_kernel_lock();
103 return retval; 105 return retval;
104} 106}
105 107
diff --git a/drivers/char/mxser.c b/drivers/char/mxser.c
index 4b81a85c5b53..6307e301bd26 100644
--- a/drivers/char/mxser.c
+++ b/drivers/char/mxser.c
@@ -222,8 +222,8 @@ struct mxser_mon_ext {
222struct mxser_board; 222struct mxser_board;
223 223
224struct mxser_port { 224struct mxser_port {
225 struct tty_port port;
225 struct mxser_board *board; 226 struct mxser_board *board;
226 struct tty_struct *tty;
227 227
228 unsigned long ioaddr; 228 unsigned long ioaddr;
229 unsigned long opmode_ioaddr; 229 unsigned long opmode_ioaddr;
@@ -234,7 +234,6 @@ struct mxser_port {
234 int rx_low_water; 234 int rx_low_water;
235 int baud_base; /* max. speed */ 235 int baud_base; /* max. speed */
236 int type; /* UART type */ 236 int type; /* UART type */
237 int flags; /* defined in tty.h */
238 237
239 int x_char; /* xon/xoff character */ 238 int x_char; /* xon/xoff character */
240 int IER; /* Interrupt Enable Register */ 239 int IER; /* Interrupt Enable Register */
@@ -244,20 +243,14 @@ struct mxser_port {
244 unsigned char ldisc_stop_rx; 243 unsigned char ldisc_stop_rx;
245 244
246 int custom_divisor; 245 int custom_divisor;
247 int close_delay;
248 unsigned short closing_wait;
249 unsigned char err_shadow; 246 unsigned char err_shadow;
250 unsigned long event;
251 247
252 int count; /* # of fd on device */
253 int blocked_open; /* # of blocked opens */
254 struct async_icount icount; /* kernel counters for 4 input interrupts */ 248 struct async_icount icount; /* kernel counters for 4 input interrupts */
255 int timeout; 249 int timeout;
256 250
257 int read_status_mask; 251 int read_status_mask;
258 int ignore_status_mask; 252 int ignore_status_mask;
259 int xmit_fifo_size; 253 int xmit_fifo_size;
260 unsigned char *xmit_buf;
261 int xmit_head; 254 int xmit_head;
262 int xmit_tail; 255 int xmit_tail;
263 int xmit_cnt; 256 int xmit_cnt;
@@ -267,7 +260,6 @@ struct mxser_port {
267 struct mxser_mon mon_data; 260 struct mxser_mon mon_data;
268 261
269 spinlock_t slock; 262 spinlock_t slock;
270 wait_queue_head_t open_wait;
271 wait_queue_head_t delta_msr_wait; 263 wait_queue_head_t delta_msr_wait;
272}; 264};
273 265
@@ -575,7 +567,7 @@ static int mxser_block_til_ready(struct tty_struct *tty, struct file *filp,
575 */ 567 */
576 if ((filp->f_flags & O_NONBLOCK) || 568 if ((filp->f_flags & O_NONBLOCK) ||
577 test_bit(TTY_IO_ERROR, &tty->flags)) { 569 test_bit(TTY_IO_ERROR, &tty->flags)) {
578 port->flags |= ASYNC_NORMAL_ACTIVE; 570 port->port.flags |= ASYNC_NORMAL_ACTIVE;
579 return 0; 571 return 0;
580 } 572 }
581 573
@@ -585,32 +577,32 @@ static int mxser_block_til_ready(struct tty_struct *tty, struct file *filp,
585 /* 577 /*
586 * Block waiting for the carrier detect and the line to become 578 * Block waiting for the carrier detect and the line to become
587 * free (i.e., not in use by the callout). While we are in 579 * free (i.e., not in use by the callout). While we are in
588 * this loop, port->count is dropped by one, so that 580 * this loop, port->port.count is dropped by one, so that
589 * mxser_close() knows when to free things. We restore it upon 581 * mxser_close() knows when to free things. We restore it upon
590 * exit, either normal or abnormal. 582 * exit, either normal or abnormal.
591 */ 583 */
592 retval = 0; 584 retval = 0;
593 add_wait_queue(&port->open_wait, &wait); 585 add_wait_queue(&port->port.open_wait, &wait);
594 586
595 spin_lock_irqsave(&port->slock, flags); 587 spin_lock_irqsave(&port->slock, flags);
596 if (!tty_hung_up_p(filp)) 588 if (!tty_hung_up_p(filp))
597 port->count--; 589 port->port.count--;
598 spin_unlock_irqrestore(&port->slock, flags); 590 spin_unlock_irqrestore(&port->slock, flags);
599 port->blocked_open++; 591 port->port.blocked_open++;
600 while (1) { 592 while (1) {
601 spin_lock_irqsave(&port->slock, flags); 593 spin_lock_irqsave(&port->slock, flags);
602 outb(inb(port->ioaddr + UART_MCR) | 594 outb(inb(port->ioaddr + UART_MCR) |
603 UART_MCR_DTR | UART_MCR_RTS, port->ioaddr + UART_MCR); 595 UART_MCR_DTR | UART_MCR_RTS, port->ioaddr + UART_MCR);
604 spin_unlock_irqrestore(&port->slock, flags); 596 spin_unlock_irqrestore(&port->slock, flags);
605 set_current_state(TASK_INTERRUPTIBLE); 597 set_current_state(TASK_INTERRUPTIBLE);
606 if (tty_hung_up_p(filp) || !(port->flags & ASYNC_INITIALIZED)) { 598 if (tty_hung_up_p(filp) || !(port->port.flags & ASYNC_INITIALIZED)) {
607 if (port->flags & ASYNC_HUP_NOTIFY) 599 if (port->port.flags & ASYNC_HUP_NOTIFY)
608 retval = -EAGAIN; 600 retval = -EAGAIN;
609 else 601 else
610 retval = -ERESTARTSYS; 602 retval = -ERESTARTSYS;
611 break; 603 break;
612 } 604 }
613 if (!(port->flags & ASYNC_CLOSING) && 605 if (!(port->port.flags & ASYNC_CLOSING) &&
614 (do_clocal || 606 (do_clocal ||
615 (inb(port->ioaddr + UART_MSR) & UART_MSR_DCD))) 607 (inb(port->ioaddr + UART_MSR) & UART_MSR_DCD)))
616 break; 608 break;
@@ -621,13 +613,13 @@ static int mxser_block_til_ready(struct tty_struct *tty, struct file *filp,
621 schedule(); 613 schedule();
622 } 614 }
623 set_current_state(TASK_RUNNING); 615 set_current_state(TASK_RUNNING);
624 remove_wait_queue(&port->open_wait, &wait); 616 remove_wait_queue(&port->port.open_wait, &wait);
625 if (!tty_hung_up_p(filp)) 617 if (!tty_hung_up_p(filp))
626 port->count++; 618 port->port.count++;
627 port->blocked_open--; 619 port->port.blocked_open--;
628 if (retval) 620 if (retval)
629 return retval; 621 return retval;
630 port->flags |= ASYNC_NORMAL_ACTIVE; 622 port->port.flags |= ASYNC_NORMAL_ACTIVE;
631 return 0; 623 return 0;
632} 624}
633 625
@@ -636,7 +628,7 @@ static int mxser_set_baud(struct mxser_port *info, long newspd)
636 int quot = 0, baud; 628 int quot = 0, baud;
637 unsigned char cval; 629 unsigned char cval;
638 630
639 if (!info->tty || !info->tty->termios) 631 if (!info->port.tty || !info->port.tty->termios)
640 return -1; 632 return -1;
641 633
642 if (!(info->ioaddr)) 634 if (!(info->ioaddr))
@@ -647,13 +639,13 @@ static int mxser_set_baud(struct mxser_port *info, long newspd)
647 639
648 if (newspd == 134) { 640 if (newspd == 134) {
649 quot = 2 * info->baud_base / 269; 641 quot = 2 * info->baud_base / 269;
650 tty_encode_baud_rate(info->tty, 134, 134); 642 tty_encode_baud_rate(info->port.tty, 134, 134);
651 } else if (newspd) { 643 } else if (newspd) {
652 quot = info->baud_base / newspd; 644 quot = info->baud_base / newspd;
653 if (quot == 0) 645 if (quot == 0)
654 quot = 1; 646 quot = 1;
655 baud = info->baud_base/quot; 647 baud = info->baud_base/quot;
656 tty_encode_baud_rate(info->tty, baud, baud); 648 tty_encode_baud_rate(info->port.tty, baud, baud);
657 } else { 649 } else {
658 quot = 0; 650 quot = 0;
659 } 651 }
@@ -679,7 +671,7 @@ static int mxser_set_baud(struct mxser_port *info, long newspd)
679 outb(cval, info->ioaddr + UART_LCR); /* reset DLAB */ 671 outb(cval, info->ioaddr + UART_LCR); /* reset DLAB */
680 672
681#ifdef BOTHER 673#ifdef BOTHER
682 if (C_BAUD(info->tty) == BOTHER) { 674 if (C_BAUD(info->port.tty) == BOTHER) {
683 quot = info->baud_base % newspd; 675 quot = info->baud_base % newspd;
684 quot *= 8; 676 quot *= 8;
685 if (quot % newspd > newspd / 2) { 677 if (quot % newspd > newspd / 2) {
@@ -707,14 +699,14 @@ static int mxser_change_speed(struct mxser_port *info,
707 int ret = 0; 699 int ret = 0;
708 unsigned char status; 700 unsigned char status;
709 701
710 if (!info->tty || !info->tty->termios) 702 if (!info->port.tty || !info->port.tty->termios)
711 return ret; 703 return ret;
712 cflag = info->tty->termios->c_cflag; 704 cflag = info->port.tty->termios->c_cflag;
713 if (!(info->ioaddr)) 705 if (!(info->ioaddr))
714 return ret; 706 return ret;
715 707
716 if (mxser_set_baud_method[info->tty->index] == 0) 708 if (mxser_set_baud_method[info->port.tty->index] == 0)
717 mxser_set_baud(info, tty_get_baud_rate(info->tty)); 709 mxser_set_baud(info, tty_get_baud_rate(info->port.tty));
718 710
719 /* byte size and parity */ 711 /* byte size and parity */
720 switch (cflag & CSIZE) { 712 switch (cflag & CSIZE) {
@@ -777,15 +769,15 @@ static int mxser_change_speed(struct mxser_port *info,
777 info->IER &= ~UART_IER_MSI; 769 info->IER &= ~UART_IER_MSI;
778 info->MCR &= ~UART_MCR_AFE; 770 info->MCR &= ~UART_MCR_AFE;
779 if (cflag & CRTSCTS) { 771 if (cflag & CRTSCTS) {
780 info->flags |= ASYNC_CTS_FLOW; 772 info->port.flags |= ASYNC_CTS_FLOW;
781 info->IER |= UART_IER_MSI; 773 info->IER |= UART_IER_MSI;
782 if ((info->type == PORT_16550A) || (info->board->chip_flag)) { 774 if ((info->type == PORT_16550A) || (info->board->chip_flag)) {
783 info->MCR |= UART_MCR_AFE; 775 info->MCR |= UART_MCR_AFE;
784 } else { 776 } else {
785 status = inb(info->ioaddr + UART_MSR); 777 status = inb(info->ioaddr + UART_MSR);
786 if (info->tty->hw_stopped) { 778 if (info->port.tty->hw_stopped) {
787 if (status & UART_MSR_CTS) { 779 if (status & UART_MSR_CTS) {
788 info->tty->hw_stopped = 0; 780 info->port.tty->hw_stopped = 0;
789 if (info->type != PORT_16550A && 781 if (info->type != PORT_16550A &&
790 !info->board->chip_flag) { 782 !info->board->chip_flag) {
791 outb(info->IER & ~UART_IER_THRI, 783 outb(info->IER & ~UART_IER_THRI,
@@ -795,11 +787,11 @@ static int mxser_change_speed(struct mxser_port *info,
795 outb(info->IER, info->ioaddr + 787 outb(info->IER, info->ioaddr +
796 UART_IER); 788 UART_IER);
797 } 789 }
798 tty_wakeup(info->tty); 790 tty_wakeup(info->port.tty);
799 } 791 }
800 } else { 792 } else {
801 if (!(status & UART_MSR_CTS)) { 793 if (!(status & UART_MSR_CTS)) {
802 info->tty->hw_stopped = 1; 794 info->port.tty->hw_stopped = 1;
803 if ((info->type != PORT_16550A) && 795 if ((info->type != PORT_16550A) &&
804 (!info->board->chip_flag)) { 796 (!info->board->chip_flag)) {
805 info->IER &= ~UART_IER_THRI; 797 info->IER &= ~UART_IER_THRI;
@@ -810,13 +802,13 @@ static int mxser_change_speed(struct mxser_port *info,
810 } 802 }
811 } 803 }
812 } else { 804 } else {
813 info->flags &= ~ASYNC_CTS_FLOW; 805 info->port.flags &= ~ASYNC_CTS_FLOW;
814 } 806 }
815 outb(info->MCR, info->ioaddr + UART_MCR); 807 outb(info->MCR, info->ioaddr + UART_MCR);
816 if (cflag & CLOCAL) { 808 if (cflag & CLOCAL) {
817 info->flags &= ~ASYNC_CHECK_CD; 809 info->port.flags &= ~ASYNC_CHECK_CD;
818 } else { 810 } else {
819 info->flags |= ASYNC_CHECK_CD; 811 info->port.flags |= ASYNC_CHECK_CD;
820 info->IER |= UART_IER_MSI; 812 info->IER |= UART_IER_MSI;
821 } 813 }
822 outb(info->IER, info->ioaddr + UART_IER); 814 outb(info->IER, info->ioaddr + UART_IER);
@@ -825,21 +817,21 @@ static int mxser_change_speed(struct mxser_port *info,
825 * Set up parity check flag 817 * Set up parity check flag
826 */ 818 */
827 info->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR; 819 info->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR;
828 if (I_INPCK(info->tty)) 820 if (I_INPCK(info->port.tty))
829 info->read_status_mask |= UART_LSR_FE | UART_LSR_PE; 821 info->read_status_mask |= UART_LSR_FE | UART_LSR_PE;
830 if (I_BRKINT(info->tty) || I_PARMRK(info->tty)) 822 if (I_BRKINT(info->port.tty) || I_PARMRK(info->port.tty))
831 info->read_status_mask |= UART_LSR_BI; 823 info->read_status_mask |= UART_LSR_BI;
832 824
833 info->ignore_status_mask = 0; 825 info->ignore_status_mask = 0;
834 826
835 if (I_IGNBRK(info->tty)) { 827 if (I_IGNBRK(info->port.tty)) {
836 info->ignore_status_mask |= UART_LSR_BI; 828 info->ignore_status_mask |= UART_LSR_BI;
837 info->read_status_mask |= UART_LSR_BI; 829 info->read_status_mask |= UART_LSR_BI;
838 /* 830 /*
839 * If we're ignore parity and break indicators, ignore 831 * If we're ignore parity and break indicators, ignore
840 * overruns too. (For real raw support). 832 * overruns too. (For real raw support).
841 */ 833 */
842 if (I_IGNPAR(info->tty)) { 834 if (I_IGNPAR(info->port.tty)) {
843 info->ignore_status_mask |= 835 info->ignore_status_mask |=
844 UART_LSR_OE | 836 UART_LSR_OE |
845 UART_LSR_PE | 837 UART_LSR_PE |
@@ -851,16 +843,16 @@ static int mxser_change_speed(struct mxser_port *info,
851 } 843 }
852 } 844 }
853 if (info->board->chip_flag) { 845 if (info->board->chip_flag) {
854 mxser_set_must_xon1_value(info->ioaddr, START_CHAR(info->tty)); 846 mxser_set_must_xon1_value(info->ioaddr, START_CHAR(info->port.tty));
855 mxser_set_must_xoff1_value(info->ioaddr, STOP_CHAR(info->tty)); 847 mxser_set_must_xoff1_value(info->ioaddr, STOP_CHAR(info->port.tty));
856 if (I_IXON(info->tty)) { 848 if (I_IXON(info->port.tty)) {
857 mxser_enable_must_rx_software_flow_control( 849 mxser_enable_must_rx_software_flow_control(
858 info->ioaddr); 850 info->ioaddr);
859 } else { 851 } else {
860 mxser_disable_must_rx_software_flow_control( 852 mxser_disable_must_rx_software_flow_control(
861 info->ioaddr); 853 info->ioaddr);
862 } 854 }
863 if (I_IXOFF(info->tty)) { 855 if (I_IXOFF(info->port.tty)) {
864 mxser_enable_must_tx_software_flow_control( 856 mxser_enable_must_tx_software_flow_control(
865 info->ioaddr); 857 info->ioaddr);
866 } else { 858 } else {
@@ -890,15 +882,15 @@ static void mxser_check_modem_status(struct mxser_port *port, int status)
890 port->mon_data.modem_status = status; 882 port->mon_data.modem_status = status;
891 wake_up_interruptible(&port->delta_msr_wait); 883 wake_up_interruptible(&port->delta_msr_wait);
892 884
893 if ((port->flags & ASYNC_CHECK_CD) && (status & UART_MSR_DDCD)) { 885 if ((port->port.flags & ASYNC_CHECK_CD) && (status & UART_MSR_DDCD)) {
894 if (status & UART_MSR_DCD) 886 if (status & UART_MSR_DCD)
895 wake_up_interruptible(&port->open_wait); 887 wake_up_interruptible(&port->port.open_wait);
896 } 888 }
897 889
898 if (port->flags & ASYNC_CTS_FLOW) { 890 if (port->port.flags & ASYNC_CTS_FLOW) {
899 if (port->tty->hw_stopped) { 891 if (port->port.tty->hw_stopped) {
900 if (status & UART_MSR_CTS) { 892 if (status & UART_MSR_CTS) {
901 port->tty->hw_stopped = 0; 893 port->port.tty->hw_stopped = 0;
902 894
903 if ((port->type != PORT_16550A) && 895 if ((port->type != PORT_16550A) &&
904 (!port->board->chip_flag)) { 896 (!port->board->chip_flag)) {
@@ -908,11 +900,11 @@ static void mxser_check_modem_status(struct mxser_port *port, int status)
908 outb(port->IER, port->ioaddr + 900 outb(port->IER, port->ioaddr +
909 UART_IER); 901 UART_IER);
910 } 902 }
911 tty_wakeup(port->tty); 903 tty_wakeup(port->port.tty);
912 } 904 }
913 } else { 905 } else {
914 if (!(status & UART_MSR_CTS)) { 906 if (!(status & UART_MSR_CTS)) {
915 port->tty->hw_stopped = 1; 907 port->port.tty->hw_stopped = 1;
916 if (port->type != PORT_16550A && 908 if (port->type != PORT_16550A &&
917 !port->board->chip_flag) { 909 !port->board->chip_flag) {
918 port->IER &= ~UART_IER_THRI; 910 port->IER &= ~UART_IER_THRI;
@@ -935,23 +927,23 @@ static int mxser_startup(struct mxser_port *info)
935 927
936 spin_lock_irqsave(&info->slock, flags); 928 spin_lock_irqsave(&info->slock, flags);
937 929
938 if (info->flags & ASYNC_INITIALIZED) { 930 if (info->port.flags & ASYNC_INITIALIZED) {
939 free_page(page); 931 free_page(page);
940 spin_unlock_irqrestore(&info->slock, flags); 932 spin_unlock_irqrestore(&info->slock, flags);
941 return 0; 933 return 0;
942 } 934 }
943 935
944 if (!info->ioaddr || !info->type) { 936 if (!info->ioaddr || !info->type) {
945 if (info->tty) 937 if (info->port.tty)
946 set_bit(TTY_IO_ERROR, &info->tty->flags); 938 set_bit(TTY_IO_ERROR, &info->port.tty->flags);
947 free_page(page); 939 free_page(page);
948 spin_unlock_irqrestore(&info->slock, flags); 940 spin_unlock_irqrestore(&info->slock, flags);
949 return 0; 941 return 0;
950 } 942 }
951 if (info->xmit_buf) 943 if (info->port.xmit_buf)
952 free_page(page); 944 free_page(page);
953 else 945 else
954 info->xmit_buf = (unsigned char *) page; 946 info->port.xmit_buf = (unsigned char *) page;
955 947
956 /* 948 /*
957 * Clear the FIFO buffers and disable them 949 * Clear the FIFO buffers and disable them
@@ -973,8 +965,8 @@ static int mxser_startup(struct mxser_port *info)
973 if (inb(info->ioaddr + UART_LSR) == 0xff) { 965 if (inb(info->ioaddr + UART_LSR) == 0xff) {
974 spin_unlock_irqrestore(&info->slock, flags); 966 spin_unlock_irqrestore(&info->slock, flags);
975 if (capable(CAP_SYS_ADMIN)) { 967 if (capable(CAP_SYS_ADMIN)) {
976 if (info->tty) 968 if (info->port.tty)
977 set_bit(TTY_IO_ERROR, &info->tty->flags); 969 set_bit(TTY_IO_ERROR, &info->port.tty->flags);
978 return 0; 970 return 0;
979 } else 971 } else
980 return -ENODEV; 972 return -ENODEV;
@@ -1012,15 +1004,15 @@ static int mxser_startup(struct mxser_port *info)
1012 (void) inb(info->ioaddr + UART_IIR); 1004 (void) inb(info->ioaddr + UART_IIR);
1013 (void) inb(info->ioaddr + UART_MSR); 1005 (void) inb(info->ioaddr + UART_MSR);
1014 1006
1015 if (info->tty) 1007 if (info->port.tty)
1016 clear_bit(TTY_IO_ERROR, &info->tty->flags); 1008 clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
1017 info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; 1009 info->xmit_cnt = info->xmit_head = info->xmit_tail = 0;
1018 1010
1019 /* 1011 /*
1020 * and set the speed of the serial port 1012 * and set the speed of the serial port
1021 */ 1013 */
1022 mxser_change_speed(info, NULL); 1014 mxser_change_speed(info, NULL);
1023 info->flags |= ASYNC_INITIALIZED; 1015 info->port.flags |= ASYNC_INITIALIZED;
1024 spin_unlock_irqrestore(&info->slock, flags); 1016 spin_unlock_irqrestore(&info->slock, flags);
1025 1017
1026 return 0; 1018 return 0;
@@ -1034,7 +1026,7 @@ static void mxser_shutdown(struct mxser_port *info)
1034{ 1026{
1035 unsigned long flags; 1027 unsigned long flags;
1036 1028
1037 if (!(info->flags & ASYNC_INITIALIZED)) 1029 if (!(info->port.flags & ASYNC_INITIALIZED))
1038 return; 1030 return;
1039 1031
1040 spin_lock_irqsave(&info->slock, flags); 1032 spin_lock_irqsave(&info->slock, flags);
@@ -1048,15 +1040,15 @@ static void mxser_shutdown(struct mxser_port *info)
1048 /* 1040 /*
1049 * Free the IRQ, if necessary 1041 * Free the IRQ, if necessary
1050 */ 1042 */
1051 if (info->xmit_buf) { 1043 if (info->port.xmit_buf) {
1052 free_page((unsigned long) info->xmit_buf); 1044 free_page((unsigned long) info->port.xmit_buf);
1053 info->xmit_buf = NULL; 1045 info->port.xmit_buf = NULL;
1054 } 1046 }
1055 1047
1056 info->IER = 0; 1048 info->IER = 0;
1057 outb(0x00, info->ioaddr + UART_IER); 1049 outb(0x00, info->ioaddr + UART_IER);
1058 1050
1059 if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) 1051 if (!info->port.tty || (info->port.tty->termios->c_cflag & HUPCL))
1060 info->MCR &= ~(UART_MCR_DTR | UART_MCR_RTS); 1052 info->MCR &= ~(UART_MCR_DTR | UART_MCR_RTS);
1061 outb(info->MCR, info->ioaddr + UART_MCR); 1053 outb(info->MCR, info->ioaddr + UART_MCR);
1062 1054
@@ -1072,10 +1064,10 @@ static void mxser_shutdown(struct mxser_port *info)
1072 /* read data port to reset things */ 1064 /* read data port to reset things */
1073 (void) inb(info->ioaddr + UART_RX); 1065 (void) inb(info->ioaddr + UART_RX);
1074 1066
1075 if (info->tty) 1067 if (info->port.tty)
1076 set_bit(TTY_IO_ERROR, &info->tty->flags); 1068 set_bit(TTY_IO_ERROR, &info->port.tty->flags);
1077 1069
1078 info->flags &= ~ASYNC_INITIALIZED; 1070 info->port.flags &= ~ASYNC_INITIALIZED;
1079 1071
1080 if (info->board->chip_flag) 1072 if (info->board->chip_flag)
1081 SET_MOXA_MUST_NO_SOFTWARE_FLOW_CONTROL(info->ioaddr); 1073 SET_MOXA_MUST_NO_SOFTWARE_FLOW_CONTROL(info->ioaddr);
@@ -1105,12 +1097,12 @@ static int mxser_open(struct tty_struct *tty, struct file *filp)
1105 return -ENODEV; 1097 return -ENODEV;
1106 1098
1107 tty->driver_data = info; 1099 tty->driver_data = info;
1108 info->tty = tty; 1100 info->port.tty = tty;
1109 /* 1101 /*
1110 * Start up serial port 1102 * Start up serial port
1111 */ 1103 */
1112 spin_lock_irqsave(&info->slock, flags); 1104 spin_lock_irqsave(&info->slock, flags);
1113 info->count++; 1105 info->port.count++;
1114 spin_unlock_irqrestore(&info->slock, flags); 1106 spin_unlock_irqrestore(&info->slock, flags);
1115 retval = mxser_startup(info); 1107 retval = mxser_startup(info);
1116 if (retval) 1108 if (retval)
@@ -1170,42 +1162,42 @@ static void mxser_close(struct tty_struct *tty, struct file *filp)
1170 spin_unlock_irqrestore(&info->slock, flags); 1162 spin_unlock_irqrestore(&info->slock, flags);
1171 return; 1163 return;
1172 } 1164 }
1173 if ((tty->count == 1) && (info->count != 1)) { 1165 if ((tty->count == 1) && (info->port.count != 1)) {
1174 /* 1166 /*
1175 * Uh, oh. tty->count is 1, which means that the tty 1167 * Uh, oh. tty->count is 1, which means that the tty
1176 * structure will be freed. Info->count should always 1168 * structure will be freed. Info->port.count should always
1177 * be one in these conditions. If it's greater than 1169 * be one in these conditions. If it's greater than
1178 * one, we've got real problems, since it means the 1170 * one, we've got real problems, since it means the
1179 * serial port won't be shutdown. 1171 * serial port won't be shutdown.
1180 */ 1172 */
1181 printk(KERN_ERR "mxser_close: bad serial port count; " 1173 printk(KERN_ERR "mxser_close: bad serial port count; "
1182 "tty->count is 1, info->count is %d\n", info->count); 1174 "tty->count is 1, info->port.count is %d\n", info->port.count);
1183 info->count = 1; 1175 info->port.count = 1;
1184 } 1176 }
1185 if (--info->count < 0) { 1177 if (--info->port.count < 0) {
1186 printk(KERN_ERR "mxser_close: bad serial port count for " 1178 printk(KERN_ERR "mxser_close: bad serial port count for "
1187 "ttys%d: %d\n", tty->index, info->count); 1179 "ttys%d: %d\n", tty->index, info->port.count);
1188 info->count = 0; 1180 info->port.count = 0;
1189 } 1181 }
1190 if (info->count) { 1182 if (info->port.count) {
1191 spin_unlock_irqrestore(&info->slock, flags); 1183 spin_unlock_irqrestore(&info->slock, flags);
1192 return; 1184 return;
1193 } 1185 }
1194 info->flags |= ASYNC_CLOSING; 1186 info->port.flags |= ASYNC_CLOSING;
1195 spin_unlock_irqrestore(&info->slock, flags); 1187 spin_unlock_irqrestore(&info->slock, flags);
1196 /* 1188 /*
1197 * Save the termios structure, since this port may have 1189 * Save the termios structure, since this port may have
1198 * separate termios for callout and dialin. 1190 * separate termios for callout and dialin.
1199 */ 1191 */
1200 if (info->flags & ASYNC_NORMAL_ACTIVE) 1192 if (info->port.flags & ASYNC_NORMAL_ACTIVE)
1201 info->normal_termios = *tty->termios; 1193 info->normal_termios = *tty->termios;
1202 /* 1194 /*
1203 * Now we wait for the transmit buffer to clear; and we notify 1195 * Now we wait for the transmit buffer to clear; and we notify
1204 * the line discipline to only process XON/XOFF characters. 1196 * the line discipline to only process XON/XOFF characters.
1205 */ 1197 */
1206 tty->closing = 1; 1198 tty->closing = 1;
1207 if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE) 1199 if (info->port.closing_wait != ASYNC_CLOSING_WAIT_NONE)
1208 tty_wait_until_sent(tty, info->closing_wait); 1200 tty_wait_until_sent(tty, info->port.closing_wait);
1209 /* 1201 /*
1210 * At this point we stop accepting input. To do this, we 1202 * At this point we stop accepting input. To do this, we
1211 * disable the receive line status interrupts, and tell the 1203 * disable the receive line status interrupts, and tell the
@@ -1216,7 +1208,7 @@ static void mxser_close(struct tty_struct *tty, struct file *filp)
1216 if (info->board->chip_flag) 1208 if (info->board->chip_flag)
1217 info->IER &= ~MOXA_MUST_RECV_ISR; 1209 info->IER &= ~MOXA_MUST_RECV_ISR;
1218 1210
1219 if (info->flags & ASYNC_INITIALIZED) { 1211 if (info->port.flags & ASYNC_INITIALIZED) {
1220 outb(info->IER, info->ioaddr + UART_IER); 1212 outb(info->IER, info->ioaddr + UART_IER);
1221 /* 1213 /*
1222 * Before we drop DTR, make sure the UART transmitter 1214 * Before we drop DTR, make sure the UART transmitter
@@ -1236,15 +1228,14 @@ static void mxser_close(struct tty_struct *tty, struct file *filp)
1236 tty_ldisc_flush(tty); 1228 tty_ldisc_flush(tty);
1237 1229
1238 tty->closing = 0; 1230 tty->closing = 0;
1239 info->event = 0; 1231 info->port.tty = NULL;
1240 info->tty = NULL; 1232 if (info->port.blocked_open) {
1241 if (info->blocked_open) { 1233 if (info->port.close_delay)
1242 if (info->close_delay) 1234 schedule_timeout_interruptible(info->port.close_delay);
1243 schedule_timeout_interruptible(info->close_delay); 1235 wake_up_interruptible(&info->port.open_wait);
1244 wake_up_interruptible(&info->open_wait);
1245 } 1236 }
1246 1237
1247 info->flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING); 1238 info->port.flags &= ~(ASYNC_NORMAL_ACTIVE | ASYNC_CLOSING);
1248} 1239}
1249 1240
1250static int mxser_write(struct tty_struct *tty, const unsigned char *buf, int count) 1241static int mxser_write(struct tty_struct *tty, const unsigned char *buf, int count)
@@ -1253,7 +1244,7 @@ static int mxser_write(struct tty_struct *tty, const unsigned char *buf, int cou
1253 struct mxser_port *info = tty->driver_data; 1244 struct mxser_port *info = tty->driver_data;
1254 unsigned long flags; 1245 unsigned long flags;
1255 1246
1256 if (!info->xmit_buf) 1247 if (!info->port.xmit_buf)
1257 return 0; 1248 return 0;
1258 1249
1259 while (1) { 1250 while (1) {
@@ -1262,7 +1253,7 @@ static int mxser_write(struct tty_struct *tty, const unsigned char *buf, int cou
1262 if (c <= 0) 1253 if (c <= 0)
1263 break; 1254 break;
1264 1255
1265 memcpy(info->xmit_buf + info->xmit_head, buf, c); 1256 memcpy(info->port.xmit_buf + info->xmit_head, buf, c);
1266 spin_lock_irqsave(&info->slock, flags); 1257 spin_lock_irqsave(&info->slock, flags);
1267 info->xmit_head = (info->xmit_head + c) & 1258 info->xmit_head = (info->xmit_head + c) &
1268 (SERIAL_XMIT_SIZE - 1); 1259 (SERIAL_XMIT_SIZE - 1);
@@ -1294,14 +1285,14 @@ static int mxser_put_char(struct tty_struct *tty, unsigned char ch)
1294 struct mxser_port *info = tty->driver_data; 1285 struct mxser_port *info = tty->driver_data;
1295 unsigned long flags; 1286 unsigned long flags;
1296 1287
1297 if (!info->xmit_buf) 1288 if (!info->port.xmit_buf)
1298 return 0; 1289 return 0;
1299 1290
1300 if (info->xmit_cnt >= SERIAL_XMIT_SIZE - 1) 1291 if (info->xmit_cnt >= SERIAL_XMIT_SIZE - 1)
1301 return 0; 1292 return 0;
1302 1293
1303 spin_lock_irqsave(&info->slock, flags); 1294 spin_lock_irqsave(&info->slock, flags);
1304 info->xmit_buf[info->xmit_head++] = ch; 1295 info->port.xmit_buf[info->xmit_head++] = ch;
1305 info->xmit_head &= SERIAL_XMIT_SIZE - 1; 1296 info->xmit_head &= SERIAL_XMIT_SIZE - 1;
1306 info->xmit_cnt++; 1297 info->xmit_cnt++;
1307 spin_unlock_irqrestore(&info->slock, flags); 1298 spin_unlock_irqrestore(&info->slock, flags);
@@ -1327,7 +1318,7 @@ static void mxser_flush_chars(struct tty_struct *tty)
1327 1318
1328 if (info->xmit_cnt <= 0 || 1319 if (info->xmit_cnt <= 0 ||
1329 tty->stopped || 1320 tty->stopped ||
1330 !info->xmit_buf || 1321 !info->port.xmit_buf ||
1331 (tty->hw_stopped && 1322 (tty->hw_stopped &&
1332 (info->type != PORT_16550A) && 1323 (info->type != PORT_16550A) &&
1333 (!info->board->chip_flag) 1324 (!info->board->chip_flag)
@@ -1370,13 +1361,13 @@ static int mxser_get_serial_info(struct mxser_port *info,
1370{ 1361{
1371 struct serial_struct tmp = { 1362 struct serial_struct tmp = {
1372 .type = info->type, 1363 .type = info->type,
1373 .line = info->tty->index, 1364 .line = info->port.tty->index,
1374 .port = info->ioaddr, 1365 .port = info->ioaddr,
1375 .irq = info->board->irq, 1366 .irq = info->board->irq,
1376 .flags = info->flags, 1367 .flags = info->port.flags,
1377 .baud_base = info->baud_base, 1368 .baud_base = info->baud_base,
1378 .close_delay = info->close_delay, 1369 .close_delay = info->port.close_delay,
1379 .closing_wait = info->closing_wait, 1370 .closing_wait = info->port.closing_wait,
1380 .custom_divisor = info->custom_divisor, 1371 .custom_divisor = info->custom_divisor,
1381 .hub6 = 0 1372 .hub6 = 0
1382 }; 1373 };
@@ -1403,33 +1394,33 @@ static int mxser_set_serial_info(struct mxser_port *info,
1403 new_serial.port != info->ioaddr) 1394 new_serial.port != info->ioaddr)
1404 return -EINVAL; 1395 return -EINVAL;
1405 1396
1406 flags = info->flags & ASYNC_SPD_MASK; 1397 flags = info->port.flags & ASYNC_SPD_MASK;
1407 1398
1408 if (!capable(CAP_SYS_ADMIN)) { 1399 if (!capable(CAP_SYS_ADMIN)) {
1409 if ((new_serial.baud_base != info->baud_base) || 1400 if ((new_serial.baud_base != info->baud_base) ||
1410 (new_serial.close_delay != info->close_delay) || 1401 (new_serial.close_delay != info->port.close_delay) ||
1411 ((new_serial.flags & ~ASYNC_USR_MASK) != (info->flags & ~ASYNC_USR_MASK))) 1402 ((new_serial.flags & ~ASYNC_USR_MASK) != (info->port.flags & ~ASYNC_USR_MASK)))
1412 return -EPERM; 1403 return -EPERM;
1413 info->flags = ((info->flags & ~ASYNC_USR_MASK) | 1404 info->port.flags = ((info->port.flags & ~ASYNC_USR_MASK) |
1414 (new_serial.flags & ASYNC_USR_MASK)); 1405 (new_serial.flags & ASYNC_USR_MASK));
1415 } else { 1406 } else {
1416 /* 1407 /*
1417 * OK, past this point, all the error checking has been done. 1408 * OK, past this point, all the error checking has been done.
1418 * At this point, we start making changes..... 1409 * At this point, we start making changes.....
1419 */ 1410 */
1420 info->flags = ((info->flags & ~ASYNC_FLAGS) | 1411 info->port.flags = ((info->port.flags & ~ASYNC_FLAGS) |
1421 (new_serial.flags & ASYNC_FLAGS)); 1412 (new_serial.flags & ASYNC_FLAGS));
1422 info->close_delay = new_serial.close_delay * HZ / 100; 1413 info->port.close_delay = new_serial.close_delay * HZ / 100;
1423 info->closing_wait = new_serial.closing_wait * HZ / 100; 1414 info->port.closing_wait = new_serial.closing_wait * HZ / 100;
1424 info->tty->low_latency = 1415 info->port.tty->low_latency =
1425 (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; 1416 (info->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0;
1426 info->tty->low_latency = 0; 1417 info->port.tty->low_latency = 0;
1427 if ((info->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST && 1418 if ((info->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST &&
1428 (new_serial.baud_base != info->baud_base || 1419 (new_serial.baud_base != info->baud_base ||
1429 new_serial.custom_divisor != 1420 new_serial.custom_divisor !=
1430 info->custom_divisor)) { 1421 info->custom_divisor)) {
1431 baud = new_serial.baud_base / new_serial.custom_divisor; 1422 baud = new_serial.baud_base / new_serial.custom_divisor;
1432 tty_encode_baud_rate(info->tty, baud, baud); 1423 tty_encode_baud_rate(info->port.tty, baud, baud);
1433 } 1424 }
1434 } 1425 }
1435 1426
@@ -1437,8 +1428,8 @@ static int mxser_set_serial_info(struct mxser_port *info,
1437 1428
1438 process_txrx_fifo(info); 1429 process_txrx_fifo(info);
1439 1430
1440 if (info->flags & ASYNC_INITIALIZED) { 1431 if (info->port.flags & ASYNC_INITIALIZED) {
1441 if (flags != (info->flags & ASYNC_SPD_MASK)) { 1432 if (flags != (info->port.flags & ASYNC_SPD_MASK)) {
1442 spin_lock_irqsave(&info->slock, sl_flags); 1433 spin_lock_irqsave(&info->slock, sl_flags);
1443 mxser_change_speed(info, NULL); 1434 mxser_change_speed(info, NULL);
1444 spin_unlock_irqrestore(&info->slock, sl_flags); 1435 spin_unlock_irqrestore(&info->slock, sl_flags);
@@ -1693,12 +1684,12 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp)
1693 continue; 1684 continue;
1694 } 1685 }
1695 1686
1696 if (!port->tty || !port->tty->termios) 1687 if (!port->port.tty || !port->port.tty->termios)
1697 GMStatus[i].cflag = 1688 GMStatus[i].cflag =
1698 port->normal_termios.c_cflag; 1689 port->normal_termios.c_cflag;
1699 else 1690 else
1700 GMStatus[i].cflag = 1691 GMStatus[i].cflag =
1701 port->tty->termios->c_cflag; 1692 port->port.tty->termios->c_cflag;
1702 1693
1703 status = inb(port->ioaddr + UART_MSR); 1694 status = inb(port->ioaddr + UART_MSR);
1704 if (status & 0x80 /*UART_MSR_DCD */ ) 1695 if (status & 0x80 /*UART_MSR_DCD */ )
@@ -1755,14 +1746,14 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp)
1755 mon_data_ext.modem_status[i] = 1746 mon_data_ext.modem_status[i] =
1756 port->mon_data.modem_status; 1747 port->mon_data.modem_status;
1757 mon_data_ext.baudrate[i] = 1748 mon_data_ext.baudrate[i] =
1758 tty_get_baud_rate(port->tty); 1749 tty_get_baud_rate(port->port.tty);
1759 1750
1760 if (!port->tty || !port->tty->termios) { 1751 if (!port->port.tty || !port->port.tty->termios) {
1761 cflag = port->normal_termios.c_cflag; 1752 cflag = port->normal_termios.c_cflag;
1762 iflag = port->normal_termios.c_iflag; 1753 iflag = port->normal_termios.c_iflag;
1763 } else { 1754 } else {
1764 cflag = port->tty->termios->c_cflag; 1755 cflag = port->port.tty->termios->c_cflag;
1765 iflag = port->tty->termios->c_iflag; 1756 iflag = port->port.tty->termios->c_iflag;
1766 } 1757 }
1767 1758
1768 mon_data_ext.databits[i] = cflag & CSIZE; 1759 mon_data_ext.databits[i] = cflag & CSIZE;
@@ -1989,7 +1980,7 @@ static int mxser_ioctl(struct tty_struct *tty, struct file *file,
1989 else 1980 else
1990 info->mon_data.hold_reason |= NPPI_NOTIFY_XOFFXENT; 1981 info->mon_data.hold_reason |= NPPI_NOTIFY_XOFFXENT;
1991 1982
1992 if (info->tty->hw_stopped) 1983 if (info->port.tty->hw_stopped)
1993 info->mon_data.hold_reason |= NPPI_NOTIFY_CTSHOLD; 1984 info->mon_data.hold_reason |= NPPI_NOTIFY_CTSHOLD;
1994 else 1985 else
1995 info->mon_data.hold_reason &= ~NPPI_NOTIFY_CTSHOLD; 1986 info->mon_data.hold_reason &= ~NPPI_NOTIFY_CTSHOLD;
@@ -2038,7 +2029,7 @@ static void mxser_stoprx(struct tty_struct *tty)
2038 } 2029 }
2039 } 2030 }
2040 2031
2041 if (info->tty->termios->c_cflag & CRTSCTS) { 2032 if (info->port.tty->termios->c_cflag & CRTSCTS) {
2042 info->MCR &= ~UART_MCR_RTS; 2033 info->MCR &= ~UART_MCR_RTS;
2043 outb(info->MCR, info->ioaddr + UART_MCR); 2034 outb(info->MCR, info->ioaddr + UART_MCR);
2044 } 2035 }
@@ -2075,7 +2066,7 @@ static void mxser_unthrottle(struct tty_struct *tty)
2075 } 2066 }
2076 } 2067 }
2077 2068
2078 if (info->tty->termios->c_cflag & CRTSCTS) { 2069 if (info->port.tty->termios->c_cflag & CRTSCTS) {
2079 info->MCR |= UART_MCR_RTS; 2070 info->MCR |= UART_MCR_RTS;
2080 outb(info->MCR, info->ioaddr + UART_MCR); 2071 outb(info->MCR, info->ioaddr + UART_MCR);
2081 } 2072 }
@@ -2106,7 +2097,7 @@ static void mxser_start(struct tty_struct *tty)
2106 unsigned long flags; 2097 unsigned long flags;
2107 2098
2108 spin_lock_irqsave(&info->slock, flags); 2099 spin_lock_irqsave(&info->slock, flags);
2109 if (info->xmit_cnt && info->xmit_buf) { 2100 if (info->xmit_cnt && info->port.xmit_buf) {
2110 outb(info->IER & ~UART_IER_THRI, info->ioaddr + UART_IER); 2101 outb(info->IER & ~UART_IER_THRI, info->ioaddr + UART_IER);
2111 info->IER |= UART_IER_THRI; 2102 info->IER |= UART_IER_THRI;
2112 outb(info->IER, info->ioaddr + UART_IER); 2103 outb(info->IER, info->ioaddr + UART_IER);
@@ -2219,11 +2210,10 @@ static void mxser_hangup(struct tty_struct *tty)
2219 2210
2220 mxser_flush_buffer(tty); 2211 mxser_flush_buffer(tty);
2221 mxser_shutdown(info); 2212 mxser_shutdown(info);
2222 info->event = 0; 2213 info->port.count = 0;
2223 info->count = 0; 2214 info->port.flags &= ~ASYNC_NORMAL_ACTIVE;
2224 info->flags &= ~ASYNC_NORMAL_ACTIVE; 2215 info->port.tty = NULL;
2225 info->tty = NULL; 2216 wake_up_interruptible(&info->port.open_wait);
2226 wake_up_interruptible(&info->open_wait);
2227} 2217}
2228 2218
2229/* 2219/*
@@ -2246,7 +2236,7 @@ static void mxser_rs_break(struct tty_struct *tty, int break_state)
2246 2236
2247static void mxser_receive_chars(struct mxser_port *port, int *status) 2237static void mxser_receive_chars(struct mxser_port *port, int *status)
2248{ 2238{
2249 struct tty_struct *tty = port->tty; 2239 struct tty_struct *tty = port->port.tty;
2250 unsigned char ch, gdl; 2240 unsigned char ch, gdl;
2251 int ignored = 0; 2241 int ignored = 0;
2252 int cnt = 0; 2242 int cnt = 0;
@@ -2302,7 +2292,7 @@ intr_old:
2302 flag = TTY_BREAK; 2292 flag = TTY_BREAK;
2303 port->icount.brk++; 2293 port->icount.brk++;
2304 2294
2305 if (port->flags & ASYNC_SAK) 2295 if (port->port.flags & ASYNC_SAK)
2306 do_SAK(tty); 2296 do_SAK(tty);
2307 } else if (*status & UART_LSR_PE) { 2297 } else if (*status & UART_LSR_PE) {
2308 flag = TTY_PARITY; 2298 flag = TTY_PARITY;
@@ -2333,7 +2323,7 @@ intr_old:
2333 } while (*status & UART_LSR_DR); 2323 } while (*status & UART_LSR_DR);
2334 2324
2335end_intr: 2325end_intr:
2336 mxvar_log.rxcnt[port->tty->index] += cnt; 2326 mxvar_log.rxcnt[port->port.tty->index] += cnt;
2337 port->mon_data.rxcnt += cnt; 2327 port->mon_data.rxcnt += cnt;
2338 port->mon_data.up_rxcnt += cnt; 2328 port->mon_data.up_rxcnt += cnt;
2339 2329
@@ -2354,18 +2344,18 @@ static void mxser_transmit_chars(struct mxser_port *port)
2354 if (port->x_char) { 2344 if (port->x_char) {
2355 outb(port->x_char, port->ioaddr + UART_TX); 2345 outb(port->x_char, port->ioaddr + UART_TX);
2356 port->x_char = 0; 2346 port->x_char = 0;
2357 mxvar_log.txcnt[port->tty->index]++; 2347 mxvar_log.txcnt[port->port.tty->index]++;
2358 port->mon_data.txcnt++; 2348 port->mon_data.txcnt++;
2359 port->mon_data.up_txcnt++; 2349 port->mon_data.up_txcnt++;
2360 port->icount.tx++; 2350 port->icount.tx++;
2361 return; 2351 return;
2362 } 2352 }
2363 2353
2364 if (port->xmit_buf == NULL) 2354 if (port->port.xmit_buf == NULL)
2365 return; 2355 return;
2366 2356
2367 if ((port->xmit_cnt <= 0) || port->tty->stopped || 2357 if ((port->xmit_cnt <= 0) || port->port.tty->stopped ||
2368 (port->tty->hw_stopped && 2358 (port->port.tty->hw_stopped &&
2369 (port->type != PORT_16550A) && 2359 (port->type != PORT_16550A) &&
2370 (!port->board->chip_flag))) { 2360 (!port->board->chip_flag))) {
2371 port->IER &= ~UART_IER_THRI; 2361 port->IER &= ~UART_IER_THRI;
@@ -2376,20 +2366,20 @@ static void mxser_transmit_chars(struct mxser_port *port)
2376 cnt = port->xmit_cnt; 2366 cnt = port->xmit_cnt;
2377 count = port->xmit_fifo_size; 2367 count = port->xmit_fifo_size;
2378 do { 2368 do {
2379 outb(port->xmit_buf[port->xmit_tail++], 2369 outb(port->port.xmit_buf[port->xmit_tail++],
2380 port->ioaddr + UART_TX); 2370 port->ioaddr + UART_TX);
2381 port->xmit_tail = port->xmit_tail & (SERIAL_XMIT_SIZE - 1); 2371 port->xmit_tail = port->xmit_tail & (SERIAL_XMIT_SIZE - 1);
2382 if (--port->xmit_cnt <= 0) 2372 if (--port->xmit_cnt <= 0)
2383 break; 2373 break;
2384 } while (--count > 0); 2374 } while (--count > 0);
2385 mxvar_log.txcnt[port->tty->index] += (cnt - port->xmit_cnt); 2375 mxvar_log.txcnt[port->port.tty->index] += (cnt - port->xmit_cnt);
2386 2376
2387 port->mon_data.txcnt += (cnt - port->xmit_cnt); 2377 port->mon_data.txcnt += (cnt - port->xmit_cnt);
2388 port->mon_data.up_txcnt += (cnt - port->xmit_cnt); 2378 port->mon_data.up_txcnt += (cnt - port->xmit_cnt);
2389 port->icount.tx += (cnt - port->xmit_cnt); 2379 port->icount.tx += (cnt - port->xmit_cnt);
2390 2380
2391 if (port->xmit_cnt < WAKEUP_CHARS) 2381 if (port->xmit_cnt < WAKEUP_CHARS)
2392 tty_wakeup(port->tty); 2382 tty_wakeup(port->port.tty);
2393 2383
2394 if (port->xmit_cnt <= 0) { 2384 if (port->xmit_cnt <= 0) {
2395 port->IER &= ~UART_IER_THRI; 2385 port->IER &= ~UART_IER_THRI;
@@ -2440,9 +2430,9 @@ static irqreturn_t mxser_interrupt(int irq, void *dev_id)
2440 if (iir & UART_IIR_NO_INT) 2430 if (iir & UART_IIR_NO_INT)
2441 break; 2431 break;
2442 iir &= MOXA_MUST_IIR_MASK; 2432 iir &= MOXA_MUST_IIR_MASK;
2443 if (!port->tty || 2433 if (!port->port.tty ||
2444 (port->flags & ASYNC_CLOSING) || 2434 (port->port.flags & ASYNC_CLOSING) ||
2445 !(port->flags & 2435 !(port->port.flags &
2446 ASYNC_INITIALIZED)) { 2436 ASYNC_INITIALIZED)) {
2447 status = inb(port->ioaddr + UART_LSR); 2437 status = inb(port->ioaddr + UART_LSR);
2448 outb(0x27, port->ioaddr + UART_FCR); 2438 outb(0x27, port->ioaddr + UART_FCR);
@@ -2550,6 +2540,7 @@ static int __devinit mxser_initbrd(struct mxser_board *brd,
2550 2540
2551 for (i = 0; i < brd->info->nports; i++) { 2541 for (i = 0; i < brd->info->nports; i++) {
2552 info = &brd->ports[i]; 2542 info = &brd->ports[i];
2543 tty_port_init(&info->port);
2553 info->board = brd; 2544 info->board = brd;
2554 info->stop_rx = 0; 2545 info->stop_rx = 0;
2555 info->ldisc_stop_rx = 0; 2546 info->ldisc_stop_rx = 0;
@@ -2558,16 +2549,15 @@ static int __devinit mxser_initbrd(struct mxser_board *brd,
2558 if (brd->chip_flag != MOXA_OTHER_UART) 2549 if (brd->chip_flag != MOXA_OTHER_UART)
2559 mxser_enable_must_enchance_mode(info->ioaddr); 2550 mxser_enable_must_enchance_mode(info->ioaddr);
2560 2551
2561 info->flags = ASYNC_SHARE_IRQ; 2552 info->port.flags = ASYNC_SHARE_IRQ;
2562 info->type = brd->uart_type; 2553 info->type = brd->uart_type;
2563 2554
2564 process_txrx_fifo(info); 2555 process_txrx_fifo(info);
2565 2556
2566 info->custom_divisor = info->baud_base * 16; 2557 info->custom_divisor = info->baud_base * 16;
2567 info->close_delay = 5 * HZ / 10; 2558 info->port.close_delay = 5 * HZ / 10;
2568 info->closing_wait = 30 * HZ; 2559 info->port.closing_wait = 30 * HZ;
2569 info->normal_termios = mxvar_sdriver->init_termios; 2560 info->normal_termios = mxvar_sdriver->init_termios;
2570 init_waitqueue_head(&info->open_wait);
2571 init_waitqueue_head(&info->delta_msr_wait); 2561 init_waitqueue_head(&info->delta_msr_wait);
2572 memset(&info->mon_data, 0, sizeof(struct mxser_mon)); 2562 memset(&info->mon_data, 0, sizeof(struct mxser_mon));
2573 info->err_shadow = 0; 2563 info->err_shadow = 0;
diff --git a/drivers/char/n_hdlc.c b/drivers/char/n_hdlc.c
index a35bfd7ee80e..ed4e03333ab4 100644
--- a/drivers/char/n_hdlc.c
+++ b/drivers/char/n_hdlc.c
@@ -199,7 +199,7 @@ static void n_hdlc_tty_wakeup(struct tty_struct *tty);
199#define tty2n_hdlc(tty) ((struct n_hdlc *) ((tty)->disc_data)) 199#define tty2n_hdlc(tty) ((struct n_hdlc *) ((tty)->disc_data))
200#define n_hdlc2tty(n_hdlc) ((n_hdlc)->tty) 200#define n_hdlc2tty(n_hdlc) ((n_hdlc)->tty)
201 201
202static struct tty_ldisc n_hdlc_ldisc = { 202static struct tty_ldisc_ops n_hdlc_ldisc = {
203 .owner = THIS_MODULE, 203 .owner = THIS_MODULE,
204 .magic = TTY_LDISC_MAGIC, 204 .magic = TTY_LDISC_MAGIC,
205 .name = "hdlc", 205 .name = "hdlc",
@@ -342,8 +342,8 @@ static int n_hdlc_tty_open (struct tty_struct *tty)
342#endif 342#endif
343 343
344 /* Flush any pending characters in the driver and discipline. */ 344 /* Flush any pending characters in the driver and discipline. */
345 if (tty->ldisc.flush_buffer) 345 if (tty->ldisc.ops->flush_buffer)
346 tty->ldisc.flush_buffer(tty); 346 tty->ldisc.ops->flush_buffer(tty);
347 347
348 tty_driver_flush_buffer(tty); 348 tty_driver_flush_buffer(tty);
349 349
diff --git a/drivers/char/n_r3964.c b/drivers/char/n_r3964.c
index 902169062332..ae377aa473ba 100644
--- a/drivers/char/n_r3964.c
+++ b/drivers/char/n_r3964.c
@@ -143,7 +143,7 @@ static unsigned int r3964_poll(struct tty_struct *tty, struct file *file,
143static void r3964_receive_buf(struct tty_struct *tty, const unsigned char *cp, 143static void r3964_receive_buf(struct tty_struct *tty, const unsigned char *cp,
144 char *fp, int count); 144 char *fp, int count);
145 145
146static struct tty_ldisc tty_ldisc_N_R3964 = { 146static struct tty_ldisc_ops tty_ldisc_N_R3964 = {
147 .owner = THIS_MODULE, 147 .owner = THIS_MODULE,
148 .magic = TTY_LDISC_MAGIC, 148 .magic = TTY_LDISC_MAGIC,
149 .name = "R3964", 149 .name = "R3964",
diff --git a/drivers/char/n_tty.c b/drivers/char/n_tty.c
index 8096389b0dc2..708c2b1dbe51 100644
--- a/drivers/char/n_tty.c
+++ b/drivers/char/n_tty.c
@@ -1573,7 +1573,7 @@ static unsigned int normal_poll(struct tty_struct *tty, struct file *file,
1573 return mask; 1573 return mask;
1574} 1574}
1575 1575
1576struct tty_ldisc tty_ldisc_N_TTY = { 1576struct tty_ldisc_ops tty_ldisc_N_TTY = {
1577 .magic = TTY_LDISC_MAGIC, 1577 .magic = TTY_LDISC_MAGIC,
1578 .name = "n_tty", 1578 .name = "n_tty",
1579 .open = n_tty_open, 1579 .open = n_tty_open,
diff --git a/drivers/char/nvram.c b/drivers/char/nvram.c
index 98dec380af49..a22662b6a1a5 100644
--- a/drivers/char/nvram.c
+++ b/drivers/char/nvram.c
@@ -107,6 +107,7 @@
107#include <linux/init.h> 107#include <linux/init.h>
108#include <linux/proc_fs.h> 108#include <linux/proc_fs.h>
109#include <linux/spinlock.h> 109#include <linux/spinlock.h>
110#include <linux/smp_lock.h>
110 111
111#include <asm/io.h> 112#include <asm/io.h>
112#include <asm/uaccess.h> 113#include <asm/uaccess.h>
@@ -333,12 +334,14 @@ nvram_ioctl(struct inode *inode, struct file *file,
333static int 334static int
334nvram_open(struct inode *inode, struct file *file) 335nvram_open(struct inode *inode, struct file *file)
335{ 336{
337 lock_kernel();
336 spin_lock(&nvram_state_lock); 338 spin_lock(&nvram_state_lock);
337 339
338 if ((nvram_open_cnt && (file->f_flags & O_EXCL)) || 340 if ((nvram_open_cnt && (file->f_flags & O_EXCL)) ||
339 (nvram_open_mode & NVRAM_EXCL) || 341 (nvram_open_mode & NVRAM_EXCL) ||
340 ((file->f_mode & 2) && (nvram_open_mode & NVRAM_WRITE))) { 342 ((file->f_mode & 2) && (nvram_open_mode & NVRAM_WRITE))) {
341 spin_unlock(&nvram_state_lock); 343 spin_unlock(&nvram_state_lock);
344 unlock_kernel();
342 return -EBUSY; 345 return -EBUSY;
343 } 346 }
344 347
@@ -349,6 +352,7 @@ nvram_open(struct inode *inode, struct file *file)
349 nvram_open_cnt++; 352 nvram_open_cnt++;
350 353
351 spin_unlock(&nvram_state_lock); 354 spin_unlock(&nvram_state_lock);
355 unlock_kernel();
352 356
353 return 0; 357 return 0;
354} 358}
@@ -440,7 +444,7 @@ nvram_init(void)
440 444
441 /* First test whether the driver should init at all */ 445 /* First test whether the driver should init at all */
442 if (!CHECK_DRIVER_INIT()) 446 if (!CHECK_DRIVER_INIT())
443 return -ENXIO; 447 return -ENODEV;
444 448
445 ret = misc_register(&nvram_dev); 449 ret = misc_register(&nvram_dev);
446 if (ret) { 450 if (ret) {
diff --git a/drivers/char/pc8736x_gpio.c b/drivers/char/pc8736x_gpio.c
index ecfaf180e5bd..b930de50407a 100644
--- a/drivers/char/pc8736x_gpio.c
+++ b/drivers/char/pc8736x_gpio.c
@@ -20,6 +20,7 @@
20#include <linux/mutex.h> 20#include <linux/mutex.h>
21#include <linux/nsc_gpio.h> 21#include <linux/nsc_gpio.h>
22#include <linux/platform_device.h> 22#include <linux/platform_device.h>
23#include <linux/smp_lock.h>
23#include <asm/uaccess.h> 24#include <asm/uaccess.h>
24 25
25#define DEVNAME "pc8736x_gpio" 26#define DEVNAME "pc8736x_gpio"
@@ -217,6 +218,7 @@ static int pc8736x_gpio_open(struct inode *inode, struct file *file)
217 unsigned m = iminor(inode); 218 unsigned m = iminor(inode);
218 file->private_data = &pc8736x_gpio_ops; 219 file->private_data = &pc8736x_gpio_ops;
219 220
221 cycle_kernel_lock();
220 dev_dbg(&pdev->dev, "open %d\n", m); 222 dev_dbg(&pdev->dev, "open %d\n", m);
221 223
222 if (m >= PC8736X_GPIO_CT) 224 if (m >= PC8736X_GPIO_CT)
diff --git a/drivers/char/pcmcia/cm4000_cs.c b/drivers/char/pcmcia/cm4000_cs.c
index 4a933d413423..e4a4fbd37d7a 100644
--- a/drivers/char/pcmcia/cm4000_cs.c
+++ b/drivers/char/pcmcia/cm4000_cs.c
@@ -32,8 +32,9 @@
32#include <linux/fs.h> 32#include <linux/fs.h>
33#include <linux/delay.h> 33#include <linux/delay.h>
34#include <linux/bitrev.h> 34#include <linux/bitrev.h>
35#include <asm/uaccess.h> 35#include <linux/smp_lock.h>
36#include <asm/io.h> 36#include <linux/uaccess.h>
37#include <linux/io.h>
37 38
38#include <pcmcia/cs_types.h> 39#include <pcmcia/cs_types.h>
39#include <pcmcia/cs.h> 40#include <pcmcia/cs.h>
@@ -1405,11 +1406,11 @@ static void stop_monitor(struct cm4000_dev *dev)
1405 DEBUGP(3, dev, "<- stop_monitor\n"); 1406 DEBUGP(3, dev, "<- stop_monitor\n");
1406} 1407}
1407 1408
1408static int cmm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, 1409static long cmm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
1409 unsigned long arg)
1410{ 1410{
1411 struct cm4000_dev *dev = filp->private_data; 1411 struct cm4000_dev *dev = filp->private_data;
1412 unsigned int iobase = dev->p_dev->io.BasePort1; 1412 unsigned int iobase = dev->p_dev->io.BasePort1;
1413 struct inode *inode = filp->f_path.dentry->d_inode;
1413 struct pcmcia_device *link; 1414 struct pcmcia_device *link;
1414 int size; 1415 int size;
1415 int rc; 1416 int rc;
@@ -1426,38 +1427,42 @@ static int cmm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
1426 DEBUGP(3, dev, "cmm_ioctl(device=%d.%d) %s\n", imajor(inode), 1427 DEBUGP(3, dev, "cmm_ioctl(device=%d.%d) %s\n", imajor(inode),
1427 iminor(inode), ioctl_names[_IOC_NR(cmd)]); 1428 iminor(inode), ioctl_names[_IOC_NR(cmd)]);
1428 1429
1430 lock_kernel();
1431 rc = -ENODEV;
1429 link = dev_table[iminor(inode)]; 1432 link = dev_table[iminor(inode)];
1430 if (!pcmcia_dev_present(link)) { 1433 if (!pcmcia_dev_present(link)) {
1431 DEBUGP(4, dev, "DEV_OK false\n"); 1434 DEBUGP(4, dev, "DEV_OK false\n");
1432 return -ENODEV; 1435 goto out;
1433 } 1436 }
1434 1437
1435 if (test_bit(IS_CMM_ABSENT, &dev->flags)) { 1438 if (test_bit(IS_CMM_ABSENT, &dev->flags)) {
1436 DEBUGP(4, dev, "CMM_ABSENT flag set\n"); 1439 DEBUGP(4, dev, "CMM_ABSENT flag set\n");
1437 return -ENODEV; 1440 goto out;
1438 } 1441 }
1442 rc = -EINVAL;
1439 1443
1440 if (_IOC_TYPE(cmd) != CM_IOC_MAGIC) { 1444 if (_IOC_TYPE(cmd) != CM_IOC_MAGIC) {
1441 DEBUGP(4, dev, "ioctype mismatch\n"); 1445 DEBUGP(4, dev, "ioctype mismatch\n");
1442 return -EINVAL; 1446 goto out;
1443 } 1447 }
1444 if (_IOC_NR(cmd) > CM_IOC_MAXNR) { 1448 if (_IOC_NR(cmd) > CM_IOC_MAXNR) {
1445 DEBUGP(4, dev, "iocnr mismatch\n"); 1449 DEBUGP(4, dev, "iocnr mismatch\n");
1446 return -EINVAL; 1450 goto out;
1447 } 1451 }
1448 size = _IOC_SIZE(cmd); 1452 size = _IOC_SIZE(cmd);
1449 rc = 0; 1453 rc = -EFAULT;
1450 DEBUGP(4, dev, "iocdir=%.4x iocr=%.4x iocw=%.4x iocsize=%d cmd=%.4x\n", 1454 DEBUGP(4, dev, "iocdir=%.4x iocr=%.4x iocw=%.4x iocsize=%d cmd=%.4x\n",
1451 _IOC_DIR(cmd), _IOC_READ, _IOC_WRITE, size, cmd); 1455 _IOC_DIR(cmd), _IOC_READ, _IOC_WRITE, size, cmd);
1452 1456
1453 if (_IOC_DIR(cmd) & _IOC_READ) { 1457 if (_IOC_DIR(cmd) & _IOC_READ) {
1454 if (!access_ok(VERIFY_WRITE, argp, size)) 1458 if (!access_ok(VERIFY_WRITE, argp, size))
1455 return -EFAULT; 1459 goto out;
1456 } 1460 }
1457 if (_IOC_DIR(cmd) & _IOC_WRITE) { 1461 if (_IOC_DIR(cmd) & _IOC_WRITE) {
1458 if (!access_ok(VERIFY_READ, argp, size)) 1462 if (!access_ok(VERIFY_READ, argp, size))
1459 return -EFAULT; 1463 goto out;
1460 } 1464 }
1465 rc = 0;
1461 1466
1462 switch (cmd) { 1467 switch (cmd) {
1463 case CM_IOCGSTATUS: 1468 case CM_IOCGSTATUS:
@@ -1477,9 +1482,9 @@ static int cmm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
1477 if (test_bit(IS_BAD_CARD, &dev->flags)) 1482 if (test_bit(IS_BAD_CARD, &dev->flags))
1478 status |= CM_BAD_CARD; 1483 status |= CM_BAD_CARD;
1479 if (copy_to_user(argp, &status, sizeof(int))) 1484 if (copy_to_user(argp, &status, sizeof(int)))
1480 return -EFAULT; 1485 rc = -EFAULT;
1481 } 1486 }
1482 return 0; 1487 break;
1483 case CM_IOCGATR: 1488 case CM_IOCGATR:
1484 DEBUGP(4, dev, "... in CM_IOCGATR\n"); 1489 DEBUGP(4, dev, "... in CM_IOCGATR\n");
1485 { 1490 {
@@ -1492,25 +1497,29 @@ static int cmm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
1492 || (test_bit(IS_ATR_PRESENT, (void *)&dev->flags) 1497 || (test_bit(IS_ATR_PRESENT, (void *)&dev->flags)
1493 != 0)))) { 1498 != 0)))) {
1494 if (filp->f_flags & O_NONBLOCK) 1499 if (filp->f_flags & O_NONBLOCK)
1495 return -EAGAIN; 1500 rc = -EAGAIN;
1496 return -ERESTARTSYS; 1501 else
1502 rc = -ERESTARTSYS;
1503 break;
1497 } 1504 }
1498 1505
1506 rc = -EFAULT;
1499 if (test_bit(IS_ATR_VALID, &dev->flags) == 0) { 1507 if (test_bit(IS_ATR_VALID, &dev->flags) == 0) {
1500 tmp = -1; 1508 tmp = -1;
1501 if (copy_to_user(&(atreq->atr_len), &tmp, 1509 if (copy_to_user(&(atreq->atr_len), &tmp,
1502 sizeof(int))) 1510 sizeof(int)))
1503 return -EFAULT; 1511 break;
1504 } else { 1512 } else {
1505 if (copy_to_user(atreq->atr, dev->atr, 1513 if (copy_to_user(atreq->atr, dev->atr,
1506 dev->atr_len)) 1514 dev->atr_len))
1507 return -EFAULT; 1515 break;
1508 1516
1509 tmp = dev->atr_len; 1517 tmp = dev->atr_len;
1510 if (copy_to_user(&(atreq->atr_len), &tmp, sizeof(int))) 1518 if (copy_to_user(&(atreq->atr_len), &tmp, sizeof(int)))
1511 return -EFAULT; 1519 break;
1512 } 1520 }
1513 return 0; 1521 rc = 0;
1522 break;
1514 } 1523 }
1515 case CM_IOCARDOFF: 1524 case CM_IOCARDOFF:
1516 1525
@@ -1538,8 +1547,10 @@ static int cmm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
1538 || (test_and_set_bit(LOCK_IO, (void *)&dev->flags) 1547 || (test_and_set_bit(LOCK_IO, (void *)&dev->flags)
1539 == 0)))) { 1548 == 0)))) {
1540 if (filp->f_flags & O_NONBLOCK) 1549 if (filp->f_flags & O_NONBLOCK)
1541 return -EAGAIN; 1550 rc = -EAGAIN;
1542 return -ERESTARTSYS; 1551 else
1552 rc = -ERESTARTSYS;
1553 break;
1543 } 1554 }
1544 /* Set Flags0 = 0x42 */ 1555 /* Set Flags0 = 0x42 */
1545 DEBUGP(4, dev, "Set Flags0=0x42 \n"); 1556 DEBUGP(4, dev, "Set Flags0=0x42 \n");
@@ -1554,8 +1565,10 @@ static int cmm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
1554 || (test_bit(IS_ATR_VALID, (void *)&dev->flags) != 1565 || (test_bit(IS_ATR_VALID, (void *)&dev->flags) !=
1555 0)))) { 1566 0)))) {
1556 if (filp->f_flags & O_NONBLOCK) 1567 if (filp->f_flags & O_NONBLOCK)
1557 return -EAGAIN; 1568 rc = -EAGAIN;
1558 return -ERESTARTSYS; 1569 else
1570 rc = -ERESTARTSYS;
1571 break;
1559 } 1572 }
1560 } 1573 }
1561 /* release lock */ 1574 /* release lock */
@@ -1568,8 +1581,10 @@ static int cmm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
1568 struct ptsreq krnptsreq; 1581 struct ptsreq krnptsreq;
1569 1582
1570 if (copy_from_user(&krnptsreq, argp, 1583 if (copy_from_user(&krnptsreq, argp,
1571 sizeof(struct ptsreq))) 1584 sizeof(struct ptsreq))) {
1572 return -EFAULT; 1585 rc = -EFAULT;
1586 break;
1587 }
1573 1588
1574 rc = 0; 1589 rc = 0;
1575 DEBUGP(4, dev, "... in CM_IOCSPTS\n"); 1590 DEBUGP(4, dev, "... in CM_IOCSPTS\n");
@@ -1580,8 +1595,10 @@ static int cmm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
1580 || (test_bit(IS_ATR_PRESENT, (void *)&dev->flags) 1595 || (test_bit(IS_ATR_PRESENT, (void *)&dev->flags)
1581 != 0)))) { 1596 != 0)))) {
1582 if (filp->f_flags & O_NONBLOCK) 1597 if (filp->f_flags & O_NONBLOCK)
1583 return -EAGAIN; 1598 rc = -EAGAIN;
1584 return -ERESTARTSYS; 1599 else
1600 rc = -ERESTARTSYS;
1601 break;
1585 } 1602 }
1586 /* get IO lock */ 1603 /* get IO lock */
1587 if (wait_event_interruptible 1604 if (wait_event_interruptible
@@ -1590,8 +1607,10 @@ static int cmm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
1590 || (test_and_set_bit(LOCK_IO, (void *)&dev->flags) 1607 || (test_and_set_bit(LOCK_IO, (void *)&dev->flags)
1591 == 0)))) { 1608 == 0)))) {
1592 if (filp->f_flags & O_NONBLOCK) 1609 if (filp->f_flags & O_NONBLOCK)
1593 return -EAGAIN; 1610 rc = -EAGAIN;
1594 return -ERESTARTSYS; 1611 else
1612 rc = -ERESTARTSYS;
1613 break;
1595 } 1614 }
1596 1615
1597 if ((rc = set_protocol(dev, &krnptsreq)) != 0) { 1616 if ((rc = set_protocol(dev, &krnptsreq)) != 0) {
@@ -1604,7 +1623,7 @@ static int cmm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
1604 wake_up_interruptible(&dev->ioq); 1623 wake_up_interruptible(&dev->ioq);
1605 1624
1606 } 1625 }
1607 return rc; 1626 break;
1608#ifdef PCMCIA_DEBUG 1627#ifdef PCMCIA_DEBUG
1609 case CM_IOSDBGLVL: /* set debug log level */ 1628 case CM_IOSDBGLVL: /* set debug log level */
1610 { 1629 {
@@ -1612,18 +1631,20 @@ static int cmm_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
1612 1631
1613 old_pc_debug = pc_debug; 1632 old_pc_debug = pc_debug;
1614 if (copy_from_user(&pc_debug, argp, sizeof(int))) 1633 if (copy_from_user(&pc_debug, argp, sizeof(int)))
1615 return -EFAULT; 1634 rc = -EFAULT;
1616 1635 else if (old_pc_debug != pc_debug)
1617 if (old_pc_debug != pc_debug)
1618 DEBUGP(0, dev, "Changed debug log level " 1636 DEBUGP(0, dev, "Changed debug log level "
1619 "to %i\n", pc_debug); 1637 "to %i\n", pc_debug);
1620 } 1638 }
1621 return rc; 1639 break;
1622#endif 1640#endif
1623 default: 1641 default:
1624 DEBUGP(4, dev, "... in default (unknown IOCTL code)\n"); 1642 DEBUGP(4, dev, "... in default (unknown IOCTL code)\n");
1625 return -EINVAL; 1643 rc = -ENOTTY;
1626 } 1644 }
1645out:
1646 unlock_kernel();
1647 return rc;
1627} 1648}
1628 1649
1629static int cmm_open(struct inode *inode, struct file *filp) 1650static int cmm_open(struct inode *inode, struct file *filp)
@@ -1631,16 +1652,22 @@ static int cmm_open(struct inode *inode, struct file *filp)
1631 struct cm4000_dev *dev; 1652 struct cm4000_dev *dev;
1632 struct pcmcia_device *link; 1653 struct pcmcia_device *link;
1633 int minor = iminor(inode); 1654 int minor = iminor(inode);
1655 int ret;
1634 1656
1635 if (minor >= CM4000_MAX_DEV) 1657 if (minor >= CM4000_MAX_DEV)
1636 return -ENODEV; 1658 return -ENODEV;
1637 1659
1660 lock_kernel();
1638 link = dev_table[minor]; 1661 link = dev_table[minor];
1639 if (link == NULL || !pcmcia_dev_present(link)) 1662 if (link == NULL || !pcmcia_dev_present(link)) {
1640 return -ENODEV; 1663 ret = -ENODEV;
1664 goto out;
1665 }
1641 1666
1642 if (link->open) 1667 if (link->open) {
1643 return -EBUSY; 1668 ret = -EBUSY;
1669 goto out;
1670 }
1644 1671
1645 dev = link->priv; 1672 dev = link->priv;
1646 filp->private_data = dev; 1673 filp->private_data = dev;
@@ -1660,8 +1687,10 @@ static int cmm_open(struct inode *inode, struct file *filp)
1660 * vaild = block until valid (or card 1687 * vaild = block until valid (or card
1661 * inserted) 1688 * inserted)
1662 */ 1689 */
1663 if (filp->f_flags & O_NONBLOCK) 1690 if (filp->f_flags & O_NONBLOCK) {
1664 return -EAGAIN; 1691 ret = -EAGAIN;
1692 goto out;
1693 }
1665 1694
1666 dev->mdelay = T_50MSEC; 1695 dev->mdelay = T_50MSEC;
1667 1696
@@ -1671,7 +1700,10 @@ static int cmm_open(struct inode *inode, struct file *filp)
1671 link->open = 1; /* only one open per device */ 1700 link->open = 1; /* only one open per device */
1672 1701
1673 DEBUGP(2, dev, "<- cmm_open\n"); 1702 DEBUGP(2, dev, "<- cmm_open\n");
1674 return nonseekable_open(inode, filp); 1703 ret = nonseekable_open(inode, filp);
1704out:
1705 unlock_kernel();
1706 return ret;
1675} 1707}
1676 1708
1677static int cmm_close(struct inode *inode, struct file *filp) 1709static int cmm_close(struct inode *inode, struct file *filp)
@@ -1897,7 +1929,7 @@ static const struct file_operations cm4000_fops = {
1897 .owner = THIS_MODULE, 1929 .owner = THIS_MODULE,
1898 .read = cmm_read, 1930 .read = cmm_read,
1899 .write = cmm_write, 1931 .write = cmm_write,
1900 .ioctl = cmm_ioctl, 1932 .unlocked_ioctl = cmm_ioctl,
1901 .open = cmm_open, 1933 .open = cmm_open,
1902 .release= cmm_close, 1934 .release= cmm_close,
1903}; 1935};
diff --git a/drivers/char/pcmcia/cm4040_cs.c b/drivers/char/pcmcia/cm4040_cs.c
index 035084c07329..6181f8a9b0bd 100644
--- a/drivers/char/pcmcia/cm4040_cs.c
+++ b/drivers/char/pcmcia/cm4040_cs.c
@@ -26,6 +26,7 @@
26#include <linux/fs.h> 26#include <linux/fs.h>
27#include <linux/delay.h> 27#include <linux/delay.h>
28#include <linux/poll.h> 28#include <linux/poll.h>
29#include <linux/smp_lock.h>
29#include <linux/wait.h> 30#include <linux/wait.h>
30#include <asm/uaccess.h> 31#include <asm/uaccess.h>
31#include <asm/io.h> 32#include <asm/io.h>
@@ -448,23 +449,30 @@ static int cm4040_open(struct inode *inode, struct file *filp)
448 struct reader_dev *dev; 449 struct reader_dev *dev;
449 struct pcmcia_device *link; 450 struct pcmcia_device *link;
450 int minor = iminor(inode); 451 int minor = iminor(inode);
452 int ret;
451 453
452 if (minor >= CM_MAX_DEV) 454 if (minor >= CM_MAX_DEV)
453 return -ENODEV; 455 return -ENODEV;
454 456
457 lock_kernel();
455 link = dev_table[minor]; 458 link = dev_table[minor];
456 if (link == NULL || !pcmcia_dev_present(link)) 459 if (link == NULL || !pcmcia_dev_present(link)) {
457 return -ENODEV; 460 ret = -ENODEV;
461 goto out;
462 }
458 463
459 if (link->open) 464 if (link->open) {
460 return -EBUSY; 465 ret = -EBUSY;
466 goto out;
467 }
461 468
462 dev = link->priv; 469 dev = link->priv;
463 filp->private_data = dev; 470 filp->private_data = dev;
464 471
465 if (filp->f_flags & O_NONBLOCK) { 472 if (filp->f_flags & O_NONBLOCK) {
466 DEBUGP(4, dev, "filep->f_flags O_NONBLOCK set\n"); 473 DEBUGP(4, dev, "filep->f_flags O_NONBLOCK set\n");
467 return -EAGAIN; 474 ret = -EAGAIN;
475 goto out;
468 } 476 }
469 477
470 link->open = 1; 478 link->open = 1;
@@ -473,7 +481,10 @@ static int cm4040_open(struct inode *inode, struct file *filp)
473 mod_timer(&dev->poll_timer, jiffies + POLL_PERIOD); 481 mod_timer(&dev->poll_timer, jiffies + POLL_PERIOD);
474 482
475 DEBUGP(2, dev, "<- cm4040_open (successfully)\n"); 483 DEBUGP(2, dev, "<- cm4040_open (successfully)\n");
476 return nonseekable_open(inode, filp); 484 ret = nonseekable_open(inode, filp);
485out:
486 unlock_kernel();
487 return ret;
477} 488}
478 489
479static int cm4040_close(struct inode *inode, struct file *filp) 490static int cm4040_close(struct inode *inode, struct file *filp)
diff --git a/drivers/char/pcmcia/ipwireless/hardware.c b/drivers/char/pcmcia/ipwireless/hardware.c
index fa9d3c945f31..929101ecbae2 100644
--- a/drivers/char/pcmcia/ipwireless/hardware.c
+++ b/drivers/char/pcmcia/ipwireless/hardware.c
@@ -251,10 +251,11 @@ struct ipw_hardware {
251 int init_loops; 251 int init_loops;
252 struct timer_list setup_timer; 252 struct timer_list setup_timer;
253 253
254 /* Flag if hw is ready to send next packet */
254 int tx_ready; 255 int tx_ready;
255 struct list_head tx_queue[NL_NUM_OF_PRIORITIES]; 256 /* Count of pending packets to be sent */
256 /* True if any packets are queued for transmission */
257 int tx_queued; 257 int tx_queued;
258 struct list_head tx_queue[NL_NUM_OF_PRIORITIES];
258 259
259 int rx_bytes_queued; 260 int rx_bytes_queued;
260 struct list_head rx_queue; 261 struct list_head rx_queue;
@@ -404,6 +405,8 @@ static int do_send_fragment(struct ipw_hardware *hw, const unsigned char *data,
404 405
405 spin_lock_irqsave(&hw->spinlock, flags); 406 spin_lock_irqsave(&hw->spinlock, flags);
406 407
408 hw->tx_ready = 0;
409
407 if (hw->hw_version == HW_VERSION_1) { 410 if (hw->hw_version == HW_VERSION_1) {
408 outw((unsigned short) length, hw->base_port + IODWR); 411 outw((unsigned short) length, hw->base_port + IODWR);
409 412
@@ -492,6 +495,7 @@ static int do_send_packet(struct ipw_hardware *hw, struct ipw_tx_packet *packet)
492 495
493 spin_lock_irqsave(&hw->spinlock, flags); 496 spin_lock_irqsave(&hw->spinlock, flags);
494 list_add(&packet->queue, &hw->tx_queue[0]); 497 list_add(&packet->queue, &hw->tx_queue[0]);
498 hw->tx_queued++;
495 spin_unlock_irqrestore(&hw->spinlock, flags); 499 spin_unlock_irqrestore(&hw->spinlock, flags);
496 } else { 500 } else {
497 if (packet->packet_callback) 501 if (packet->packet_callback)
@@ -586,8 +590,10 @@ static struct ipw_rx_packet *pool_allocate(struct ipw_hardware *hw,
586 packet = kmalloc(sizeof(struct ipw_rx_packet) + 590 packet = kmalloc(sizeof(struct ipw_rx_packet) +
587 old_packet->length + minimum_free_space, 591 old_packet->length + minimum_free_space,
588 GFP_ATOMIC); 592 GFP_ATOMIC);
589 if (!packet) 593 if (!packet) {
594 kfree(old_packet);
590 return NULL; 595 return NULL;
596 }
591 memcpy(packet, old_packet, 597 memcpy(packet, old_packet,
592 sizeof(struct ipw_rx_packet) 598 sizeof(struct ipw_rx_packet)
593 + old_packet->length); 599 + old_packet->length);
@@ -949,12 +955,10 @@ static int send_pending_packet(struct ipw_hardware *hw, int priority_limit)
949 unsigned long flags; 955 unsigned long flags;
950 956
951 spin_lock_irqsave(&hw->spinlock, flags); 957 spin_lock_irqsave(&hw->spinlock, flags);
952 if (hw->tx_queued && hw->tx_ready != 0) { 958 if (hw->tx_queued && hw->tx_ready) {
953 int priority; 959 int priority;
954 struct ipw_tx_packet *packet = NULL; 960 struct ipw_tx_packet *packet = NULL;
955 961
956 hw->tx_ready--;
957
958 /* Pick a packet */ 962 /* Pick a packet */
959 for (priority = 0; priority < priority_limit; priority++) { 963 for (priority = 0; priority < priority_limit; priority++) {
960 if (!list_empty(&hw->tx_queue[priority])) { 964 if (!list_empty(&hw->tx_queue[priority])) {
@@ -963,6 +967,7 @@ static int send_pending_packet(struct ipw_hardware *hw, int priority_limit)
963 struct ipw_tx_packet, 967 struct ipw_tx_packet,
964 queue); 968 queue);
965 969
970 hw->tx_queued--;
966 list_del(&packet->queue); 971 list_del(&packet->queue);
967 972
968 break; 973 break;
@@ -973,6 +978,7 @@ static int send_pending_packet(struct ipw_hardware *hw, int priority_limit)
973 spin_unlock_irqrestore(&hw->spinlock, flags); 978 spin_unlock_irqrestore(&hw->spinlock, flags);
974 return 0; 979 return 0;
975 } 980 }
981
976 spin_unlock_irqrestore(&hw->spinlock, flags); 982 spin_unlock_irqrestore(&hw->spinlock, flags);
977 983
978 /* Send */ 984 /* Send */
@@ -1063,7 +1069,7 @@ static irqreturn_t ipwireless_handle_v1_interrupt(int irq,
1063 if (irqn & IR_TXINTR) { 1069 if (irqn & IR_TXINTR) {
1064 ack |= IR_TXINTR; 1070 ack |= IR_TXINTR;
1065 spin_lock_irqsave(&hw->spinlock, flags); 1071 spin_lock_irqsave(&hw->spinlock, flags);
1066 hw->tx_ready++; 1072 hw->tx_ready = 1;
1067 spin_unlock_irqrestore(&hw->spinlock, flags); 1073 spin_unlock_irqrestore(&hw->spinlock, flags);
1068 } 1074 }
1069 /* Received data */ 1075 /* Received data */
@@ -1170,7 +1176,7 @@ static irqreturn_t ipwireless_handle_v2_v3_interrupt(int irq,
1170 if (memrxdone & MEMRX_RX_DONE) { 1176 if (memrxdone & MEMRX_RX_DONE) {
1171 writew(0, &hw->memory_info_regs->memreg_rx_done); 1177 writew(0, &hw->memory_info_regs->memreg_rx_done);
1172 spin_lock_irqsave(&hw->spinlock, flags); 1178 spin_lock_irqsave(&hw->spinlock, flags);
1173 hw->tx_ready++; 1179 hw->tx_ready = 1;
1174 spin_unlock_irqrestore(&hw->spinlock, flags); 1180 spin_unlock_irqrestore(&hw->spinlock, flags);
1175 tx = 1; 1181 tx = 1;
1176 } 1182 }
@@ -1234,7 +1240,7 @@ static void send_packet(struct ipw_hardware *hw, int priority,
1234 1240
1235 spin_lock_irqsave(&hw->spinlock, flags); 1241 spin_lock_irqsave(&hw->spinlock, flags);
1236 list_add_tail(&packet->queue, &hw->tx_queue[priority]); 1242 list_add_tail(&packet->queue, &hw->tx_queue[priority]);
1237 hw->tx_queued = 1; 1243 hw->tx_queued++;
1238 spin_unlock_irqrestore(&hw->spinlock, flags); 1244 spin_unlock_irqrestore(&hw->spinlock, flags);
1239 1245
1240 flush_packets_to_hw(hw); 1246 flush_packets_to_hw(hw);
diff --git a/drivers/char/pcmcia/ipwireless/main.c b/drivers/char/pcmcia/ipwireless/main.c
index 00c7f8407e3e..cc7dcea2d283 100644
--- a/drivers/char/pcmcia/ipwireless/main.c
+++ b/drivers/char/pcmcia/ipwireless/main.c
@@ -28,7 +28,6 @@
28#include <linux/sched.h> 28#include <linux/sched.h>
29#include <linux/slab.h> 29#include <linux/slab.h>
30 30
31#include <pcmcia/version.h>
32#include <pcmcia/cisreg.h> 31#include <pcmcia/cisreg.h>
33#include <pcmcia/device_id.h> 32#include <pcmcia/device_id.h>
34#include <pcmcia/ss.h> 33#include <pcmcia/ss.h>
diff --git a/drivers/char/pcmcia/synclink_cs.c b/drivers/char/pcmcia/synclink_cs.c
index 1dd0e992c83d..b694d430f10e 100644
--- a/drivers/char/pcmcia/synclink_cs.c
+++ b/drivers/char/pcmcia/synclink_cs.c
@@ -514,8 +514,8 @@ static void ldisc_receive_buf(struct tty_struct *tty,
514 return; 514 return;
515 ld = tty_ldisc_ref(tty); 515 ld = tty_ldisc_ref(tty);
516 if (ld) { 516 if (ld) {
517 if (ld->receive_buf) 517 if (ld->ops->receive_buf)
518 ld->receive_buf(tty, data, flags, count); 518 ld->ops->receive_buf(tty, data, flags, count);
519 tty_ldisc_deref(ld); 519 tty_ldisc_deref(ld);
520 } 520 }
521} 521}
@@ -3886,9 +3886,8 @@ static bool rx_get_frame(MGSLPC_INFO *info)
3886 framesize = 0; 3886 framesize = 0;
3887#if SYNCLINK_GENERIC_HDLC 3887#if SYNCLINK_GENERIC_HDLC
3888 { 3888 {
3889 struct net_device_stats *stats = hdlc_stats(info->netdev); 3889 info->netdev->stats.rx_errors++;
3890 stats->rx_errors++; 3890 info->netdev->stats.rx_frame_errors++;
3891 stats->rx_frame_errors++;
3892 } 3891 }
3893#endif 3892#endif
3894 } else 3893 } else
@@ -4144,7 +4143,6 @@ static int hdlcdev_attach(struct net_device *dev, unsigned short encoding,
4144static int hdlcdev_xmit(struct sk_buff *skb, struct net_device *dev) 4143static int hdlcdev_xmit(struct sk_buff *skb, struct net_device *dev)
4145{ 4144{
4146 MGSLPC_INFO *info = dev_to_port(dev); 4145 MGSLPC_INFO *info = dev_to_port(dev);
4147 struct net_device_stats *stats = hdlc_stats(dev);
4148 unsigned long flags; 4146 unsigned long flags;
4149 4147
4150 if (debug_level >= DEBUG_LEVEL_INFO) 4148 if (debug_level >= DEBUG_LEVEL_INFO)
@@ -4159,8 +4157,8 @@ static int hdlcdev_xmit(struct sk_buff *skb, struct net_device *dev)
4159 info->tx_put = info->tx_count = skb->len; 4157 info->tx_put = info->tx_count = skb->len;
4160 4158
4161 /* update network statistics */ 4159 /* update network statistics */
4162 stats->tx_packets++; 4160 dev->stats.tx_packets++;
4163 stats->tx_bytes += skb->len; 4161 dev->stats.tx_bytes += skb->len;
4164 4162
4165 /* done with socket buffer, so free it */ 4163 /* done with socket buffer, so free it */
4166 dev_kfree_skb(skb); 4164 dev_kfree_skb(skb);
@@ -4376,14 +4374,13 @@ static int hdlcdev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
4376static void hdlcdev_tx_timeout(struct net_device *dev) 4374static void hdlcdev_tx_timeout(struct net_device *dev)
4377{ 4375{
4378 MGSLPC_INFO *info = dev_to_port(dev); 4376 MGSLPC_INFO *info = dev_to_port(dev);
4379 struct net_device_stats *stats = hdlc_stats(dev);
4380 unsigned long flags; 4377 unsigned long flags;
4381 4378
4382 if (debug_level >= DEBUG_LEVEL_INFO) 4379 if (debug_level >= DEBUG_LEVEL_INFO)
4383 printk("hdlcdev_tx_timeout(%s)\n",dev->name); 4380 printk("hdlcdev_tx_timeout(%s)\n",dev->name);
4384 4381
4385 stats->tx_errors++; 4382 dev->stats.tx_errors++;
4386 stats->tx_aborted_errors++; 4383 dev->stats.tx_aborted_errors++;
4387 4384
4388 spin_lock_irqsave(&info->lock,flags); 4385 spin_lock_irqsave(&info->lock,flags);
4389 tx_stop(info); 4386 tx_stop(info);
@@ -4416,27 +4413,26 @@ static void hdlcdev_rx(MGSLPC_INFO *info, char *buf, int size)
4416{ 4413{
4417 struct sk_buff *skb = dev_alloc_skb(size); 4414 struct sk_buff *skb = dev_alloc_skb(size);
4418 struct net_device *dev = info->netdev; 4415 struct net_device *dev = info->netdev;
4419 struct net_device_stats *stats = hdlc_stats(dev);
4420 4416
4421 if (debug_level >= DEBUG_LEVEL_INFO) 4417 if (debug_level >= DEBUG_LEVEL_INFO)
4422 printk("hdlcdev_rx(%s)\n",dev->name); 4418 printk("hdlcdev_rx(%s)\n",dev->name);
4423 4419
4424 if (skb == NULL) { 4420 if (skb == NULL) {
4425 printk(KERN_NOTICE "%s: can't alloc skb, dropping packet\n", dev->name); 4421 printk(KERN_NOTICE "%s: can't alloc skb, dropping packet\n", dev->name);
4426 stats->rx_dropped++; 4422 dev->stats.rx_dropped++;
4427 return; 4423 return;
4428 } 4424 }
4429 4425
4430 memcpy(skb_put(skb, size),buf,size); 4426 memcpy(skb_put(skb, size), buf, size);
4431 4427
4432 skb->protocol = hdlc_type_trans(skb, info->netdev); 4428 skb->protocol = hdlc_type_trans(skb, dev);
4433 4429
4434 stats->rx_packets++; 4430 dev->stats.rx_packets++;
4435 stats->rx_bytes += size; 4431 dev->stats.rx_bytes += size;
4436 4432
4437 netif_rx(skb); 4433 netif_rx(skb);
4438 4434
4439 info->netdev->last_rx = jiffies; 4435 dev->last_rx = jiffies;
4440} 4436}
4441 4437
4442/** 4438/**
diff --git a/drivers/char/ppdev.c b/drivers/char/ppdev.c
index 3aab837d9480..f6e6acadd9a0 100644
--- a/drivers/char/ppdev.c
+++ b/drivers/char/ppdev.c
@@ -66,6 +66,7 @@
66#include <linux/poll.h> 66#include <linux/poll.h>
67#include <linux/major.h> 67#include <linux/major.h>
68#include <linux/ppdev.h> 68#include <linux/ppdev.h>
69#include <linux/smp_lock.h>
69#include <asm/uaccess.h> 70#include <asm/uaccess.h>
70 71
71#define PP_VERSION "ppdev: user-space parallel port driver" 72#define PP_VERSION "ppdev: user-space parallel port driver"
@@ -638,6 +639,7 @@ static int pp_open (struct inode * inode, struct file * file)
638 unsigned int minor = iminor(inode); 639 unsigned int minor = iminor(inode);
639 struct pp_struct *pp; 640 struct pp_struct *pp;
640 641
642 cycle_kernel_lock();
641 if (minor >= PARPORT_MAX) 643 if (minor >= PARPORT_MAX)
642 return -ENXIO; 644 return -ENXIO;
643 645
diff --git a/drivers/char/pty.c b/drivers/char/pty.c
index 0a05c038ae6f..76b27932d229 100644
--- a/drivers/char/pty.c
+++ b/drivers/char/pty.c
@@ -111,7 +111,7 @@ static int pty_write(struct tty_struct * tty, const unsigned char *buf, int coun
111 c = to->receive_room; 111 c = to->receive_room;
112 if (c > count) 112 if (c > count)
113 c = count; 113 c = count;
114 to->ldisc.receive_buf(to, buf, NULL, c); 114 to->ldisc.ops->receive_buf(to, buf, NULL, c);
115 115
116 return c; 116 return c;
117} 117}
@@ -149,11 +149,11 @@ static int pty_chars_in_buffer(struct tty_struct *tty)
149 int count; 149 int count;
150 150
151 /* We should get the line discipline lock for "tty->link" */ 151 /* We should get the line discipline lock for "tty->link" */
152 if (!to || !to->ldisc.chars_in_buffer) 152 if (!to || !to->ldisc.ops->chars_in_buffer)
153 return 0; 153 return 0;
154 154
155 /* The ldisc must report 0 if no characters available to be read */ 155 /* The ldisc must report 0 if no characters available to be read */
156 count = to->ldisc.chars_in_buffer(to); 156 count = to->ldisc.ops->chars_in_buffer(to);
157 157
158 if (tty->driver->subtype == PTY_TYPE_SLAVE) return count; 158 if (tty->driver->subtype == PTY_TYPE_SLAVE) return count;
159 159
@@ -186,8 +186,8 @@ static void pty_flush_buffer(struct tty_struct *tty)
186 if (!to) 186 if (!to)
187 return; 187 return;
188 188
189 if (to->ldisc.flush_buffer) 189 if (to->ldisc.ops->flush_buffer)
190 to->ldisc.flush_buffer(to); 190 to->ldisc.ops->flush_buffer(to);
191 191
192 if (to->packet) { 192 if (to->packet) {
193 spin_lock_irqsave(&tty->ctrl_lock, flags); 193 spin_lock_irqsave(&tty->ctrl_lock, flags);
diff --git a/drivers/char/raw.c b/drivers/char/raw.c
index bbfa0e241cba..505fcbe884a4 100644
--- a/drivers/char/raw.c
+++ b/drivers/char/raw.c
@@ -19,6 +19,7 @@
19#include <linux/cdev.h> 19#include <linux/cdev.h>
20#include <linux/device.h> 20#include <linux/device.h>
21#include <linux/mutex.h> 21#include <linux/mutex.h>
22#include <linux/smp_lock.h>
22 23
23#include <asm/uaccess.h> 24#include <asm/uaccess.h>
24 25
@@ -53,6 +54,7 @@ static int raw_open(struct inode *inode, struct file *filp)
53 return 0; 54 return 0;
54 } 55 }
55 56
57 lock_kernel();
56 mutex_lock(&raw_mutex); 58 mutex_lock(&raw_mutex);
57 59
58 /* 60 /*
@@ -79,6 +81,7 @@ static int raw_open(struct inode *inode, struct file *filp)
79 bdev->bd_inode->i_mapping; 81 bdev->bd_inode->i_mapping;
80 filp->private_data = bdev; 82 filp->private_data = bdev;
81 mutex_unlock(&raw_mutex); 83 mutex_unlock(&raw_mutex);
84 unlock_kernel();
82 return 0; 85 return 0;
83 86
84out2: 87out2:
diff --git a/drivers/char/rio/cirrus.h b/drivers/char/rio/cirrus.h
index a03a538a3efb..5ab51679caa2 100644
--- a/drivers/char/rio/cirrus.h
+++ b/drivers/char/rio/cirrus.h
@@ -35,9 +35,6 @@
35 ***************************************************************************/ 35 ***************************************************************************/
36 36
37#ifndef _cirrus_h 37#ifndef _cirrus_h
38#ifndef lint
39/* static char* _cirrus_h_sccs = "@(#)cirrus.h 1.16"; */
40#endif
41#define _cirrus_h 1 38#define _cirrus_h 1
42 39
43/* Bit fields for particular registers shared with driver */ 40/* Bit fields for particular registers shared with driver */
diff --git a/drivers/char/rio/cmdblk.h b/drivers/char/rio/cmdblk.h
index c46b2fdb6626..9ed4f861675a 100644
--- a/drivers/char/rio/cmdblk.h
+++ b/drivers/char/rio/cmdblk.h
@@ -33,12 +33,6 @@
33#ifndef __rio_cmdblk_h__ 33#ifndef __rio_cmdblk_h__
34#define __rio_cmdblk_h__ 34#define __rio_cmdblk_h__
35 35
36#ifdef SCCS_LABELS
37#ifndef lint
38static char *_cmdblk_h_sccs_ = "@(#)cmdblk.h 1.2";
39#endif
40#endif
41
42/* 36/*
43** the structure of a command block, used to queue commands destined for 37** the structure of a command block, used to queue commands destined for
44** a rup. 38** a rup.
diff --git a/drivers/char/rio/cmdpkt.h b/drivers/char/rio/cmdpkt.h
index 357ae5722436..c1e7a2798070 100644
--- a/drivers/char/rio/cmdpkt.h
+++ b/drivers/char/rio/cmdpkt.h
@@ -32,12 +32,6 @@
32#ifndef __rio_cmdpkt_h__ 32#ifndef __rio_cmdpkt_h__
33#define __rio_cmdpkt_h__ 33#define __rio_cmdpkt_h__
34 34
35#ifdef SCCS_LABELS
36#ifndef lint
37static char *_cmdpkt_h_sccs_ = "@(#)cmdpkt.h 1.2";
38#endif
39#endif
40
41/* 35/*
42** overlays for the data area of a packet. Used in both directions 36** overlays for the data area of a packet. Used in both directions
43** (to build a packet to send, and to interpret a packet that arrives) 37** (to build a packet to send, and to interpret a packet that arrives)
diff --git a/drivers/char/rio/daemon.h b/drivers/char/rio/daemon.h
index 6e63f8b2c479..4af90323fd00 100644
--- a/drivers/char/rio/daemon.h
+++ b/drivers/char/rio/daemon.h
@@ -33,12 +33,6 @@
33#ifndef __rio_daemon_h__ 33#ifndef __rio_daemon_h__
34#define __rio_daemon_h__ 34#define __rio_daemon_h__
35 35
36#ifdef SCCS_LABELS
37#ifndef lint
38static char *_daemon_h_sccs_ = "@(#)daemon.h 1.3";
39#endif
40#endif
41
42 36
43/* 37/*
44** structures used on /dev/rio 38** structures used on /dev/rio
diff --git a/drivers/char/rio/errors.h b/drivers/char/rio/errors.h
index 1d0d89144337..bdb05234090a 100644
--- a/drivers/char/rio/errors.h
+++ b/drivers/char/rio/errors.h
@@ -33,12 +33,6 @@
33#ifndef __rio_errors_h__ 33#ifndef __rio_errors_h__
34#define __rio_errors_h__ 34#define __rio_errors_h__
35 35
36#ifdef SCCS_LABELS
37#ifndef lint
38static char *_errors_h_sccs_ = "@(#)errors.h 1.2";
39#endif
40#endif
41
42/* 36/*
43** error codes 37** error codes
44*/ 38*/
diff --git a/drivers/char/rio/func.h b/drivers/char/rio/func.h
index 9e7283bd81a0..078d44f85e45 100644
--- a/drivers/char/rio/func.h
+++ b/drivers/char/rio/func.h
@@ -35,12 +35,6 @@
35 35
36#include <linux/kdev_t.h> 36#include <linux/kdev_t.h>
37 37
38#ifdef SCCS_LABELS
39#ifndef lint
40static char *_func_h_sccs_ = "@(#)func.h 1.3";
41#endif
42#endif
43
44/* rioboot.c */ 38/* rioboot.c */
45int RIOBootCodeRTA(struct rio_info *, struct DownLoad *); 39int RIOBootCodeRTA(struct rio_info *, struct DownLoad *);
46int RIOBootCodeHOST(struct rio_info *, struct DownLoad *); 40int RIOBootCodeHOST(struct rio_info *, struct DownLoad *);
diff --git a/drivers/char/rio/map.h b/drivers/char/rio/map.h
index bdbcd09c8b81..8366978578c1 100644
--- a/drivers/char/rio/map.h
+++ b/drivers/char/rio/map.h
@@ -33,10 +33,6 @@
33#ifndef __rio_map_h__ 33#ifndef __rio_map_h__
34#define __rio_map_h__ 34#define __rio_map_h__
35 35
36#ifdef SCCS_LABELS
37static char *_map_h_sccs_ = "@(#)map.h 1.2";
38#endif
39
40/* 36/*
41** mapping structure passed to and from the config.rio program to 37** mapping structure passed to and from the config.rio program to
42** determine the current topology of the world 38** determine the current topology of the world
diff --git a/drivers/char/rio/param.h b/drivers/char/rio/param.h
index 675c200b2459..7e9b6283e8aa 100644
--- a/drivers/char/rio/param.h
+++ b/drivers/char/rio/param.h
@@ -33,11 +33,6 @@
33#ifndef __rio_param_h__ 33#ifndef __rio_param_h__
34#define __rio_param_h__ 34#define __rio_param_h__
35 35
36#ifdef SCCS_LABELS
37static char *_param_h_sccs_ = "@(#)param.h 1.2";
38#endif
39
40
41/* 36/*
42** the param command block, as used in OPEN and PARAM calls. 37** the param command block, as used in OPEN and PARAM calls.
43*/ 38*/
diff --git a/drivers/char/rio/parmmap.h b/drivers/char/rio/parmmap.h
index 9764ef85c5a6..acc8fa439df5 100644
--- a/drivers/char/rio/parmmap.h
+++ b/drivers/char/rio/parmmap.h
@@ -37,13 +37,6 @@
37#ifndef _parmap_h 37#ifndef _parmap_h
38#define _parmap_h 38#define _parmap_h
39 39
40
41#ifdef SCCS_LABELS
42#ifndef lint
43/* static char *_rio_parmmap_h_sccs = "@(#)parmmap.h 1.4"; */
44#endif
45#endif
46
47typedef struct PARM_MAP PARM_MAP; 40typedef struct PARM_MAP PARM_MAP;
48 41
49struct PARM_MAP { 42struct PARM_MAP {
diff --git a/drivers/char/rio/pci.h b/drivers/char/rio/pci.h
index 1eba9118079b..6032f9135956 100644
--- a/drivers/char/rio/pci.h
+++ b/drivers/char/rio/pci.h
@@ -33,10 +33,6 @@
33#ifndef __rio_pci_h__ 33#ifndef __rio_pci_h__
34#define __rio_pci_h__ 34#define __rio_pci_h__
35 35
36#ifdef SCCS_LABELS
37static char *_pci_h_sccs_ = "@(#)pci.h 1.2";
38#endif
39
40/* 36/*
41** PCI stuff 37** PCI stuff
42*/ 38*/
diff --git a/drivers/char/rio/protsts.h b/drivers/char/rio/protsts.h
index 69fc4bc34153..8ab79401d3ee 100644
--- a/drivers/char/rio/protsts.h
+++ b/drivers/char/rio/protsts.h
@@ -37,13 +37,6 @@
37#ifndef _protsts_h 37#ifndef _protsts_h
38#define _protsts_h 1 38#define _protsts_h 1
39 39
40
41#ifdef SCCS_LABELS
42#ifndef lint
43/* static char *_rio_protsts_h_sccs = "@(#)protsts.h 1.4"; */
44#endif
45#endif
46
47/************************************************* 40/*************************************************
48 * ACK bit. Last Packet received OK. Set by 41 * ACK bit. Last Packet received OK. Set by
49 * rxpkt to indicate that the Packet has been 42 * rxpkt to indicate that the Packet has been
diff --git a/drivers/char/rio/rio_linux.c b/drivers/char/rio/rio_linux.c
index 412777cd1e68..0cdfee152916 100644
--- a/drivers/char/rio/rio_linux.c
+++ b/drivers/char/rio/rio_linux.c
@@ -25,11 +25,6 @@
25 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, 25 * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139,
26 * USA. 26 * USA.
27 * 27 *
28 * Revision history:
29 * $Log: rio.c,v $
30 * Revision 1.1 1999/07/11 10:13:54 wolff
31 * Initial revision
32 *
33 * */ 28 * */
34 29
35#include <linux/module.h> 30#include <linux/module.h>
@@ -436,7 +431,7 @@ static void rio_disable_tx_interrupts(void *ptr)
436{ 431{
437 func_enter(); 432 func_enter();
438 433
439 /* port->gs.flags &= ~GS_TX_INTEN; */ 434 /* port->gs.port.flags &= ~GS_TX_INTEN; */
440 435
441 func_exit(); 436 func_exit();
442} 437}
@@ -460,7 +455,7 @@ static void rio_enable_tx_interrupts(void *ptr)
460 * In general we cannot count on "tx empty" interrupts, although 455 * In general we cannot count on "tx empty" interrupts, although
461 * the interrupt routine seems to be able to tell the difference. 456 * the interrupt routine seems to be able to tell the difference.
462 */ 457 */
463 PortP->gs.flags &= ~GS_TX_INTEN; 458 PortP->gs.port.flags &= ~GS_TX_INTEN;
464 459
465 func_exit(); 460 func_exit();
466} 461}
@@ -515,7 +510,7 @@ static void rio_shutdown_port(void *ptr)
515 func_enter(); 510 func_enter();
516 511
517 PortP = (struct Port *) ptr; 512 PortP = (struct Port *) ptr;
518 PortP->gs.tty = NULL; 513 PortP->gs.port.tty = NULL;
519 func_exit(); 514 func_exit();
520} 515}
521 516
@@ -534,7 +529,7 @@ static void rio_hungup(void *ptr)
534 func_enter(); 529 func_enter();
535 530
536 PortP = (struct Port *) ptr; 531 PortP = (struct Port *) ptr;
537 PortP->gs.tty = NULL; 532 PortP->gs.port.tty = NULL;
538 533
539 func_exit(); 534 func_exit();
540} 535}
@@ -554,12 +549,12 @@ static void rio_close(void *ptr)
554 549
555 riotclose(ptr); 550 riotclose(ptr);
556 551
557 if (PortP->gs.count) { 552 if (PortP->gs.port.count) {
558 printk(KERN_ERR "WARNING port count:%d\n", PortP->gs.count); 553 printk(KERN_ERR "WARNING port count:%d\n", PortP->gs.port.count);
559 PortP->gs.count = 0; 554 PortP->gs.port.count = 0;
560 } 555 }
561 556
562 PortP->gs.tty = NULL; 557 PortP->gs.port.tty = NULL;
563 func_exit(); 558 func_exit();
564} 559}
565 560
@@ -854,8 +849,8 @@ static int rio_init_datastructures(void)
854 /* 849 /*
855 * Initializing wait queue 850 * Initializing wait queue
856 */ 851 */
857 init_waitqueue_head(&port->gs.open_wait); 852 init_waitqueue_head(&port->gs.port.open_wait);
858 init_waitqueue_head(&port->gs.close_wait); 853 init_waitqueue_head(&port->gs.port.close_wait);
859 } 854 }
860#else 855#else
861 /* We could postpone initializing them to when they are configured. */ 856 /* We could postpone initializing them to when they are configured. */
diff --git a/drivers/char/rio/rioboard.h b/drivers/char/rio/rioboard.h
index 822c071a693b..252230043c82 100644
--- a/drivers/char/rio/rioboard.h
+++ b/drivers/char/rio/rioboard.h
@@ -29,12 +29,6 @@
29/* */ 29/* */
30/************************************************************************/ 30/************************************************************************/
31 31
32/* History...
33
341.0.0 26/04/99 NPV Creation.
35
36*/
37
38#ifndef _rioboard_h /* If RIOBOARD.H not already defined */ 32#ifndef _rioboard_h /* If RIOBOARD.H not already defined */
39#define _rioboard_h 1 33#define _rioboard_h 1
40 34
diff --git a/drivers/char/rio/riocmd.c b/drivers/char/rio/riocmd.c
index 7b96e0814887..01f2654d5a2e 100644
--- a/drivers/char/rio/riocmd.c
+++ b/drivers/char/rio/riocmd.c
@@ -30,9 +30,6 @@
30** 30**
31** ----------------------------------------------------------------------------- 31** -----------------------------------------------------------------------------
32*/ 32*/
33#ifdef SCCS_LABELS
34static char *_riocmd_c_sccs_ = "@(#)riocmd.c 1.2";
35#endif
36 33
37#include <linux/module.h> 34#include <linux/module.h>
38#include <linux/slab.h> 35#include <linux/slab.h>
@@ -487,12 +484,12 @@ static int RIOCommandRup(struct rio_info *p, uint Rup, struct Host *HostP, struc
487 ** If the device is a modem, then check the modem 484 ** If the device is a modem, then check the modem
488 ** carrier. 485 ** carrier.
489 */ 486 */
490 if (PortP->gs.tty == NULL) 487 if (PortP->gs.port.tty == NULL)
491 break; 488 break;
492 if (PortP->gs.tty->termios == NULL) 489 if (PortP->gs.port.tty->termios == NULL)
493 break; 490 break;
494 491
495 if (!(PortP->gs.tty->termios->c_cflag & CLOCAL) && ((PortP->State & (RIO_MOPEN | RIO_WOPEN)))) { 492 if (!(PortP->gs.port.tty->termios->c_cflag & CLOCAL) && ((PortP->State & (RIO_MOPEN | RIO_WOPEN)))) {
496 493
497 rio_dprintk(RIO_DEBUG_CMD, "Is there a Carrier?\n"); 494 rio_dprintk(RIO_DEBUG_CMD, "Is there a Carrier?\n");
498 /* 495 /*
@@ -509,7 +506,7 @@ static int RIOCommandRup(struct rio_info *p, uint Rup, struct Host *HostP, struc
509 ** wakeup anyone in WOPEN 506 ** wakeup anyone in WOPEN
510 */ 507 */
511 if (PortP->State & (PORT_ISOPEN | RIO_WOPEN)) 508 if (PortP->State & (PORT_ISOPEN | RIO_WOPEN))
512 wake_up_interruptible(&PortP->gs.open_wait); 509 wake_up_interruptible(&PortP->gs.port.open_wait);
513 } 510 }
514 } else { 511 } else {
515 /* 512 /*
@@ -517,7 +514,7 @@ static int RIOCommandRup(struct rio_info *p, uint Rup, struct Host *HostP, struc
517 */ 514 */
518 if (PortP->State & RIO_CARR_ON) { 515 if (PortP->State & RIO_CARR_ON) {
519 if (PortP->State & (PORT_ISOPEN | RIO_WOPEN | RIO_MOPEN)) 516 if (PortP->State & (PORT_ISOPEN | RIO_WOPEN | RIO_MOPEN))
520 tty_hangup(PortP->gs.tty); 517 tty_hangup(PortP->gs.port.tty);
521 PortP->State &= ~RIO_CARR_ON; 518 PortP->State &= ~RIO_CARR_ON;
522 rio_dprintk(RIO_DEBUG_CMD, "Carrirer just went down\n"); 519 rio_dprintk(RIO_DEBUG_CMD, "Carrirer just went down\n");
523 } 520 }
diff --git a/drivers/char/rio/rioctrl.c b/drivers/char/rio/rioctrl.c
index d65ceb9a434a..eecee0f576d2 100644
--- a/drivers/char/rio/rioctrl.c
+++ b/drivers/char/rio/rioctrl.c
@@ -29,10 +29,6 @@
29** 29**
30** ----------------------------------------------------------------------------- 30** -----------------------------------------------------------------------------
31*/ 31*/
32#ifdef SCCS_LABELS
33static char *_rioctrl_c_sccs_ = "@(#)rioctrl.c 1.3";
34#endif
35
36 32
37#include <linux/module.h> 33#include <linux/module.h>
38#include <linux/slab.h> 34#include <linux/slab.h>
diff --git a/drivers/char/rio/riodrvr.h b/drivers/char/rio/riodrvr.h
index 3cffe275f216..0907e711b355 100644
--- a/drivers/char/rio/riodrvr.h
+++ b/drivers/char/rio/riodrvr.h
@@ -35,10 +35,6 @@
35 35
36#include <asm/param.h> /* for HZ */ 36#include <asm/param.h> /* for HZ */
37 37
38#ifdef SCCS_LABELS
39static char *_riodrvr_h_sccs_ = "@(#)riodrvr.h 1.3";
40#endif
41
42#define MEMDUMP_SIZE 32 38#define MEMDUMP_SIZE 32
43#define MOD_DISABLE (RIO_NOREAD|RIO_NOWRITE|RIO_NOXPRINT) 39#define MOD_DISABLE (RIO_NOREAD|RIO_NOWRITE|RIO_NOXPRINT)
44 40
diff --git a/drivers/char/rio/rioinfo.h b/drivers/char/rio/rioinfo.h
index 8de7966e603a..42ff1e79d96f 100644
--- a/drivers/char/rio/rioinfo.h
+++ b/drivers/char/rio/rioinfo.h
@@ -33,10 +33,6 @@
33#ifndef __rioinfo_h 33#ifndef __rioinfo_h
34#define __rioinfo_h 34#define __rioinfo_h
35 35
36#ifdef SCCS_LABELS
37static char *_rioinfo_h_sccs_ = "@(#)rioinfo.h 1.2";
38#endif
39
40/* 36/*
41** Host card data structure 37** Host card data structure
42*/ 38*/
diff --git a/drivers/char/rio/rioinit.c b/drivers/char/rio/rioinit.c
index add1718295ef..be0ba401966e 100644
--- a/drivers/char/rio/rioinit.c
+++ b/drivers/char/rio/rioinit.c
@@ -29,9 +29,6 @@
29** 29**
30** ----------------------------------------------------------------------------- 30** -----------------------------------------------------------------------------
31*/ 31*/
32#ifdef SCCS_LABELS
33static char *_rioinit_c_sccs_ = "@(#)rioinit.c 1.3";
34#endif
35 32
36#include <linux/module.h> 33#include <linux/module.h>
37#include <linux/slab.h> 34#include <linux/slab.h>
diff --git a/drivers/char/rio/riointr.c b/drivers/char/rio/riointr.c
index ea21686c69a4..71f87600907c 100644
--- a/drivers/char/rio/riointr.c
+++ b/drivers/char/rio/riointr.c
@@ -29,10 +29,6 @@
29** 29**
30** ----------------------------------------------------------------------------- 30** -----------------------------------------------------------------------------
31*/ 31*/
32#ifdef SCCS_LABELS
33static char *_riointr_c_sccs_ = "@(#)riointr.c 1.2";
34#endif
35
36 32
37#include <linux/module.h> 33#include <linux/module.h>
38#include <linux/slab.h> 34#include <linux/slab.h>
@@ -106,7 +102,7 @@ void RIOTxEnable(char *en)
106 102
107 PortP = (struct Port *) en; 103 PortP = (struct Port *) en;
108 p = (struct rio_info *) PortP->p; 104 p = (struct rio_info *) PortP->p;
109 tty = PortP->gs.tty; 105 tty = PortP->gs.port.tty;
110 106
111 107
112 rio_dprintk(RIO_DEBUG_INTR, "tx port %d: %d chars queued.\n", PortP->PortNum, PortP->gs.xmit_cnt); 108 rio_dprintk(RIO_DEBUG_INTR, "tx port %d: %d chars queued.\n", PortP->PortNum, PortP->gs.xmit_cnt);
@@ -162,7 +158,7 @@ void RIOTxEnable(char *en)
162 rio_spin_unlock_irqrestore(&PortP->portSem, flags); 158 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
163 159
164 if (PortP->gs.xmit_cnt <= (PortP->gs.wakeup_chars + 2 * PKT_MAX_DATA_LEN)) 160 if (PortP->gs.xmit_cnt <= (PortP->gs.wakeup_chars + 2 * PKT_MAX_DATA_LEN))
165 tty_wakeup(PortP->gs.tty); 161 tty_wakeup(PortP->gs.port.tty);
166 162
167} 163}
168 164
@@ -245,7 +241,7 @@ void RIOServiceHost(struct rio_info *p, struct Host *HostP)
245 ** find corresponding tty structure. The process of mapping 241 ** find corresponding tty structure. The process of mapping
246 ** the ports puts these here. 242 ** the ports puts these here.
247 */ 243 */
248 ttyP = PortP->gs.tty; 244 ttyP = PortP->gs.port.tty;
249 245
250 /* 246 /*
251 ** Lock the port before we begin working on it. 247 ** Lock the port before we begin working on it.
@@ -339,7 +335,7 @@ void RIOServiceHost(struct rio_info *p, struct Host *HostP)
339 ** find corresponding tty structure. The process of mapping 335 ** find corresponding tty structure. The process of mapping
340 ** the ports puts these here. 336 ** the ports puts these here.
341 */ 337 */
342 ttyP = PortP->gs.tty; 338 ttyP = PortP->gs.port.tty;
343 /* If ttyP is NULL, the port is getting closed. Forget about it. */ 339 /* If ttyP is NULL, the port is getting closed. Forget about it. */
344 if (!ttyP) { 340 if (!ttyP) {
345 rio_dprintk(RIO_DEBUG_INTR, "no tty, so skipping.\n"); 341 rio_dprintk(RIO_DEBUG_INTR, "no tty, so skipping.\n");
@@ -546,7 +542,7 @@ static void RIOReceive(struct rio_info *p, struct Port *PortP)
546 542
547 intCount++; 543 intCount++;
548 544
549 TtyP = PortP->gs.tty; 545 TtyP = PortP->gs.port.tty;
550 if (!TtyP) { 546 if (!TtyP) {
551 rio_dprintk(RIO_DEBUG_INTR, "RIOReceive: tty is null. \n"); 547 rio_dprintk(RIO_DEBUG_INTR, "RIOReceive: tty is null. \n");
552 return; 548 return;
diff --git a/drivers/char/rio/rioparam.c b/drivers/char/rio/rioparam.c
index 4810b845cc21..d687c17be152 100644
--- a/drivers/char/rio/rioparam.c
+++ b/drivers/char/rio/rioparam.c
@@ -30,10 +30,6 @@
30** ----------------------------------------------------------------------------- 30** -----------------------------------------------------------------------------
31*/ 31*/
32 32
33#ifdef SCCS_LABELS
34static char *_rioparam_c_sccs_ = "@(#)rioparam.c 1.3";
35#endif
36
37#include <linux/module.h> 33#include <linux/module.h>
38#include <linux/slab.h> 34#include <linux/slab.h>
39#include <linux/errno.h> 35#include <linux/errno.h>
@@ -164,7 +160,7 @@ int RIOParam(struct Port *PortP, int cmd, int Modem, int SleepFlag)
164 160
165 func_enter(); 161 func_enter();
166 162
167 TtyP = PortP->gs.tty; 163 TtyP = PortP->gs.port.tty;
168 164
169 rio_dprintk(RIO_DEBUG_PARAM, "RIOParam: Port:%d cmd:%d Modem:%d SleepFlag:%d Mapped: %d, tty=%p\n", PortP->PortNum, cmd, Modem, SleepFlag, PortP->Mapped, TtyP); 165 rio_dprintk(RIO_DEBUG_PARAM, "RIOParam: Port:%d cmd:%d Modem:%d SleepFlag:%d Mapped: %d, tty=%p\n", PortP->PortNum, cmd, Modem, SleepFlag, PortP->Mapped, TtyP);
170 166
diff --git a/drivers/char/rio/rioroute.c b/drivers/char/rio/rioroute.c
index 7a9df7dcf9a8..706c2a25f7aa 100644
--- a/drivers/char/rio/rioroute.c
+++ b/drivers/char/rio/rioroute.c
@@ -29,9 +29,6 @@
29** 29**
30** ----------------------------------------------------------------------------- 30** -----------------------------------------------------------------------------
31*/ 31*/
32#ifdef SCCS_LABELS
33static char *_rioroute_c_sccs_ = "@(#)rioroute.c 1.3";
34#endif
35 32
36#include <linux/module.h> 33#include <linux/module.h>
37#include <linux/slab.h> 34#include <linux/slab.h>
diff --git a/drivers/char/rio/riospace.h b/drivers/char/rio/riospace.h
index 534f1f5b9f53..ffb31d4332b9 100644
--- a/drivers/char/rio/riospace.h
+++ b/drivers/char/rio/riospace.h
@@ -33,10 +33,6 @@
33#ifndef __rio_riospace_h__ 33#ifndef __rio_riospace_h__
34#define __rio_riospace_h__ 34#define __rio_riospace_h__
35 35
36#ifdef SCCS_LABELS
37static char *_riospace_h_sccs_ = "@(#)riospace.h 1.2";
38#endif
39
40#define RIO_LOCATOR_LEN 16 36#define RIO_LOCATOR_LEN 16
41#define MAX_RIO_BOARDS 4 37#define MAX_RIO_BOARDS 4
42 38
diff --git a/drivers/char/rio/riotable.c b/drivers/char/rio/riotable.c
index 2b24488e95f2..3d15802dc0f3 100644
--- a/drivers/char/rio/riotable.c
+++ b/drivers/char/rio/riotable.c
@@ -29,9 +29,6 @@
29** 29**
30** ----------------------------------------------------------------------------- 30** -----------------------------------------------------------------------------
31*/ 31*/
32#ifdef SCCS_LABELS
33static char *_riotable_c_sccs_ = "@(#)riotable.c 1.2";
34#endif
35 32
36#include <linux/module.h> 33#include <linux/module.h>
37#include <linux/slab.h> 34#include <linux/slab.h>
diff --git a/drivers/char/rio/riotty.c b/drivers/char/rio/riotty.c
index c99354843be1..2fb49e89b324 100644
--- a/drivers/char/rio/riotty.c
+++ b/drivers/char/rio/riotty.c
@@ -29,10 +29,6 @@
29** 29**
30** ----------------------------------------------------------------------------- 30** -----------------------------------------------------------------------------
31*/ 31*/
32#ifdef SCCS_LABELS
33static char *_riotty_c_sccs_ = "@(#)riotty.c 1.3";
34#endif
35
36 32
37#define __EXPLICIT_DEF_H__ 33#define __EXPLICIT_DEF_H__
38 34
@@ -144,14 +140,14 @@ int riotopen(struct tty_struct *tty, struct file *filp)
144 140
145 tty->driver_data = PortP; 141 tty->driver_data = PortP;
146 142
147 PortP->gs.tty = tty; 143 PortP->gs.port.tty = tty;
148 PortP->gs.count++; 144 PortP->gs.port.count++;
149 145
150 rio_dprintk(RIO_DEBUG_TTY, "%d bytes in tx buffer\n", PortP->gs.xmit_cnt); 146 rio_dprintk(RIO_DEBUG_TTY, "%d bytes in tx buffer\n", PortP->gs.xmit_cnt);
151 147
152 retval = gs_init_port(&PortP->gs); 148 retval = gs_init_port(&PortP->gs);
153 if (retval) { 149 if (retval) {
154 PortP->gs.count--; 150 PortP->gs.port.count--;
155 return -ENXIO; 151 return -ENXIO;
156 } 152 }
157 /* 153 /*
@@ -297,7 +293,7 @@ int riotopen(struct tty_struct *tty, struct file *filp)
297 ** insert test for carrier here. -- ??? 293 ** insert test for carrier here. -- ???
298 ** I already see that test here. What's the deal? -- REW 294 ** I already see that test here. What's the deal? -- REW
299 */ 295 */
300 if ((PortP->gs.tty->termios->c_cflag & CLOCAL) || 296 if ((PortP->gs.port.tty->termios->c_cflag & CLOCAL) ||
301 (PortP->ModemState & RIOC_MSVR1_CD)) { 297 (PortP->ModemState & RIOC_MSVR1_CD)) {
302 rio_dprintk(RIO_DEBUG_TTY, "open(%d) Modem carr on\n", SysPort); 298 rio_dprintk(RIO_DEBUG_TTY, "open(%d) Modem carr on\n", SysPort);
303 /* 299 /*
@@ -305,16 +301,16 @@ int riotopen(struct tty_struct *tty, struct file *filp)
305 wakeup((caddr_t) &tp->tm.c_canq); 301 wakeup((caddr_t) &tp->tm.c_canq);
306 */ 302 */
307 PortP->State |= RIO_CARR_ON; 303 PortP->State |= RIO_CARR_ON;
308 wake_up_interruptible(&PortP->gs.open_wait); 304 wake_up_interruptible(&PortP->gs.port.open_wait);
309 } else { /* no carrier - wait for DCD */ 305 } else { /* no carrier - wait for DCD */
310 /* 306 /*
311 while (!(PortP->gs.tty->termios->c_state & CARR_ON) && 307 while (!(PortP->gs.port.tty->termios->c_state & CARR_ON) &&
312 !(filp->f_flags & O_NONBLOCK) && !p->RIOHalted ) 308 !(filp->f_flags & O_NONBLOCK) && !p->RIOHalted )
313 */ 309 */
314 while (!(PortP->State & RIO_CARR_ON) && !(filp->f_flags & O_NONBLOCK) && !p->RIOHalted) { 310 while (!(PortP->State & RIO_CARR_ON) && !(filp->f_flags & O_NONBLOCK) && !p->RIOHalted) {
315 rio_dprintk(RIO_DEBUG_TTY, "open(%d) sleeping for carr on\n", SysPort); 311 rio_dprintk(RIO_DEBUG_TTY, "open(%d) sleeping for carr on\n", SysPort);
316 /* 312 /*
317 PortP->gs.tty->termios->c_state |= WOPEN; 313 PortP->gs.port.tty->termios->c_state |= WOPEN;
318 */ 314 */
319 PortP->State |= RIO_WOPEN; 315 PortP->State |= RIO_WOPEN;
320 rio_spin_unlock_irqrestore(&PortP->portSem, flags); 316 rio_spin_unlock_irqrestore(&PortP->portSem, flags);
@@ -384,7 +380,7 @@ int riotclose(void *ptr)
384 /* PortP = p->RIOPortp[SysPort]; */ 380 /* PortP = p->RIOPortp[SysPort]; */
385 rio_dprintk(RIO_DEBUG_TTY, "Port is at address %p\n", PortP); 381 rio_dprintk(RIO_DEBUG_TTY, "Port is at address %p\n", PortP);
386 /* tp = PortP->TtyP; *//* Get tty */ 382 /* tp = PortP->TtyP; *//* Get tty */
387 tty = PortP->gs.tty; 383 tty = PortP->gs.port.tty;
388 rio_dprintk(RIO_DEBUG_TTY, "TTY is at address %p\n", tty); 384 rio_dprintk(RIO_DEBUG_TTY, "TTY is at address %p\n", tty);
389 385
390 if (PortP->gs.closing_wait) 386 if (PortP->gs.closing_wait)
diff --git a/drivers/char/rio/route.h b/drivers/char/rio/route.h
index 769744e575ab..20ed73f3fd7b 100644
--- a/drivers/char/rio/route.h
+++ b/drivers/char/rio/route.h
@@ -37,12 +37,6 @@
37#ifndef _route_h 37#ifndef _route_h
38#define _route_h 38#define _route_h
39 39
40#ifdef SCCS_LABELS
41#ifndef lint
42/* static char *_rio_route_h_sccs = "@(#)route.h 1.3"; */
43#endif
44#endif
45
46#define MAX_LINKS 4 40#define MAX_LINKS 4
47#define MAX_NODES 17 /* Maximum nodes in a subnet */ 41#define MAX_NODES 17 /* Maximum nodes in a subnet */
48#define NODE_BYTES ((MAX_NODES / 8) + 1) /* Number of bytes needed for 42#define NODE_BYTES ((MAX_NODES / 8) + 1) /* Number of bytes needed for
diff --git a/drivers/char/rio/unixrup.h b/drivers/char/rio/unixrup.h
index 46bd532f7746..7abf0cba0f2c 100644
--- a/drivers/char/rio/unixrup.h
+++ b/drivers/char/rio/unixrup.h
@@ -33,10 +33,6 @@
33#ifndef __rio_unixrup_h__ 33#ifndef __rio_unixrup_h__
34#define __rio_unixrup_h__ 34#define __rio_unixrup_h__
35 35
36#ifdef SCCS_LABELS
37static char *_unixrup_h_sccs_ = "@(#)unixrup.h 1.2";
38#endif
39
40/* 36/*
41** UnixRup data structure. This contains pointers to actual RUPs on the 37** UnixRup data structure. This contains pointers to actual RUPs on the
42** host card, and all the command/boot control stuff. 38** host card, and all the command/boot control stuff.
diff --git a/drivers/char/riscom8.c b/drivers/char/riscom8.c
index f073c710ab8d..724b2b20f4b2 100644
--- a/drivers/char/riscom8.c
+++ b/drivers/char/riscom8.c
@@ -322,7 +322,7 @@ static struct riscom_port *rc_get_port(struct riscom_board const *bp,
322 channel = rc_in(bp, CD180_GICR) >> GICR_CHAN_OFF; 322 channel = rc_in(bp, CD180_GICR) >> GICR_CHAN_OFF;
323 if (channel < CD180_NCH) { 323 if (channel < CD180_NCH) {
324 port = &rc_port[board_No(bp) * RC_NPORT + channel]; 324 port = &rc_port[board_No(bp) * RC_NPORT + channel];
325 if (port->flags & ASYNC_INITIALIZED) 325 if (port->port.flags & ASYNC_INITIALIZED)
326 return port; 326 return port;
327 } 327 }
328 printk(KERN_ERR "rc%d: %s interrupt from invalid port %d\n", 328 printk(KERN_ERR "rc%d: %s interrupt from invalid port %d\n",
@@ -341,7 +341,7 @@ static void rc_receive_exc(struct riscom_board const *bp)
341 if (port == NULL) 341 if (port == NULL)
342 return; 342 return;
343 343
344 tty = port->tty; 344 tty = port->port.tty;
345 345
346#ifdef RC_REPORT_OVERRUN 346#ifdef RC_REPORT_OVERRUN
347 status = rc_in(bp, CD180_RCSR); 347 status = rc_in(bp, CD180_RCSR);
@@ -364,7 +364,7 @@ static void rc_receive_exc(struct riscom_board const *bp)
364 printk(KERN_INFO "rc%d: port %d: Handling break...\n", 364 printk(KERN_INFO "rc%d: port %d: Handling break...\n",
365 board_No(bp), port_No(port)); 365 board_No(bp), port_No(port));
366 flag = TTY_BREAK; 366 flag = TTY_BREAK;
367 if (port->flags & ASYNC_SAK) 367 if (port->port.flags & ASYNC_SAK)
368 do_SAK(tty); 368 do_SAK(tty);
369 369
370 } else if (status & RCSR_PE) 370 } else if (status & RCSR_PE)
@@ -392,7 +392,7 @@ static void rc_receive(struct riscom_board const *bp)
392 if (port == NULL) 392 if (port == NULL)
393 return; 393 return;
394 394
395 tty = port->tty; 395 tty = port->port.tty;
396 396
397 count = rc_in(bp, CD180_RDCR); 397 count = rc_in(bp, CD180_RDCR);
398 398
@@ -422,7 +422,7 @@ static void rc_transmit(struct riscom_board const *bp)
422 if (port == NULL) 422 if (port == NULL)
423 return; 423 return;
424 424
425 tty = port->tty; 425 tty = port->port.tty;
426 426
427 if (port->IER & IER_TXEMPTY) { 427 if (port->IER & IER_TXEMPTY) {
428 /* FIFO drained */ 428 /* FIFO drained */
@@ -467,7 +467,7 @@ static void rc_transmit(struct riscom_board const *bp)
467 467
468 count = CD180_NFIFO; 468 count = CD180_NFIFO;
469 do { 469 do {
470 rc_out(bp, CD180_TDR, port->xmit_buf[port->xmit_tail++]); 470 rc_out(bp, CD180_TDR, port->port.xmit_buf[port->xmit_tail++]);
471 port->xmit_tail = port->xmit_tail & (SERIAL_XMIT_SIZE-1); 471 port->xmit_tail = port->xmit_tail & (SERIAL_XMIT_SIZE-1);
472 if (--port->xmit_cnt <= 0) 472 if (--port->xmit_cnt <= 0)
473 break; 473 break;
@@ -492,12 +492,12 @@ static void rc_check_modem(struct riscom_board const *bp)
492 if (port == NULL) 492 if (port == NULL)
493 return; 493 return;
494 494
495 tty = port->tty; 495 tty = port->port.tty;
496 496
497 mcr = rc_in(bp, CD180_MCR); 497 mcr = rc_in(bp, CD180_MCR);
498 if (mcr & MCR_CDCHG) { 498 if (mcr & MCR_CDCHG) {
499 if (rc_in(bp, CD180_MSVR) & MSVR_CD) 499 if (rc_in(bp, CD180_MSVR) & MSVR_CD)
500 wake_up_interruptible(&port->open_wait); 500 wake_up_interruptible(&port->port.open_wait);
501 else 501 else
502 tty_hangup(tty); 502 tty_hangup(tty);
503 } 503 }
@@ -632,15 +632,12 @@ static void rc_shutdown_board(struct riscom_board *bp)
632 */ 632 */
633static void rc_change_speed(struct riscom_board *bp, struct riscom_port *port) 633static void rc_change_speed(struct riscom_board *bp, struct riscom_port *port)
634{ 634{
635 struct tty_struct *tty = port->tty; 635 struct tty_struct *tty = port->port.tty;
636 unsigned long baud; 636 unsigned long baud;
637 long tmp; 637 long tmp;
638 unsigned char cor1 = 0, cor3 = 0; 638 unsigned char cor1 = 0, cor3 = 0;
639 unsigned char mcor1 = 0, mcor2 = 0; 639 unsigned char mcor1 = 0, mcor2 = 0;
640 640
641 if (tty == NULL || tty->termios == NULL)
642 return;
643
644 port->IER = 0; 641 port->IER = 0;
645 port->COR2 = 0; 642 port->COR2 = 0;
646 port->MSVR = MSVR_RTS; 643 port->MSVR = MSVR_RTS;
@@ -786,39 +783,30 @@ static int rc_setup_port(struct riscom_board *bp, struct riscom_port *port)
786{ 783{
787 unsigned long flags; 784 unsigned long flags;
788 785
789 if (port->flags & ASYNC_INITIALIZED) 786 if (port->port.flags & ASYNC_INITIALIZED)
790 return 0; 787 return 0;
791 788
792 if (!port->xmit_buf) { 789 if (tty_port_alloc_xmit_buf(&port->port) < 0)
793 /* We may sleep in get_zeroed_page() */ 790 return -ENOMEM;
794 unsigned long tmp = get_zeroed_page(GFP_KERNEL); 791
795 if (tmp == 0)
796 return -ENOMEM;
797 if (port->xmit_buf)
798 free_page(tmp);
799 else
800 port->xmit_buf = (unsigned char *) tmp;
801 }
802 spin_lock_irqsave(&riscom_lock, flags); 792 spin_lock_irqsave(&riscom_lock, flags);
803 793
804 if (port->tty) 794 clear_bit(TTY_IO_ERROR, &port->port.tty->flags);
805 clear_bit(TTY_IO_ERROR, &port->tty->flags); 795 if (port->port.count == 1)
806 if (port->count == 1)
807 bp->count++; 796 bp->count++;
808 port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; 797 port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
809 rc_change_speed(bp, port); 798 rc_change_speed(bp, port);
810 port->flags |= ASYNC_INITIALIZED; 799 port->port.flags |= ASYNC_INITIALIZED;
811 800
812 spin_unlock_irqrestore(&riscom_lock, flags); 801 spin_unlock_irqrestore(&riscom_lock, flags);
813 return 0; 802 return 0;
814} 803}
815 804
816/* Must be called with interrupts disabled */ 805/* Must be called with interrupts disabled */
817static void rc_shutdown_port(struct riscom_board *bp, struct riscom_port *port) 806static void rc_shutdown_port(struct tty_struct *tty,
807 struct riscom_board *bp, struct riscom_port *port)
818{ 808{
819 struct tty_struct *tty; 809 if (!(port->port.flags & ASYNC_INITIALIZED))
820
821 if (!(port->flags & ASYNC_INITIALIZED))
822 return; 810 return;
823 811
824#ifdef RC_REPORT_OVERRUN 812#ifdef RC_REPORT_OVERRUN
@@ -836,14 +824,8 @@ static void rc_shutdown_port(struct riscom_board *bp, struct riscom_port *port)
836 printk("].\n"); 824 printk("].\n");
837 } 825 }
838#endif 826#endif
839 if (port->xmit_buf) { 827 tty_port_free_xmit_buf(&port->port);
840 free_page((unsigned long) port->xmit_buf); 828 if (C_HUPCL(tty)) {
841 port->xmit_buf = NULL;
842 }
843
844 tty = port->tty;
845
846 if (tty == NULL || C_HUPCL(tty)) {
847 /* Drop DTR */ 829 /* Drop DTR */
848 bp->DTR |= (1u << port_No(port)); 830 bp->DTR |= (1u << port_No(port));
849 rc_out(bp, RC_DTR, bp->DTR); 831 rc_out(bp, RC_DTR, bp->DTR);
@@ -858,9 +840,8 @@ static void rc_shutdown_port(struct riscom_board *bp, struct riscom_port *port)
858 port->IER = 0; 840 port->IER = 0;
859 rc_out(bp, CD180_IER, port->IER); 841 rc_out(bp, CD180_IER, port->IER);
860 842
861 if (tty) 843 set_bit(TTY_IO_ERROR, &tty->flags);
862 set_bit(TTY_IO_ERROR, &tty->flags); 844 port->port.flags &= ~ASYNC_INITIALIZED;
863 port->flags &= ~ASYNC_INITIALIZED;
864 845
865 if (--bp->count < 0) { 846 if (--bp->count < 0) {
866 printk(KERN_INFO "rc%d: rc_shutdown_port: " 847 printk(KERN_INFO "rc%d: rc_shutdown_port: "
@@ -890,9 +871,9 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
890 * If the device is in the middle of being closed, then block 871 * If the device is in the middle of being closed, then block
891 * until it's done, and then try again. 872 * until it's done, and then try again.
892 */ 873 */
893 if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) { 874 if (tty_hung_up_p(filp) || port->port.flags & ASYNC_CLOSING) {
894 interruptible_sleep_on(&port->close_wait); 875 interruptible_sleep_on(&port->port.close_wait);
895 if (port->flags & ASYNC_HUP_NOTIFY) 876 if (port->port.flags & ASYNC_HUP_NOTIFY)
896 return -EAGAIN; 877 return -EAGAIN;
897 else 878 else
898 return -ERESTARTSYS; 879 return -ERESTARTSYS;
@@ -904,7 +885,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
904 */ 885 */
905 if ((filp->f_flags & O_NONBLOCK) || 886 if ((filp->f_flags & O_NONBLOCK) ||
906 (tty->flags & (1 << TTY_IO_ERROR))) { 887 (tty->flags & (1 << TTY_IO_ERROR))) {
907 port->flags |= ASYNC_NORMAL_ACTIVE; 888 port->port.flags |= ASYNC_NORMAL_ACTIVE;
908 return 0; 889 return 0;
909 } 890 }
910 891
@@ -919,16 +900,16 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
919 * exit, either normal or abnormal. 900 * exit, either normal or abnormal.
920 */ 901 */
921 retval = 0; 902 retval = 0;
922 add_wait_queue(&port->open_wait, &wait); 903 add_wait_queue(&port->port.open_wait, &wait);
923 904
924 spin_lock_irqsave(&riscom_lock, flags); 905 spin_lock_irqsave(&riscom_lock, flags);
925 906
926 if (!tty_hung_up_p(filp)) 907 if (!tty_hung_up_p(filp))
927 port->count--; 908 port->port.count--;
928 909
929 spin_unlock_irqrestore(&riscom_lock, flags); 910 spin_unlock_irqrestore(&riscom_lock, flags);
930 911
931 port->blocked_open++; 912 port->port.blocked_open++;
932 while (1) { 913 while (1) {
933 spin_lock_irqsave(&riscom_lock, flags); 914 spin_lock_irqsave(&riscom_lock, flags);
934 915
@@ -942,14 +923,14 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
942 923
943 set_current_state(TASK_INTERRUPTIBLE); 924 set_current_state(TASK_INTERRUPTIBLE);
944 if (tty_hung_up_p(filp) || 925 if (tty_hung_up_p(filp) ||
945 !(port->flags & ASYNC_INITIALIZED)) { 926 !(port->port.flags & ASYNC_INITIALIZED)) {
946 if (port->flags & ASYNC_HUP_NOTIFY) 927 if (port->port.flags & ASYNC_HUP_NOTIFY)
947 retval = -EAGAIN; 928 retval = -EAGAIN;
948 else 929 else
949 retval = -ERESTARTSYS; 930 retval = -ERESTARTSYS;
950 break; 931 break;
951 } 932 }
952 if (!(port->flags & ASYNC_CLOSING) && 933 if (!(port->port.flags & ASYNC_CLOSING) &&
953 (do_clocal || CD)) 934 (do_clocal || CD))
954 break; 935 break;
955 if (signal_pending(current)) { 936 if (signal_pending(current)) {
@@ -959,14 +940,14 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
959 schedule(); 940 schedule();
960 } 941 }
961 __set_current_state(TASK_RUNNING); 942 __set_current_state(TASK_RUNNING);
962 remove_wait_queue(&port->open_wait, &wait); 943 remove_wait_queue(&port->port.open_wait, &wait);
963 if (!tty_hung_up_p(filp)) 944 if (!tty_hung_up_p(filp))
964 port->count++; 945 port->port.count++;
965 port->blocked_open--; 946 port->port.blocked_open--;
966 if (retval) 947 if (retval)
967 return retval; 948 return retval;
968 949
969 port->flags |= ASYNC_NORMAL_ACTIVE; 950 port->port.flags |= ASYNC_NORMAL_ACTIVE;
970 return 0; 951 return 0;
971} 952}
972 953
@@ -990,9 +971,9 @@ static int rc_open(struct tty_struct *tty, struct file *filp)
990 if (error) 971 if (error)
991 return error; 972 return error;
992 973
993 port->count++; 974 port->port.count++;
994 tty->driver_data = port; 975 tty->driver_data = port;
995 port->tty = tty; 976 port->port.tty = tty;
996 977
997 error = rc_setup_port(bp, port); 978 error = rc_setup_port(bp, port);
998 if (error == 0) 979 if (error == 0)
@@ -1031,28 +1012,28 @@ static void rc_close(struct tty_struct *tty, struct file *filp)
1031 goto out; 1012 goto out;
1032 1013
1033 bp = port_Board(port); 1014 bp = port_Board(port);
1034 if ((tty->count == 1) && (port->count != 1)) { 1015 if ((tty->count == 1) && (port->port.count != 1)) {
1035 printk(KERN_INFO "rc%d: rc_close: bad port count;" 1016 printk(KERN_INFO "rc%d: rc_close: bad port count;"
1036 " tty->count is 1, port count is %d\n", 1017 " tty->count is 1, port count is %d\n",
1037 board_No(bp), port->count); 1018 board_No(bp), port->port.count);
1038 port->count = 1; 1019 port->port.count = 1;
1039 } 1020 }
1040 if (--port->count < 0) { 1021 if (--port->port.count < 0) {
1041 printk(KERN_INFO "rc%d: rc_close: bad port count " 1022 printk(KERN_INFO "rc%d: rc_close: bad port count "
1042 "for tty%d: %d\n", 1023 "for tty%d: %d\n",
1043 board_No(bp), port_No(port), port->count); 1024 board_No(bp), port_No(port), port->port.count);
1044 port->count = 0; 1025 port->port.count = 0;
1045 } 1026 }
1046 if (port->count) 1027 if (port->port.count)
1047 goto out; 1028 goto out;
1048 port->flags |= ASYNC_CLOSING; 1029 port->port.flags |= ASYNC_CLOSING;
1049 /* 1030 /*
1050 * Now we wait for the transmit buffer to clear; and we notify 1031 * Now we wait for the transmit buffer to clear; and we notify
1051 * the line discipline to only process XON/XOFF characters. 1032 * the line discipline to only process XON/XOFF characters.
1052 */ 1033 */
1053 tty->closing = 1; 1034 tty->closing = 1;
1054 if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE) 1035 if (port->port.closing_wait != ASYNC_CLOSING_WAIT_NONE)
1055 tty_wait_until_sent(tty, port->closing_wait); 1036 tty_wait_until_sent(tty, port->port.closing_wait);
1056 /* 1037 /*
1057 * At this point we stop accepting input. To do this, we 1038 * At this point we stop accepting input. To do this, we
1058 * disable the receive line status interrupts, and tell the 1039 * disable the receive line status interrupts, and tell the
@@ -1060,7 +1041,7 @@ static void rc_close(struct tty_struct *tty, struct file *filp)
1060 * line status register. 1041 * line status register.
1061 */ 1042 */
1062 port->IER &= ~IER_RXD; 1043 port->IER &= ~IER_RXD;
1063 if (port->flags & ASYNC_INITIALIZED) { 1044 if (port->port.flags & ASYNC_INITIALIZED) {
1064 port->IER &= ~IER_TXRDY; 1045 port->IER &= ~IER_TXRDY;
1065 port->IER |= IER_TXEMPTY; 1046 port->IER |= IER_TXEMPTY;
1066 rc_out(bp, CD180_CAR, port_No(port)); 1047 rc_out(bp, CD180_CAR, port_No(port));
@@ -1077,19 +1058,19 @@ static void rc_close(struct tty_struct *tty, struct file *filp)
1077 break; 1058 break;
1078 } 1059 }
1079 } 1060 }
1080 rc_shutdown_port(bp, port); 1061 rc_shutdown_port(tty, bp, port);
1081 rc_flush_buffer(tty); 1062 rc_flush_buffer(tty);
1082 tty_ldisc_flush(tty); 1063 tty_ldisc_flush(tty);
1083 1064
1084 tty->closing = 0; 1065 tty->closing = 0;
1085 port->tty = NULL; 1066 port->port.tty = NULL;
1086 if (port->blocked_open) { 1067 if (port->port.blocked_open) {
1087 if (port->close_delay) 1068 if (port->port.close_delay)
1088 msleep_interruptible(jiffies_to_msecs(port->close_delay)); 1069 msleep_interruptible(jiffies_to_msecs(port->port.close_delay));
1089 wake_up_interruptible(&port->open_wait); 1070 wake_up_interruptible(&port->port.open_wait);
1090 } 1071 }
1091 port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); 1072 port->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
1092 wake_up_interruptible(&port->close_wait); 1073 wake_up_interruptible(&port->port.close_wait);
1093 1074
1094out: 1075out:
1095 spin_unlock_irqrestore(&riscom_lock, flags); 1076 spin_unlock_irqrestore(&riscom_lock, flags);
@@ -1108,9 +1089,6 @@ static int rc_write(struct tty_struct *tty,
1108 1089
1109 bp = port_Board(port); 1090 bp = port_Board(port);
1110 1091
1111 if (!tty || !port->xmit_buf)
1112 return 0;
1113
1114 while (1) { 1092 while (1) {
1115 spin_lock_irqsave(&riscom_lock, flags); 1093 spin_lock_irqsave(&riscom_lock, flags);
1116 1094
@@ -1119,7 +1097,7 @@ static int rc_write(struct tty_struct *tty,
1119 if (c <= 0) 1097 if (c <= 0)
1120 break; /* lock continues to be held */ 1098 break; /* lock continues to be held */
1121 1099
1122 memcpy(port->xmit_buf + port->xmit_head, buf, c); 1100 memcpy(port->port.xmit_buf + port->xmit_head, buf, c);
1123 port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1); 1101 port->xmit_head = (port->xmit_head + c) & (SERIAL_XMIT_SIZE-1);
1124 port->xmit_cnt += c; 1102 port->xmit_cnt += c;
1125 1103
@@ -1151,15 +1129,12 @@ static int rc_put_char(struct tty_struct *tty, unsigned char ch)
1151 if (rc_paranoia_check(port, tty->name, "rc_put_char")) 1129 if (rc_paranoia_check(port, tty->name, "rc_put_char"))
1152 return 0; 1130 return 0;
1153 1131
1154 if (!tty || !port->xmit_buf)
1155 return 0;
1156
1157 spin_lock_irqsave(&riscom_lock, flags); 1132 spin_lock_irqsave(&riscom_lock, flags);
1158 1133
1159 if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1) 1134 if (port->xmit_cnt >= SERIAL_XMIT_SIZE - 1)
1160 goto out; 1135 goto out;
1161 1136
1162 port->xmit_buf[port->xmit_head++] = ch; 1137 port->port.xmit_buf[port->xmit_head++] = ch;
1163 port->xmit_head &= SERIAL_XMIT_SIZE - 1; 1138 port->xmit_head &= SERIAL_XMIT_SIZE - 1;
1164 port->xmit_cnt++; 1139 port->xmit_cnt++;
1165 ret = 1; 1140 ret = 1;
@@ -1177,8 +1152,7 @@ static void rc_flush_chars(struct tty_struct *tty)
1177 if (rc_paranoia_check(port, tty->name, "rc_flush_chars")) 1152 if (rc_paranoia_check(port, tty->name, "rc_flush_chars"))
1178 return; 1153 return;
1179 1154
1180 if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || 1155 if (port->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped)
1181 !port->xmit_buf)
1182 return; 1156 return;
1183 1157
1184 spin_lock_irqsave(&riscom_lock, flags); 1158 spin_lock_irqsave(&riscom_lock, flags);
@@ -1317,22 +1291,22 @@ static int rc_set_serial_info(struct riscom_port *port,
1317 return -EINVAL; 1291 return -EINVAL;
1318#endif 1292#endif
1319 1293
1320 change_speed = ((port->flags & ASYNC_SPD_MASK) != 1294 change_speed = ((port->port.flags & ASYNC_SPD_MASK) !=
1321 (tmp.flags & ASYNC_SPD_MASK)); 1295 (tmp.flags & ASYNC_SPD_MASK));
1322 1296
1323 if (!capable(CAP_SYS_ADMIN)) { 1297 if (!capable(CAP_SYS_ADMIN)) {
1324 if ((tmp.close_delay != port->close_delay) || 1298 if ((tmp.close_delay != port->port.close_delay) ||
1325 (tmp.closing_wait != port->closing_wait) || 1299 (tmp.closing_wait != port->port.closing_wait) ||
1326 ((tmp.flags & ~ASYNC_USR_MASK) != 1300 ((tmp.flags & ~ASYNC_USR_MASK) !=
1327 (port->flags & ~ASYNC_USR_MASK))) 1301 (port->port.flags & ~ASYNC_USR_MASK)))
1328 return -EPERM; 1302 return -EPERM;
1329 port->flags = ((port->flags & ~ASYNC_USR_MASK) | 1303 port->port.flags = ((port->port.flags & ~ASYNC_USR_MASK) |
1330 (tmp.flags & ASYNC_USR_MASK)); 1304 (tmp.flags & ASYNC_USR_MASK));
1331 } else { 1305 } else {
1332 port->flags = ((port->flags & ~ASYNC_FLAGS) | 1306 port->port.flags = ((port->port.flags & ~ASYNC_FLAGS) |
1333 (tmp.flags & ASYNC_FLAGS)); 1307 (tmp.flags & ASYNC_FLAGS));
1334 port->close_delay = tmp.close_delay; 1308 port->port.close_delay = tmp.close_delay;
1335 port->closing_wait = tmp.closing_wait; 1309 port->port.closing_wait = tmp.closing_wait;
1336 } 1310 }
1337 if (change_speed) { 1311 if (change_speed) {
1338 unsigned long flags; 1312 unsigned long flags;
@@ -1355,10 +1329,10 @@ static int rc_get_serial_info(struct riscom_port *port,
1355 tmp.line = port - rc_port; 1329 tmp.line = port - rc_port;
1356 tmp.port = bp->base; 1330 tmp.port = bp->base;
1357 tmp.irq = bp->irq; 1331 tmp.irq = bp->irq;
1358 tmp.flags = port->flags; 1332 tmp.flags = port->port.flags;
1359 tmp.baud_base = (RC_OSCFREQ + CD180_TPC/2) / CD180_TPC; 1333 tmp.baud_base = (RC_OSCFREQ + CD180_TPC/2) / CD180_TPC;
1360 tmp.close_delay = port->close_delay * HZ/100; 1334 tmp.close_delay = port->port.close_delay * HZ/100;
1361 tmp.closing_wait = port->closing_wait * HZ/100; 1335 tmp.closing_wait = port->port.closing_wait * HZ/100;
1362 tmp.xmit_fifo_size = CD180_NFIFO; 1336 tmp.xmit_fifo_size = CD180_NFIFO;
1363 return copy_to_user(retinfo, &tmp, sizeof(tmp)) ? -EFAULT : 0; 1337 return copy_to_user(retinfo, &tmp, sizeof(tmp)) ? -EFAULT : 0;
1364} 1338}
@@ -1480,7 +1454,7 @@ static void rc_start(struct tty_struct *tty)
1480 1454
1481 spin_lock_irqsave(&riscom_lock, flags); 1455 spin_lock_irqsave(&riscom_lock, flags);
1482 1456
1483 if (port->xmit_cnt && port->xmit_buf && !(port->IER & IER_TXRDY)) { 1457 if (port->xmit_cnt && port->port.xmit_buf && !(port->IER & IER_TXRDY)) {
1484 port->IER |= IER_TXRDY; 1458 port->IER |= IER_TXRDY;
1485 rc_out(bp, CD180_CAR, port_No(port)); 1459 rc_out(bp, CD180_CAR, port_No(port));
1486 rc_out(bp, CD180_IER, port->IER); 1460 rc_out(bp, CD180_IER, port->IER);
@@ -1498,11 +1472,11 @@ static void rc_hangup(struct tty_struct *tty)
1498 1472
1499 bp = port_Board(port); 1473 bp = port_Board(port);
1500 1474
1501 rc_shutdown_port(bp, port); 1475 rc_shutdown_port(tty, bp, port);
1502 port->count = 0; 1476 port->port.count = 0;
1503 port->flags &= ~ASYNC_NORMAL_ACTIVE; 1477 port->port.flags &= ~ASYNC_NORMAL_ACTIVE;
1504 port->tty = NULL; 1478 port->port.tty = NULL;
1505 wake_up_interruptible(&port->open_wait); 1479 wake_up_interruptible(&port->port.open_wait);
1506} 1480}
1507 1481
1508static void rc_set_termios(struct tty_struct *tty, 1482static void rc_set_termios(struct tty_struct *tty,
@@ -1575,11 +1549,8 @@ static int __init rc_init_drivers(void)
1575 } 1549 }
1576 memset(rc_port, 0, sizeof(rc_port)); 1550 memset(rc_port, 0, sizeof(rc_port));
1577 for (i = 0; i < RC_NPORT * RC_NBOARD; i++) { 1551 for (i = 0; i < RC_NPORT * RC_NBOARD; i++) {
1552 tty_port_init(&rc_port[i].port);
1578 rc_port[i].magic = RISCOM8_MAGIC; 1553 rc_port[i].magic = RISCOM8_MAGIC;
1579 rc_port[i].close_delay = 50 * HZ / 100;
1580 rc_port[i].closing_wait = 3000 * HZ / 100;
1581 init_waitqueue_head(&rc_port[i].open_wait);
1582 init_waitqueue_head(&rc_port[i].close_wait);
1583 } 1554 }
1584 return 0; 1555 return 0;
1585} 1556}
diff --git a/drivers/char/riscom8.h b/drivers/char/riscom8.h
index cdfdf4394477..c9876b3f9714 100644
--- a/drivers/char/riscom8.h
+++ b/drivers/char/riscom8.h
@@ -66,23 +66,15 @@ struct riscom_board {
66 66
67struct riscom_port { 67struct riscom_port {
68 int magic; 68 int magic;
69 struct tty_port port;
69 int baud_base; 70 int baud_base;
70 int flags;
71 struct tty_struct * tty;
72 int count;
73 int blocked_open;
74 int timeout; 71 int timeout;
75 int close_delay;
76 unsigned char * xmit_buf;
77 int custom_divisor; 72 int custom_divisor;
78 int xmit_head; 73 int xmit_head;
79 int xmit_tail; 74 int xmit_tail;
80 int xmit_cnt; 75 int xmit_cnt;
81 wait_queue_head_t open_wait;
82 wait_queue_head_t close_wait;
83 short wakeup_chars; 76 short wakeup_chars;
84 short break_length; 77 short break_length;
85 unsigned short closing_wait;
86 unsigned char mark_mask; 78 unsigned char mark_mask;
87 unsigned char IER; 79 unsigned char IER;
88 unsigned char MSVR; 80 unsigned char MSVR;
diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c
index 743dc80a9325..e670eae2f510 100644
--- a/drivers/char/rocket.c
+++ b/drivers/char/rocket.c
@@ -72,6 +72,7 @@
72#include <linux/tty.h> 72#include <linux/tty.h>
73#include <linux/tty_driver.h> 73#include <linux/tty_driver.h>
74#include <linux/tty_flip.h> 74#include <linux/tty_flip.h>
75#include <linux/serial.h>
75#include <linux/string.h> 76#include <linux/string.h>
76#include <linux/fcntl.h> 77#include <linux/fcntl.h>
77#include <linux/ptrace.h> 78#include <linux/ptrace.h>
@@ -81,7 +82,7 @@
81#include <linux/completion.h> 82#include <linux/completion.h>
82#include <linux/wait.h> 83#include <linux/wait.h>
83#include <linux/pci.h> 84#include <linux/pci.h>
84#include <asm/uaccess.h> 85#include <linux/uaccess.h>
85#include <asm/atomic.h> 86#include <asm/atomic.h>
86#include <asm/unaligned.h> 87#include <asm/unaligned.h>
87#include <linux/bitops.h> 88#include <linux/bitops.h>
@@ -434,15 +435,15 @@ static void rp_do_transmit(struct r_port *info)
434#endif 435#endif
435 if (!info) 436 if (!info)
436 return; 437 return;
437 if (!info->tty) { 438 if (!info->port.tty) {
438 printk(KERN_WARNING "rp: WARNING %s called with " 439 printk(KERN_WARNING "rp: WARNING %s called with "
439 "info->tty==NULL\n", __func__); 440 "info->port.tty==NULL\n", __func__);
440 clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]); 441 clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
441 return; 442 return;
442 } 443 }
443 444
444 spin_lock_irqsave(&info->slock, flags); 445 spin_lock_irqsave(&info->slock, flags);
445 tty = info->tty; 446 tty = info->port.tty;
446 info->xmit_fifo_room = TXFIFO_SIZE - sGetTxCnt(cp); 447 info->xmit_fifo_room = TXFIFO_SIZE - sGetTxCnt(cp);
447 448
448 /* Loop sending data to FIFO until done or FIFO full */ 449 /* Loop sending data to FIFO until done or FIFO full */
@@ -502,13 +503,13 @@ static void rp_handle_port(struct r_port *info)
502 "info->flags & NOT_INIT\n"); 503 "info->flags & NOT_INIT\n");
503 return; 504 return;
504 } 505 }
505 if (!info->tty) { 506 if (!info->port.tty) {
506 printk(KERN_WARNING "rp: WARNING: rp_handle_port called with " 507 printk(KERN_WARNING "rp: WARNING: rp_handle_port called with "
507 "info->tty==NULL\n"); 508 "info->port.tty==NULL\n");
508 return; 509 return;
509 } 510 }
510 cp = &info->channel; 511 cp = &info->channel;
511 tty = info->tty; 512 tty = info->port.tty;
512 513
513 IntMask = sGetChanIntID(cp) & info->intmask; 514 IntMask = sGetChanIntID(cp) & info->intmask;
514#ifdef ROCKET_DEBUG_INTR 515#ifdef ROCKET_DEBUG_INTR
@@ -530,7 +531,7 @@ static void rp_handle_port(struct r_port *info)
530 tty_hangup(tty); 531 tty_hangup(tty);
531 } 532 }
532 info->cd_status = (ChanStatus & CD_ACT) ? 1 : 0; 533 info->cd_status = (ChanStatus & CD_ACT) ? 1 : 0;
533 wake_up_interruptible(&info->open_wait); 534 wake_up_interruptible(&info->port.open_wait);
534 } 535 }
535#ifdef ROCKET_DEBUG_INTR 536#ifdef ROCKET_DEBUG_INTR
536 if (IntMask & DELTA_CTS) { /* CTS change */ 537 if (IntMask & DELTA_CTS) { /* CTS change */
@@ -648,9 +649,9 @@ static void init_r_port(int board, int aiop, int chan, struct pci_dev *pci_dev)
648 info->board = board; 649 info->board = board;
649 info->aiop = aiop; 650 info->aiop = aiop;
650 info->chan = chan; 651 info->chan = chan;
651 info->closing_wait = 3000; 652 info->port.closing_wait = 3000;
652 info->close_delay = 50; 653 info->port.close_delay = 50;
653 init_waitqueue_head(&info->open_wait); 654 init_waitqueue_head(&info->port.open_wait);
654 init_completion(&info->close_wait); 655 init_completion(&info->close_wait);
655 info->flags &= ~ROCKET_MODE_MASK; 656 info->flags &= ~ROCKET_MODE_MASK;
656 switch (pc104[board][line]) { 657 switch (pc104[board][line]) {
@@ -717,7 +718,7 @@ static void configure_r_port(struct r_port *info,
717 unsigned rocketMode; 718 unsigned rocketMode;
718 int bits, baud, divisor; 719 int bits, baud, divisor;
719 CHANNEL_t *cp; 720 CHANNEL_t *cp;
720 struct ktermios *t = info->tty->termios; 721 struct ktermios *t = info->port.tty->termios;
721 722
722 cp = &info->channel; 723 cp = &info->channel;
723 cflag = t->c_cflag; 724 cflag = t->c_cflag;
@@ -750,7 +751,7 @@ static void configure_r_port(struct r_port *info,
750 } 751 }
751 752
752 /* baud rate */ 753 /* baud rate */
753 baud = tty_get_baud_rate(info->tty); 754 baud = tty_get_baud_rate(info->port.tty);
754 if (!baud) 755 if (!baud)
755 baud = 9600; 756 baud = 9600;
756 divisor = ((rp_baud_base[info->board] + (baud >> 1)) / baud) - 1; 757 divisor = ((rp_baud_base[info->board] + (baud >> 1)) / baud) - 1;
@@ -768,7 +769,7 @@ static void configure_r_port(struct r_port *info,
768 sSetBaud(cp, divisor); 769 sSetBaud(cp, divisor);
769 770
770 /* FIXME: Should really back compute a baud rate from the divisor */ 771 /* FIXME: Should really back compute a baud rate from the divisor */
771 tty_encode_baud_rate(info->tty, baud, baud); 772 tty_encode_baud_rate(info->port.tty, baud, baud);
772 773
773 if (cflag & CRTSCTS) { 774 if (cflag & CRTSCTS) {
774 info->intmask |= DELTA_CTS; 775 info->intmask |= DELTA_CTS;
@@ -793,15 +794,15 @@ static void configure_r_port(struct r_port *info,
793 * Handle software flow control in the board 794 * Handle software flow control in the board
794 */ 795 */
795#ifdef ROCKET_SOFT_FLOW 796#ifdef ROCKET_SOFT_FLOW
796 if (I_IXON(info->tty)) { 797 if (I_IXON(info->port.tty)) {
797 sEnTxSoftFlowCtl(cp); 798 sEnTxSoftFlowCtl(cp);
798 if (I_IXANY(info->tty)) { 799 if (I_IXANY(info->port.tty)) {
799 sEnIXANY(cp); 800 sEnIXANY(cp);
800 } else { 801 } else {
801 sDisIXANY(cp); 802 sDisIXANY(cp);
802 } 803 }
803 sSetTxXONChar(cp, START_CHAR(info->tty)); 804 sSetTxXONChar(cp, START_CHAR(info->port.tty));
804 sSetTxXOFFChar(cp, STOP_CHAR(info->tty)); 805 sSetTxXOFFChar(cp, STOP_CHAR(info->port.tty));
805 } else { 806 } else {
806 sDisTxSoftFlowCtl(cp); 807 sDisTxSoftFlowCtl(cp);
807 sDisIXANY(cp); 808 sDisIXANY(cp);
@@ -813,24 +814,24 @@ static void configure_r_port(struct r_port *info,
813 * Set up ignore/read mask words 814 * Set up ignore/read mask words
814 */ 815 */
815 info->read_status_mask = STMRCVROVRH | 0xFF; 816 info->read_status_mask = STMRCVROVRH | 0xFF;
816 if (I_INPCK(info->tty)) 817 if (I_INPCK(info->port.tty))
817 info->read_status_mask |= STMFRAMEH | STMPARITYH; 818 info->read_status_mask |= STMFRAMEH | STMPARITYH;
818 if (I_BRKINT(info->tty) || I_PARMRK(info->tty)) 819 if (I_BRKINT(info->port.tty) || I_PARMRK(info->port.tty))
819 info->read_status_mask |= STMBREAKH; 820 info->read_status_mask |= STMBREAKH;
820 821
821 /* 822 /*
822 * Characters to ignore 823 * Characters to ignore
823 */ 824 */
824 info->ignore_status_mask = 0; 825 info->ignore_status_mask = 0;
825 if (I_IGNPAR(info->tty)) 826 if (I_IGNPAR(info->port.tty))
826 info->ignore_status_mask |= STMFRAMEH | STMPARITYH; 827 info->ignore_status_mask |= STMFRAMEH | STMPARITYH;
827 if (I_IGNBRK(info->tty)) { 828 if (I_IGNBRK(info->port.tty)) {
828 info->ignore_status_mask |= STMBREAKH; 829 info->ignore_status_mask |= STMBREAKH;
829 /* 830 /*
830 * If we're ignoring parity and break indicators, 831 * If we're ignoring parity and break indicators,
831 * ignore overruns too. (For real raw support). 832 * ignore overruns too. (For real raw support).
832 */ 833 */
833 if (I_IGNPAR(info->tty)) 834 if (I_IGNPAR(info->port.tty))
834 info->ignore_status_mask |= STMRCVROVRH; 835 info->ignore_status_mask |= STMRCVROVRH;
835 } 836 }
836 837
@@ -863,7 +864,7 @@ static void configure_r_port(struct r_port *info,
863 } 864 }
864} 865}
865 866
866/* info->count is considered critical, protected by spinlocks. */ 867/* info->port.count is considered critical, protected by spinlocks. */
867static int block_til_ready(struct tty_struct *tty, struct file *filp, 868static int block_til_ready(struct tty_struct *tty, struct file *filp,
868 struct r_port *info) 869 struct r_port *info)
869{ 870{
@@ -897,13 +898,13 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
897 898
898 /* 899 /*
899 * Block waiting for the carrier detect and the line to become free. While we are in 900 * Block waiting for the carrier detect and the line to become free. While we are in
900 * this loop, info->count is dropped by one, so that rp_close() knows when to free things. 901 * this loop, info->port.count is dropped by one, so that rp_close() knows when to free things.
901 * We restore it upon exit, either normal or abnormal. 902 * We restore it upon exit, either normal or abnormal.
902 */ 903 */
903 retval = 0; 904 retval = 0;
904 add_wait_queue(&info->open_wait, &wait); 905 add_wait_queue(&info->port.open_wait, &wait);
905#ifdef ROCKET_DEBUG_OPEN 906#ifdef ROCKET_DEBUG_OPEN
906 printk(KERN_INFO "block_til_ready before block: ttyR%d, count = %d\n", info->line, info->count); 907 printk(KERN_INFO "block_til_ready before block: ttyR%d, count = %d\n", info->line, info->port.count);
907#endif 908#endif
908 spin_lock_irqsave(&info->slock, flags); 909 spin_lock_irqsave(&info->slock, flags);
909 910
@@ -912,10 +913,10 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
912#else 913#else
913 if (!tty_hung_up_p(filp)) { 914 if (!tty_hung_up_p(filp)) {
914 extra_count = 1; 915 extra_count = 1;
915 info->count--; 916 info->port.count--;
916 } 917 }
917#endif 918#endif
918 info->blocked_open++; 919 info->port.blocked_open++;
919 920
920 spin_unlock_irqrestore(&info->slock, flags); 921 spin_unlock_irqrestore(&info->slock, flags);
921 922
@@ -940,24 +941,24 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
940 } 941 }
941#ifdef ROCKET_DEBUG_OPEN 942#ifdef ROCKET_DEBUG_OPEN
942 printk(KERN_INFO "block_til_ready blocking: ttyR%d, count = %d, flags=0x%0x\n", 943 printk(KERN_INFO "block_til_ready blocking: ttyR%d, count = %d, flags=0x%0x\n",
943 info->line, info->count, info->flags); 944 info->line, info->port.count, info->flags);
944#endif 945#endif
945 schedule(); /* Don't hold spinlock here, will hang PC */ 946 schedule(); /* Don't hold spinlock here, will hang PC */
946 } 947 }
947 __set_current_state(TASK_RUNNING); 948 __set_current_state(TASK_RUNNING);
948 remove_wait_queue(&info->open_wait, &wait); 949 remove_wait_queue(&info->port.open_wait, &wait);
949 950
950 spin_lock_irqsave(&info->slock, flags); 951 spin_lock_irqsave(&info->slock, flags);
951 952
952 if (extra_count) 953 if (extra_count)
953 info->count++; 954 info->port.count++;
954 info->blocked_open--; 955 info->port.blocked_open--;
955 956
956 spin_unlock_irqrestore(&info->slock, flags); 957 spin_unlock_irqrestore(&info->slock, flags);
957 958
958#ifdef ROCKET_DEBUG_OPEN 959#ifdef ROCKET_DEBUG_OPEN
959 printk(KERN_INFO "block_til_ready after blocking: ttyR%d, count = %d\n", 960 printk(KERN_INFO "block_til_ready after blocking: ttyR%d, count = %d\n",
960 info->line, info->count); 961 info->line, info->port.count);
961#endif 962#endif
962 if (retval) 963 if (retval)
963 return retval; 964 return retval;
@@ -1001,9 +1002,9 @@ static int rp_open(struct tty_struct *tty, struct file *filp)
1001 info->xmit_buf = (unsigned char *) page; 1002 info->xmit_buf = (unsigned char *) page;
1002 1003
1003 tty->driver_data = info; 1004 tty->driver_data = info;
1004 info->tty = tty; 1005 info->port.tty = tty;
1005 1006
1006 if (info->count++ == 0) { 1007 if (info->port.count++ == 0) {
1007 atomic_inc(&rp_num_ports_open); 1008 atomic_inc(&rp_num_ports_open);
1008 1009
1009#ifdef ROCKET_DEBUG_OPEN 1010#ifdef ROCKET_DEBUG_OPEN
@@ -1012,7 +1013,7 @@ static int rp_open(struct tty_struct *tty, struct file *filp)
1012#endif 1013#endif
1013 } 1014 }
1014#ifdef ROCKET_DEBUG_OPEN 1015#ifdef ROCKET_DEBUG_OPEN
1015 printk(KERN_INFO "rp_open ttyR%d, count=%d\n", info->line, info->count); 1016 printk(KERN_INFO "rp_open ttyR%d, count=%d\n", info->line, info->port.count);
1016#endif 1017#endif
1017 1018
1018 /* 1019 /*
@@ -1048,13 +1049,13 @@ static int rp_open(struct tty_struct *tty, struct file *filp)
1048 * Set up the tty->alt_speed kludge 1049 * Set up the tty->alt_speed kludge
1049 */ 1050 */
1050 if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_HI) 1051 if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_HI)
1051 info->tty->alt_speed = 57600; 1052 info->port.tty->alt_speed = 57600;
1052 if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_VHI) 1053 if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_VHI)
1053 info->tty->alt_speed = 115200; 1054 info->port.tty->alt_speed = 115200;
1054 if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_SHI) 1055 if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_SHI)
1055 info->tty->alt_speed = 230400; 1056 info->port.tty->alt_speed = 230400;
1056 if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_WARP) 1057 if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_WARP)
1057 info->tty->alt_speed = 460800; 1058 info->port.tty->alt_speed = 460800;
1058 1059
1059 configure_r_port(info, NULL); 1060 configure_r_port(info, NULL);
1060 if (tty->termios->c_cflag & CBAUD) { 1061 if (tty->termios->c_cflag & CBAUD) {
@@ -1076,7 +1077,7 @@ static int rp_open(struct tty_struct *tty, struct file *filp)
1076} 1077}
1077 1078
1078/* 1079/*
1079 * Exception handler that closes a serial port. info->count is considered critical. 1080 * Exception handler that closes a serial port. info->port.count is considered critical.
1080 */ 1081 */
1081static void rp_close(struct tty_struct *tty, struct file *filp) 1082static void rp_close(struct tty_struct *tty, struct file *filp)
1082{ 1083{
@@ -1089,14 +1090,14 @@ static void rp_close(struct tty_struct *tty, struct file *filp)
1089 return; 1090 return;
1090 1091
1091#ifdef ROCKET_DEBUG_OPEN 1092#ifdef ROCKET_DEBUG_OPEN
1092 printk(KERN_INFO "rp_close ttyR%d, count = %d\n", info->line, info->count); 1093 printk(KERN_INFO "rp_close ttyR%d, count = %d\n", info->line, info->port.count);
1093#endif 1094#endif
1094 1095
1095 if (tty_hung_up_p(filp)) 1096 if (tty_hung_up_p(filp))
1096 return; 1097 return;
1097 spin_lock_irqsave(&info->slock, flags); 1098 spin_lock_irqsave(&info->slock, flags);
1098 1099
1099 if ((tty->count == 1) && (info->count != 1)) { 1100 if ((tty->count == 1) && (info->port.count != 1)) {
1100 /* 1101 /*
1101 * Uh, oh. tty->count is 1, which means that the tty 1102 * Uh, oh. tty->count is 1, which means that the tty
1102 * structure will be freed. Info->count should always 1103 * structure will be freed. Info->count should always
@@ -1105,15 +1106,15 @@ static void rp_close(struct tty_struct *tty, struct file *filp)
1105 * serial port won't be shutdown. 1106 * serial port won't be shutdown.
1106 */ 1107 */
1107 printk(KERN_WARNING "rp_close: bad serial port count; " 1108 printk(KERN_WARNING "rp_close: bad serial port count; "
1108 "tty->count is 1, info->count is %d\n", info->count); 1109 "tty->count is 1, info->port.count is %d\n", info->port.count);
1109 info->count = 1; 1110 info->port.count = 1;
1110 } 1111 }
1111 if (--info->count < 0) { 1112 if (--info->port.count < 0) {
1112 printk(KERN_WARNING "rp_close: bad serial port count for " 1113 printk(KERN_WARNING "rp_close: bad serial port count for "
1113 "ttyR%d: %d\n", info->line, info->count); 1114 "ttyR%d: %d\n", info->line, info->port.count);
1114 info->count = 0; 1115 info->port.count = 0;
1115 } 1116 }
1116 if (info->count) { 1117 if (info->port.count) {
1117 spin_unlock_irqrestore(&info->slock, flags); 1118 spin_unlock_irqrestore(&info->slock, flags);
1118 return; 1119 return;
1119 } 1120 }
@@ -1137,8 +1138,8 @@ static void rp_close(struct tty_struct *tty, struct file *filp)
1137 /* 1138 /*
1138 * Wait for the transmit buffer to clear 1139 * Wait for the transmit buffer to clear
1139 */ 1140 */
1140 if (info->closing_wait != ROCKET_CLOSING_WAIT_NONE) 1141 if (info->port.closing_wait != ROCKET_CLOSING_WAIT_NONE)
1141 tty_wait_until_sent(tty, info->closing_wait); 1142 tty_wait_until_sent(tty, info->port.closing_wait);
1142 /* 1143 /*
1143 * Before we drop DTR, make sure the UART transmitter 1144 * Before we drop DTR, make sure the UART transmitter
1144 * has completely drained; this is especially 1145 * has completely drained; this is especially
@@ -1167,11 +1168,11 @@ static void rp_close(struct tty_struct *tty, struct file *filp)
1167 1168
1168 clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]); 1169 clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
1169 1170
1170 if (info->blocked_open) { 1171 if (info->port.blocked_open) {
1171 if (info->close_delay) { 1172 if (info->port.close_delay) {
1172 msleep_interruptible(jiffies_to_msecs(info->close_delay)); 1173 msleep_interruptible(jiffies_to_msecs(info->port.close_delay));
1173 } 1174 }
1174 wake_up_interruptible(&info->open_wait); 1175 wake_up_interruptible(&info->port.open_wait);
1175 } else { 1176 } else {
1176 if (info->xmit_buf) { 1177 if (info->xmit_buf) {
1177 free_page((unsigned long) info->xmit_buf); 1178 free_page((unsigned long) info->xmit_buf);
@@ -1327,8 +1328,8 @@ static int get_config(struct r_port *info, struct rocket_config __user *retinfo)
1327 memset(&tmp, 0, sizeof (tmp)); 1328 memset(&tmp, 0, sizeof (tmp));
1328 tmp.line = info->line; 1329 tmp.line = info->line;
1329 tmp.flags = info->flags; 1330 tmp.flags = info->flags;
1330 tmp.close_delay = info->close_delay; 1331 tmp.close_delay = info->port.close_delay;
1331 tmp.closing_wait = info->closing_wait; 1332 tmp.closing_wait = info->port.closing_wait;
1332 tmp.port = rcktpt_io_addr[(info->line >> 5) & 3]; 1333 tmp.port = rcktpt_io_addr[(info->line >> 5) & 3];
1333 1334
1334 if (copy_to_user(retinfo, &tmp, sizeof (*retinfo))) 1335 if (copy_to_user(retinfo, &tmp, sizeof (*retinfo)))
@@ -1353,17 +1354,17 @@ static int set_config(struct r_port *info, struct rocket_config __user *new_info
1353 } 1354 }
1354 1355
1355 info->flags = ((info->flags & ~ROCKET_FLAGS) | (new_serial.flags & ROCKET_FLAGS)); 1356 info->flags = ((info->flags & ~ROCKET_FLAGS) | (new_serial.flags & ROCKET_FLAGS));
1356 info->close_delay = new_serial.close_delay; 1357 info->port.close_delay = new_serial.close_delay;
1357 info->closing_wait = new_serial.closing_wait; 1358 info->port.closing_wait = new_serial.closing_wait;
1358 1359
1359 if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_HI) 1360 if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_HI)
1360 info->tty->alt_speed = 57600; 1361 info->port.tty->alt_speed = 57600;
1361 if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_VHI) 1362 if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_VHI)
1362 info->tty->alt_speed = 115200; 1363 info->port.tty->alt_speed = 115200;
1363 if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_SHI) 1364 if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_SHI)
1364 info->tty->alt_speed = 230400; 1365 info->port.tty->alt_speed = 230400;
1365 if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_WARP) 1366 if ((info->flags & ROCKET_SPD_MASK) == ROCKET_SPD_WARP)
1366 info->tty->alt_speed = 460800; 1367 info->port.tty->alt_speed = 460800;
1367 1368
1368 configure_r_port(info, NULL); 1369 configure_r_port(info, NULL);
1369 return 0; 1370 return 0;
@@ -1636,13 +1637,13 @@ static void rp_hangup(struct tty_struct *tty)
1636 rp_flush_buffer(tty); 1637 rp_flush_buffer(tty);
1637 if (info->flags & ROCKET_CLOSING) 1638 if (info->flags & ROCKET_CLOSING)
1638 return; 1639 return;
1639 if (info->count) 1640 if (info->port.count)
1640 atomic_dec(&rp_num_ports_open); 1641 atomic_dec(&rp_num_ports_open);
1641 clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]); 1642 clear_bit((info->aiop * 8) + info->chan, (void *) &xmit_flags[info->board]);
1642 1643
1643 info->count = 0; 1644 info->port.count = 0;
1644 info->flags &= ~ROCKET_NORMAL_ACTIVE; 1645 info->flags &= ~ROCKET_NORMAL_ACTIVE;
1645 info->tty = NULL; 1646 info->port.tty = NULL;
1646 1647
1647 cp = &info->channel; 1648 cp = &info->channel;
1648 sDisRxFIFO(cp); 1649 sDisRxFIFO(cp);
@@ -1653,7 +1654,7 @@ static void rp_hangup(struct tty_struct *tty)
1653 sClrTxXOFF(cp); 1654 sClrTxXOFF(cp);
1654 info->flags &= ~ROCKET_INITIALIZED; 1655 info->flags &= ~ROCKET_INITIALIZED;
1655 1656
1656 wake_up_interruptible(&info->open_wait); 1657 wake_up_interruptible(&info->port.open_wait);
1657} 1658}
1658 1659
1659/* 1660/*
@@ -1762,7 +1763,7 @@ static int rp_write(struct tty_struct *tty,
1762 1763
1763 /* Write remaining data into the port's xmit_buf */ 1764 /* Write remaining data into the port's xmit_buf */
1764 while (1) { 1765 while (1) {
1765 if (!info->tty) /* Seemingly obligatory check... */ 1766 if (!info->port.tty) /* Seemingly obligatory check... */
1766 goto end; 1767 goto end;
1767 c = min(count, XMIT_BUF_SIZE - info->xmit_cnt - 1); 1768 c = min(count, XMIT_BUF_SIZE - info->xmit_cnt - 1);
1768 c = min(c, XMIT_BUF_SIZE - info->xmit_head); 1769 c = min(c, XMIT_BUF_SIZE - info->xmit_head);
diff --git a/drivers/char/rocket.h b/drivers/char/rocket.h
index ae6b04f90c03..a8b09195ebba 100644
--- a/drivers/char/rocket.h
+++ b/drivers/char/rocket.h
@@ -64,8 +64,8 @@ struct rocket_version {
64/* 64/*
65 * For closing_wait and closing_wait2 65 * For closing_wait and closing_wait2
66 */ 66 */
67#define ROCKET_CLOSING_WAIT_NONE 65535 67#define ROCKET_CLOSING_WAIT_NONE ASYNC_CLOSING_WAIT_NONE
68#define ROCKET_CLOSING_WAIT_INF 0 68#define ROCKET_CLOSING_WAIT_INF ASYNC_CLOSING_WAIT_INF
69 69
70/* 70/*
71 * Rocketport ioctls -- "RP" 71 * Rocketport ioctls -- "RP"
diff --git a/drivers/char/rocket_int.h b/drivers/char/rocket_int.h
index 143cc432fdb2..21f3ff53ba32 100644
--- a/drivers/char/rocket_int.h
+++ b/drivers/char/rocket_int.h
@@ -1125,18 +1125,14 @@ Warnings: This function writes the data byte without checking to see if
1125 1125
1126struct r_port { 1126struct r_port {
1127 int magic; 1127 int magic;
1128 struct tty_port port;
1128 int line; 1129 int line;
1129 int flags; 1130 int flags; /* Don't yet match the ASY_ flags!! */
1130 int count;
1131 int blocked_open;
1132 struct tty_struct *tty;
1133 unsigned int board:3; 1131 unsigned int board:3;
1134 unsigned int aiop:2; 1132 unsigned int aiop:2;
1135 unsigned int chan:3; 1133 unsigned int chan:3;
1136 CONTROLLER_t *ctlp; 1134 CONTROLLER_t *ctlp;
1137 CHANNEL_t channel; 1135 CHANNEL_t channel;
1138 int closing_wait;
1139 int close_delay;
1140 int intmask; 1136 int intmask;
1141 int xmit_fifo_room; /* room in xmit fifo */ 1137 int xmit_fifo_room; /* room in xmit fifo */
1142 unsigned char *xmit_buf; 1138 unsigned char *xmit_buf;
@@ -1148,8 +1144,7 @@ struct r_port {
1148 int read_status_mask; 1144 int read_status_mask;
1149 int cps; 1145 int cps;
1150 1146
1151 wait_queue_head_t open_wait; 1147 struct completion close_wait; /* Not yet matching the core */
1152 struct completion close_wait;
1153 spinlock_t slock; 1148 spinlock_t slock;
1154 struct mutex write_mtx; 1149 struct mutex write_mtx;
1155}; 1150};
diff --git a/drivers/char/rtc.c b/drivers/char/rtc.c
index 5f80a9dff573..fa92a8af5a5a 100644
--- a/drivers/char/rtc.c
+++ b/drivers/char/rtc.c
@@ -73,6 +73,7 @@
73#include <linux/proc_fs.h> 73#include <linux/proc_fs.h>
74#include <linux/seq_file.h> 74#include <linux/seq_file.h>
75#include <linux/spinlock.h> 75#include <linux/spinlock.h>
76#include <linux/smp_lock.h>
76#include <linux/sysctl.h> 77#include <linux/sysctl.h>
77#include <linux/wait.h> 78#include <linux/wait.h>
78#include <linux/bcd.h> 79#include <linux/bcd.h>
@@ -678,12 +679,13 @@ static int rtc_do_ioctl(unsigned int cmd, unsigned long arg, int kernel)
678 if (arg != (1<<tmp)) 679 if (arg != (1<<tmp))
679 return -EINVAL; 680 return -EINVAL;
680 681
682 rtc_freq = arg;
683
681 spin_lock_irqsave(&rtc_lock, flags); 684 spin_lock_irqsave(&rtc_lock, flags);
682 if (hpet_set_periodic_freq(arg)) { 685 if (hpet_set_periodic_freq(arg)) {
683 spin_unlock_irqrestore(&rtc_lock, flags); 686 spin_unlock_irqrestore(&rtc_lock, flags);
684 return 0; 687 return 0;
685 } 688 }
686 rtc_freq = arg;
687 689
688 val = CMOS_READ(RTC_FREQ_SELECT) & 0xf0; 690 val = CMOS_READ(RTC_FREQ_SELECT) & 0xf0;
689 val |= (16 - tmp); 691 val |= (16 - tmp);
@@ -733,6 +735,7 @@ static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd,
733 * needed here. Or anywhere else in this driver. */ 735 * needed here. Or anywhere else in this driver. */
734static int rtc_open(struct inode *inode, struct file *file) 736static int rtc_open(struct inode *inode, struct file *file)
735{ 737{
738 lock_kernel();
736 spin_lock_irq(&rtc_lock); 739 spin_lock_irq(&rtc_lock);
737 740
738 if (rtc_status & RTC_IS_OPEN) 741 if (rtc_status & RTC_IS_OPEN)
@@ -742,10 +745,12 @@ static int rtc_open(struct inode *inode, struct file *file)
742 745
743 rtc_irq_data = 0; 746 rtc_irq_data = 0;
744 spin_unlock_irq(&rtc_lock); 747 spin_unlock_irq(&rtc_lock);
748 unlock_kernel();
745 return 0; 749 return 0;
746 750
747out_busy: 751out_busy:
748 spin_unlock_irq(&rtc_lock); 752 spin_unlock_irq(&rtc_lock);
753 unlock_kernel();
749 return -EBUSY; 754 return -EBUSY;
750} 755}
751 756
diff --git a/drivers/char/scx200_gpio.c b/drivers/char/scx200_gpio.c
index 99e5272e3c53..1d9100561c8a 100644
--- a/drivers/char/scx200_gpio.c
+++ b/drivers/char/scx200_gpio.c
@@ -12,6 +12,7 @@
12#include <linux/kernel.h> 12#include <linux/kernel.h>
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/platform_device.h> 14#include <linux/platform_device.h>
15#include <linux/smp_lock.h>
15#include <asm/uaccess.h> 16#include <asm/uaccess.h>
16#include <asm/io.h> 17#include <asm/io.h>
17 18
@@ -51,6 +52,7 @@ static int scx200_gpio_open(struct inode *inode, struct file *file)
51 unsigned m = iminor(inode); 52 unsigned m = iminor(inode);
52 file->private_data = &scx200_gpio_ops; 53 file->private_data = &scx200_gpio_ops;
53 54
55 cycle_kernel_lock();
54 if (m >= MAX_PINS) 56 if (m >= MAX_PINS)
55 return -EINVAL; 57 return -EINVAL;
56 return nonseekable_open(inode, file); 58 return nonseekable_open(inode, file);
diff --git a/drivers/char/selection.c b/drivers/char/selection.c
index d63f5ccc29e6..2978a49a172b 100644
--- a/drivers/char/selection.c
+++ b/drivers/char/selection.c
@@ -327,7 +327,8 @@ int paste_selection(struct tty_struct *tty)
327 } 327 }
328 count = sel_buffer_lth - pasted; 328 count = sel_buffer_lth - pasted;
329 count = min(count, tty->receive_room); 329 count = min(count, tty->receive_room);
330 tty->ldisc.receive_buf(tty, sel_buffer + pasted, NULL, count); 330 tty->ldisc.ops->receive_buf(tty, sel_buffer + pasted,
331 NULL, count);
331 pasted += count; 332 pasted += count;
332 } 333 }
333 remove_wait_queue(&vc->paste_wait, &wait); 334 remove_wait_queue(&vc->paste_wait, &wait);
diff --git a/drivers/char/snsc.c b/drivers/char/snsc.c
index 8fe099a41065..0b799ac1b049 100644
--- a/drivers/char/snsc.c
+++ b/drivers/char/snsc.c
@@ -21,6 +21,7 @@
21#include <linux/poll.h> 21#include <linux/poll.h>
22#include <linux/module.h> 22#include <linux/module.h>
23#include <linux/slab.h> 23#include <linux/slab.h>
24#include <linux/smp_lock.h>
24#include <asm/sn/io.h> 25#include <asm/sn/io.h>
25#include <asm/sn/sn_sal.h> 26#include <asm/sn/sn_sal.h>
26#include <asm/sn/module.h> 27#include <asm/sn/module.h>
@@ -104,6 +105,7 @@ scdrv_open(struct inode *inode, struct file *file)
104 file->private_data = sd; 105 file->private_data = sd;
105 106
106 /* hook this subchannel up to the system controller interrupt */ 107 /* hook this subchannel up to the system controller interrupt */
108 lock_kernel();
107 rv = request_irq(SGI_UART_VECTOR, scdrv_interrupt, 109 rv = request_irq(SGI_UART_VECTOR, scdrv_interrupt,
108 IRQF_SHARED | IRQF_DISABLED, 110 IRQF_SHARED | IRQF_DISABLED,
109 SYSCTL_BASENAME, sd); 111 SYSCTL_BASENAME, sd);
@@ -111,9 +113,10 @@ scdrv_open(struct inode *inode, struct file *file)
111 ia64_sn_irtr_close(sd->sd_nasid, sd->sd_subch); 113 ia64_sn_irtr_close(sd->sd_nasid, sd->sd_subch);
112 kfree(sd); 114 kfree(sd);
113 printk("%s: irq request failed (%d)\n", __func__, rv); 115 printk("%s: irq request failed (%d)\n", __func__, rv);
116 unlock_kernel();
114 return -EBUSY; 117 return -EBUSY;
115 } 118 }
116 119 unlock_kernel();
117 return 0; 120 return 0;
118} 121}
119 122
diff --git a/drivers/char/snsc_event.c b/drivers/char/snsc_event.c
index 53b3d44f8c06..55a95892ccf9 100644
--- a/drivers/char/snsc_event.c
+++ b/drivers/char/snsc_event.c
@@ -17,7 +17,7 @@
17 17
18#include <linux/interrupt.h> 18#include <linux/interrupt.h>
19#include <linux/sched.h> 19#include <linux/sched.h>
20#include <linux/byteorder/generic.h> 20#include <asm/byteorder.h>
21#include <asm/sn/sn_sal.h> 21#include <asm/sn/sn_sal.h>
22#include <asm/unaligned.h> 22#include <asm/unaligned.h>
23#include "snsc.h" 23#include "snsc.h"
diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c
index 58533de59027..85e0eb76eeab 100644
--- a/drivers/char/sonypi.c
+++ b/drivers/char/sonypi.c
@@ -49,6 +49,7 @@
49#include <linux/err.h> 49#include <linux/err.h>
50#include <linux/kfifo.h> 50#include <linux/kfifo.h>
51#include <linux/platform_device.h> 51#include <linux/platform_device.h>
52#include <linux/smp_lock.h>
52 53
53#include <asm/uaccess.h> 54#include <asm/uaccess.h>
54#include <asm/io.h> 55#include <asm/io.h>
@@ -906,12 +907,14 @@ static int sonypi_misc_release(struct inode *inode, struct file *file)
906 907
907static int sonypi_misc_open(struct inode *inode, struct file *file) 908static int sonypi_misc_open(struct inode *inode, struct file *file)
908{ 909{
910 lock_kernel();
909 mutex_lock(&sonypi_device.lock); 911 mutex_lock(&sonypi_device.lock);
910 /* Flush input queue on first open */ 912 /* Flush input queue on first open */
911 if (!sonypi_device.open_count) 913 if (!sonypi_device.open_count)
912 kfifo_reset(sonypi_device.fifo); 914 kfifo_reset(sonypi_device.fifo);
913 sonypi_device.open_count++; 915 sonypi_device.open_count++;
914 mutex_unlock(&sonypi_device.lock); 916 mutex_unlock(&sonypi_device.lock);
917 unlock_kernel();
915 return 0; 918 return 0;
916} 919}
917 920
diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c
index 2ee4d9893757..037dc47e4cb1 100644
--- a/drivers/char/specialix.c
+++ b/drivers/char/specialix.c
@@ -608,9 +608,9 @@ static inline struct specialix_port * sx_get_port(struct specialix_board * bp,
608 dprintk (SX_DEBUG_CHAN, "channel: %d\n", channel); 608 dprintk (SX_DEBUG_CHAN, "channel: %d\n", channel);
609 if (channel < CD186x_NCH) { 609 if (channel < CD186x_NCH) {
610 port = &sx_port[board_No(bp) * SX_NPORT + channel]; 610 port = &sx_port[board_No(bp) * SX_NPORT + channel];
611 dprintk (SX_DEBUG_CHAN, "port: %d %p flags: 0x%x\n",board_No(bp) * SX_NPORT + channel, port, port->flags & ASYNC_INITIALIZED); 611 dprintk (SX_DEBUG_CHAN, "port: %d %p flags: 0x%lx\n",board_No(bp) * SX_NPORT + channel, port, port->port.flags & ASYNC_INITIALIZED);
612 612
613 if (port->flags & ASYNC_INITIALIZED) { 613 if (port->port.flags & ASYNC_INITIALIZED) {
614 dprintk (SX_DEBUG_CHAN, "port: %d %p\n", channel, port); 614 dprintk (SX_DEBUG_CHAN, "port: %d %p\n", channel, port);
615 func_exit(); 615 func_exit();
616 return port; 616 return port;
@@ -637,7 +637,7 @@ static inline void sx_receive_exc(struct specialix_board * bp)
637 func_exit(); 637 func_exit();
638 return; 638 return;
639 } 639 }
640 tty = port->tty; 640 tty = port->port.tty;
641 641
642 status = sx_in(bp, CD186x_RCSR); 642 status = sx_in(bp, CD186x_RCSR);
643 643
@@ -673,7 +673,7 @@ static inline void sx_receive_exc(struct specialix_board * bp)
673 dprintk(SX_DEBUG_RX, "sx%d: port %d: Handling break...\n", 673 dprintk(SX_DEBUG_RX, "sx%d: port %d: Handling break...\n",
674 board_No(bp), port_No(port)); 674 board_No(bp), port_No(port));
675 flag = TTY_BREAK; 675 flag = TTY_BREAK;
676 if (port->flags & ASYNC_SAK) 676 if (port->port.flags & ASYNC_SAK)
677 do_SAK(tty); 677 do_SAK(tty);
678 678
679 } else if (status & RCSR_PE) 679 } else if (status & RCSR_PE)
@@ -707,7 +707,7 @@ static inline void sx_receive(struct specialix_board * bp)
707 func_exit(); 707 func_exit();
708 return; 708 return;
709 } 709 }
710 tty = port->tty; 710 tty = port->port.tty;
711 711
712 count = sx_in(bp, CD186x_RDCR); 712 count = sx_in(bp, CD186x_RDCR);
713 dprintk (SX_DEBUG_RX, "port: %p: count: %d\n", port, count); 713 dprintk (SX_DEBUG_RX, "port: %p: count: %d\n", port, count);
@@ -734,7 +734,7 @@ static inline void sx_transmit(struct specialix_board * bp)
734 return; 734 return;
735 } 735 }
736 dprintk (SX_DEBUG_TX, "port: %p\n", port); 736 dprintk (SX_DEBUG_TX, "port: %p\n", port);
737 tty = port->tty; 737 tty = port->port.tty;
738 738
739 if (port->IER & IER_TXEMPTY) { 739 if (port->IER & IER_TXEMPTY) {
740 /* FIFO drained */ 740 /* FIFO drained */
@@ -811,7 +811,7 @@ static inline void sx_check_modem(struct specialix_board * bp)
811 if (!(port = sx_get_port(bp, "Modem"))) 811 if (!(port = sx_get_port(bp, "Modem")))
812 return; 812 return;
813 813
814 tty = port->tty; 814 tty = port->port.tty;
815 815
816 mcr = sx_in(bp, CD186x_MCR); 816 mcr = sx_in(bp, CD186x_MCR);
817 printk ("mcr = %02x.\n", mcr); 817 printk ("mcr = %02x.\n", mcr);
@@ -821,7 +821,7 @@ static inline void sx_check_modem(struct specialix_board * bp)
821 msvr_cd = sx_in(bp, CD186x_MSVR) & MSVR_CD; 821 msvr_cd = sx_in(bp, CD186x_MSVR) & MSVR_CD;
822 if (msvr_cd) { 822 if (msvr_cd) {
823 dprintk (SX_DEBUG_SIGNALS, "Waking up guys in open.\n"); 823 dprintk (SX_DEBUG_SIGNALS, "Waking up guys in open.\n");
824 wake_up_interruptible(&port->open_wait); 824 wake_up_interruptible(&port->port.open_wait);
825 } else { 825 } else {
826 dprintk (SX_DEBUG_SIGNALS, "Sending HUP.\n"); 826 dprintk (SX_DEBUG_SIGNALS, "Sending HUP.\n");
827 tty_hangup(tty); 827 tty_hangup(tty);
@@ -1030,7 +1030,7 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
1030 1030
1031 func_enter(); 1031 func_enter();
1032 1032
1033 if (!(tty = port->tty) || !tty->termios) { 1033 if (!(tty = port->port.tty) || !tty->termios) {
1034 func_exit(); 1034 func_exit();
1035 return; 1035 return;
1036 } 1036 }
@@ -1052,9 +1052,9 @@ static void sx_change_speed(struct specialix_board *bp, struct specialix_port *p
1052 baud = tty_get_baud_rate(tty); 1052 baud = tty_get_baud_rate(tty);
1053 1053
1054 if (baud == 38400) { 1054 if (baud == 38400) {
1055 if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) 1055 if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
1056 baud = 57600; 1056 baud = 57600;
1057 if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) 1057 if ((port->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
1058 baud = 115200; 1058 baud = 115200;
1059 } 1059 }
1060 1060
@@ -1244,7 +1244,7 @@ static int sx_setup_port(struct specialix_board *bp, struct specialix_port *port
1244 1244
1245 func_enter(); 1245 func_enter();
1246 1246
1247 if (port->flags & ASYNC_INITIALIZED) { 1247 if (port->port.flags & ASYNC_INITIALIZED) {
1248 func_exit(); 1248 func_exit();
1249 return 0; 1249 return 0;
1250 } 1250 }
@@ -1268,12 +1268,12 @@ static int sx_setup_port(struct specialix_board *bp, struct specialix_port *port
1268 1268
1269 spin_lock_irqsave(&port->lock, flags); 1269 spin_lock_irqsave(&port->lock, flags);
1270 1270
1271 if (port->tty) 1271 if (port->port.tty)
1272 clear_bit(TTY_IO_ERROR, &port->tty->flags); 1272 clear_bit(TTY_IO_ERROR, &port->port.tty->flags);
1273 1273
1274 port->xmit_cnt = port->xmit_head = port->xmit_tail = 0; 1274 port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
1275 sx_change_speed(bp, port); 1275 sx_change_speed(bp, port);
1276 port->flags |= ASYNC_INITIALIZED; 1276 port->port.flags |= ASYNC_INITIALIZED;
1277 1277
1278 spin_unlock_irqrestore(&port->lock, flags); 1278 spin_unlock_irqrestore(&port->lock, flags);
1279 1279
@@ -1292,7 +1292,7 @@ static void sx_shutdown_port(struct specialix_board *bp, struct specialix_port *
1292 1292
1293 func_enter(); 1293 func_enter();
1294 1294
1295 if (!(port->flags & ASYNC_INITIALIZED)) { 1295 if (!(port->port.flags & ASYNC_INITIALIZED)) {
1296 func_exit(); 1296 func_exit();
1297 return; 1297 return;
1298 } 1298 }
@@ -1315,7 +1315,7 @@ static void sx_shutdown_port(struct specialix_board *bp, struct specialix_port *
1315 spin_lock_irqsave(&bp->lock, flags); 1315 spin_lock_irqsave(&bp->lock, flags);
1316 sx_out(bp, CD186x_CAR, port_No(port)); 1316 sx_out(bp, CD186x_CAR, port_No(port));
1317 1317
1318 if (!(tty = port->tty) || C_HUPCL(tty)) { 1318 if (!(tty = port->port.tty) || C_HUPCL(tty)) {
1319 /* Drop DTR */ 1319 /* Drop DTR */
1320 sx_out(bp, CD186x_MSVDTR, 0); 1320 sx_out(bp, CD186x_MSVDTR, 0);
1321 } 1321 }
@@ -1330,7 +1330,7 @@ static void sx_shutdown_port(struct specialix_board *bp, struct specialix_port *
1330 spin_unlock_irqrestore(&bp->lock, flags); 1330 spin_unlock_irqrestore(&bp->lock, flags);
1331 if (tty) 1331 if (tty)
1332 set_bit(TTY_IO_ERROR, &tty->flags); 1332 set_bit(TTY_IO_ERROR, &tty->flags);
1333 port->flags &= ~ASYNC_INITIALIZED; 1333 port->port.flags &= ~ASYNC_INITIALIZED;
1334 1334
1335 if (!bp->count) 1335 if (!bp->count)
1336 sx_shutdown_board(bp); 1336 sx_shutdown_board(bp);
@@ -1354,9 +1354,9 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
1354 * If the device is in the middle of being closed, then block 1354 * If the device is in the middle of being closed, then block
1355 * until it's done, and then try again. 1355 * until it's done, and then try again.
1356 */ 1356 */
1357 if (tty_hung_up_p(filp) || port->flags & ASYNC_CLOSING) { 1357 if (tty_hung_up_p(filp) || port->port.flags & ASYNC_CLOSING) {
1358 interruptible_sleep_on(&port->close_wait); 1358 interruptible_sleep_on(&port->port.close_wait);
1359 if (port->flags & ASYNC_HUP_NOTIFY) { 1359 if (port->port.flags & ASYNC_HUP_NOTIFY) {
1360 func_exit(); 1360 func_exit();
1361 return -EAGAIN; 1361 return -EAGAIN;
1362 } else { 1362 } else {
@@ -1371,7 +1371,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
1371 */ 1371 */
1372 if ((filp->f_flags & O_NONBLOCK) || 1372 if ((filp->f_flags & O_NONBLOCK) ||
1373 (tty->flags & (1 << TTY_IO_ERROR))) { 1373 (tty->flags & (1 << TTY_IO_ERROR))) {
1374 port->flags |= ASYNC_NORMAL_ACTIVE; 1374 port->port.flags |= ASYNC_NORMAL_ACTIVE;
1375 func_exit(); 1375 func_exit();
1376 return 0; 1376 return 0;
1377 } 1377 }
@@ -1387,13 +1387,13 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
1387 * exit, either normal or abnormal. 1387 * exit, either normal or abnormal.
1388 */ 1388 */
1389 retval = 0; 1389 retval = 0;
1390 add_wait_queue(&port->open_wait, &wait); 1390 add_wait_queue(&port->port.open_wait, &wait);
1391 spin_lock_irqsave(&port->lock, flags); 1391 spin_lock_irqsave(&port->lock, flags);
1392 if (!tty_hung_up_p(filp)) { 1392 if (!tty_hung_up_p(filp)) {
1393 port->count--; 1393 port->port.count--;
1394 } 1394 }
1395 spin_unlock_irqrestore(&port->lock, flags); 1395 spin_unlock_irqrestore(&port->lock, flags);
1396 port->blocked_open++; 1396 port->port.blocked_open++;
1397 while (1) { 1397 while (1) {
1398 spin_lock_irqsave(&bp->lock, flags); 1398 spin_lock_irqsave(&bp->lock, flags);
1399 sx_out(bp, CD186x_CAR, port_No(port)); 1399 sx_out(bp, CD186x_CAR, port_No(port));
@@ -1410,14 +1410,14 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
1410 spin_unlock_irqrestore(&bp->lock, flags); 1410 spin_unlock_irqrestore(&bp->lock, flags);
1411 set_current_state(TASK_INTERRUPTIBLE); 1411 set_current_state(TASK_INTERRUPTIBLE);
1412 if (tty_hung_up_p(filp) || 1412 if (tty_hung_up_p(filp) ||
1413 !(port->flags & ASYNC_INITIALIZED)) { 1413 !(port->port.flags & ASYNC_INITIALIZED)) {
1414 if (port->flags & ASYNC_HUP_NOTIFY) 1414 if (port->port.flags & ASYNC_HUP_NOTIFY)
1415 retval = -EAGAIN; 1415 retval = -EAGAIN;
1416 else 1416 else
1417 retval = -ERESTARTSYS; 1417 retval = -ERESTARTSYS;
1418 break; 1418 break;
1419 } 1419 }
1420 if (!(port->flags & ASYNC_CLOSING) && 1420 if (!(port->port.flags & ASYNC_CLOSING) &&
1421 (do_clocal || CD)) 1421 (do_clocal || CD))
1422 break; 1422 break;
1423 if (signal_pending(current)) { 1423 if (signal_pending(current)) {
@@ -1428,19 +1428,19 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
1428 } 1428 }
1429 1429
1430 set_current_state(TASK_RUNNING); 1430 set_current_state(TASK_RUNNING);
1431 remove_wait_queue(&port->open_wait, &wait); 1431 remove_wait_queue(&port->port.open_wait, &wait);
1432 spin_lock_irqsave(&port->lock, flags); 1432 spin_lock_irqsave(&port->lock, flags);
1433 if (!tty_hung_up_p(filp)) { 1433 if (!tty_hung_up_p(filp)) {
1434 port->count++; 1434 port->port.count++;
1435 } 1435 }
1436 port->blocked_open--; 1436 port->port.blocked_open--;
1437 spin_unlock_irqrestore(&port->lock, flags); 1437 spin_unlock_irqrestore(&port->lock, flags);
1438 if (retval) { 1438 if (retval) {
1439 func_exit(); 1439 func_exit();
1440 return retval; 1440 return retval;
1441 } 1441 }
1442 1442
1443 port->flags |= ASYNC_NORMAL_ACTIVE; 1443 port->port.flags |= ASYNC_NORMAL_ACTIVE;
1444 func_exit(); 1444 func_exit();
1445 return 0; 1445 return 0;
1446} 1446}
@@ -1484,10 +1484,10 @@ static int sx_open(struct tty_struct * tty, struct file * filp)
1484 } 1484 }
1485 1485
1486 spin_lock_irqsave(&bp->lock, flags); 1486 spin_lock_irqsave(&bp->lock, flags);
1487 port->count++; 1487 port->port.count++;
1488 bp->count++; 1488 bp->count++;
1489 tty->driver_data = port; 1489 tty->driver_data = port;
1490 port->tty = tty; 1490 port->port.tty = tty;
1491 spin_unlock_irqrestore(&bp->lock, flags); 1491 spin_unlock_irqrestore(&bp->lock, flags);
1492 1492
1493 if ((error = sx_setup_port(bp, port))) { 1493 if ((error = sx_setup_port(bp, port))) {
@@ -1547,15 +1547,15 @@ static void sx_close(struct tty_struct * tty, struct file * filp)
1547 } 1547 }
1548 1548
1549 bp = port_Board(port); 1549 bp = port_Board(port);
1550 if ((tty->count == 1) && (port->count != 1)) { 1550 if ((tty->count == 1) && (port->port.count != 1)) {
1551 printk(KERN_ERR "sx%d: sx_close: bad port count;" 1551 printk(KERN_ERR "sx%d: sx_close: bad port count;"
1552 " tty->count is 1, port count is %d\n", 1552 " tty->count is 1, port count is %d\n",
1553 board_No(bp), port->count); 1553 board_No(bp), port->port.count);
1554 port->count = 1; 1554 port->port.count = 1;
1555 } 1555 }
1556 1556
1557 if (port->count > 1) { 1557 if (port->port.count > 1) {
1558 port->count--; 1558 port->port.count--;
1559 bp->count--; 1559 bp->count--;
1560 1560
1561 spin_unlock_irqrestore(&port->lock, flags); 1561 spin_unlock_irqrestore(&port->lock, flags);
@@ -1563,7 +1563,7 @@ static void sx_close(struct tty_struct * tty, struct file * filp)
1563 func_exit(); 1563 func_exit();
1564 return; 1564 return;
1565 } 1565 }
1566 port->flags |= ASYNC_CLOSING; 1566 port->port.flags |= ASYNC_CLOSING;
1567 /* 1567 /*
1568 * Now we wait for the transmit buffer to clear; and we notify 1568 * Now we wait for the transmit buffer to clear; and we notify
1569 * the line discipline to only process XON/XOFF characters. 1569 * the line discipline to only process XON/XOFF characters.
@@ -1571,8 +1571,8 @@ static void sx_close(struct tty_struct * tty, struct file * filp)
1571 tty->closing = 1; 1571 tty->closing = 1;
1572 spin_unlock_irqrestore(&port->lock, flags); 1572 spin_unlock_irqrestore(&port->lock, flags);
1573 dprintk (SX_DEBUG_OPEN, "Closing\n"); 1573 dprintk (SX_DEBUG_OPEN, "Closing\n");
1574 if (port->closing_wait != ASYNC_CLOSING_WAIT_NONE) { 1574 if (port->port.closing_wait != ASYNC_CLOSING_WAIT_NONE) {
1575 tty_wait_until_sent(tty, port->closing_wait); 1575 tty_wait_until_sent(tty, port->port.closing_wait);
1576 } 1576 }
1577 /* 1577 /*
1578 * At this point we stop accepting input. To do this, we 1578 * At this point we stop accepting input. To do this, we
@@ -1582,7 +1582,7 @@ static void sx_close(struct tty_struct * tty, struct file * filp)
1582 */ 1582 */
1583 dprintk (SX_DEBUG_OPEN, "Closed\n"); 1583 dprintk (SX_DEBUG_OPEN, "Closed\n");
1584 port->IER &= ~IER_RXD; 1584 port->IER &= ~IER_RXD;
1585 if (port->flags & ASYNC_INITIALIZED) { 1585 if (port->port.flags & ASYNC_INITIALIZED) {
1586 port->IER &= ~IER_TXRDY; 1586 port->IER &= ~IER_TXRDY;
1587 port->IER |= IER_TXEMPTY; 1587 port->IER |= IER_TXEMPTY;
1588 spin_lock_irqsave(&bp->lock, flags); 1588 spin_lock_irqsave(&bp->lock, flags);
@@ -1611,10 +1611,10 @@ static void sx_close(struct tty_struct * tty, struct file * filp)
1611 board_No(bp), bp->count, tty->index); 1611 board_No(bp), bp->count, tty->index);
1612 bp->count = 0; 1612 bp->count = 0;
1613 } 1613 }
1614 if (--port->count < 0) { 1614 if (--port->port.count < 0) {
1615 printk(KERN_ERR "sx%d: sx_close: bad port count for tty%d: %d\n", 1615 printk(KERN_ERR "sx%d: sx_close: bad port count for tty%d: %d\n",
1616 board_No(bp), port_No(port), port->count); 1616 board_No(bp), port_No(port), port->port.count);
1617 port->count = 0; 1617 port->port.count = 0;
1618 } 1618 }
1619 1619
1620 sx_shutdown_port(bp, port); 1620 sx_shutdown_port(bp, port);
@@ -1622,16 +1622,16 @@ static void sx_close(struct tty_struct * tty, struct file * filp)
1622 tty_ldisc_flush(tty); 1622 tty_ldisc_flush(tty);
1623 spin_lock_irqsave(&port->lock, flags); 1623 spin_lock_irqsave(&port->lock, flags);
1624 tty->closing = 0; 1624 tty->closing = 0;
1625 port->tty = NULL; 1625 port->port.tty = NULL;
1626 spin_unlock_irqrestore(&port->lock, flags); 1626 spin_unlock_irqrestore(&port->lock, flags);
1627 if (port->blocked_open) { 1627 if (port->port.blocked_open) {
1628 if (port->close_delay) { 1628 if (port->port.close_delay) {
1629 msleep_interruptible(jiffies_to_msecs(port->close_delay)); 1629 msleep_interruptible(jiffies_to_msecs(port->port.close_delay));
1630 } 1630 }
1631 wake_up_interruptible(&port->open_wait); 1631 wake_up_interruptible(&port->port.open_wait);
1632 } 1632 }
1633 port->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); 1633 port->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
1634 wake_up_interruptible(&port->close_wait); 1634 wake_up_interruptible(&port->port.close_wait);
1635 1635
1636 func_exit(); 1636 func_exit();
1637} 1637}
@@ -1815,7 +1815,7 @@ static int sx_tiocmget(struct tty_struct *tty, struct file *file)
1815 dprintk (SX_DEBUG_INIT, "Got msvr[%d] = %02x, car = %d.\n", 1815 dprintk (SX_DEBUG_INIT, "Got msvr[%d] = %02x, car = %d.\n",
1816 port_No(port), status, sx_in (bp, CD186x_CAR)); 1816 port_No(port), status, sx_in (bp, CD186x_CAR));
1817 dprintk (SX_DEBUG_INIT, "sx_port = %p, port = %p\n", sx_port, port); 1817 dprintk (SX_DEBUG_INIT, "sx_port = %p, port = %p\n", sx_port, port);
1818 if (SX_CRTSCTS(port->tty)) { 1818 if (SX_CRTSCTS(port->port.tty)) {
1819 result = /* (status & MSVR_RTS) ? */ TIOCM_DTR /* : 0) */ 1819 result = /* (status & MSVR_RTS) ? */ TIOCM_DTR /* : 0) */
1820 | ((status & MSVR_DTR) ? TIOCM_RTS : 0) 1820 | ((status & MSVR_DTR) ? TIOCM_RTS : 0)
1821 | ((status & MSVR_CD) ? TIOCM_CAR : 0) 1821 | ((status & MSVR_CD) ? TIOCM_CAR : 0)
@@ -1857,7 +1857,7 @@ static int sx_tiocmset(struct tty_struct *tty, struct file *file,
1857 /* if (set & TIOCM_DTR) 1857 /* if (set & TIOCM_DTR)
1858 port->MSVR |= MSVR_DTR; */ 1858 port->MSVR |= MSVR_DTR; */
1859 1859
1860 if (SX_CRTSCTS(port->tty)) { 1860 if (SX_CRTSCTS(port->port.tty)) {
1861 if (set & TIOCM_RTS) 1861 if (set & TIOCM_RTS)
1862 port->MSVR |= MSVR_DTR; 1862 port->MSVR |= MSVR_DTR;
1863 } else { 1863 } else {
@@ -1869,7 +1869,7 @@ static int sx_tiocmset(struct tty_struct *tty, struct file *file,
1869 port->MSVR &= ~MSVR_RTS; */ 1869 port->MSVR &= ~MSVR_RTS; */
1870 /* if (clear & TIOCM_DTR) 1870 /* if (clear & TIOCM_DTR)
1871 port->MSVR &= ~MSVR_DTR; */ 1871 port->MSVR &= ~MSVR_DTR; */
1872 if (SX_CRTSCTS(port->tty)) { 1872 if (SX_CRTSCTS(port->port.tty)) {
1873 if (clear & TIOCM_RTS) 1873 if (clear & TIOCM_RTS)
1874 port->MSVR &= ~MSVR_DTR; 1874 port->MSVR &= ~MSVR_DTR;
1875 } else { 1875 } else {
@@ -1929,27 +1929,27 @@ static inline int sx_set_serial_info(struct specialix_port * port,
1929 1929
1930 lock_kernel(); 1930 lock_kernel();
1931 1931
1932 change_speed = ((port->flags & ASYNC_SPD_MASK) != 1932 change_speed = ((port->port.flags & ASYNC_SPD_MASK) !=
1933 (tmp.flags & ASYNC_SPD_MASK)); 1933 (tmp.flags & ASYNC_SPD_MASK));
1934 change_speed |= (tmp.custom_divisor != port->custom_divisor); 1934 change_speed |= (tmp.custom_divisor != port->custom_divisor);
1935 1935
1936 if (!capable(CAP_SYS_ADMIN)) { 1936 if (!capable(CAP_SYS_ADMIN)) {
1937 if ((tmp.close_delay != port->close_delay) || 1937 if ((tmp.close_delay != port->port.close_delay) ||
1938 (tmp.closing_wait != port->closing_wait) || 1938 (tmp.closing_wait != port->port.closing_wait) ||
1939 ((tmp.flags & ~ASYNC_USR_MASK) != 1939 ((tmp.flags & ~ASYNC_USR_MASK) !=
1940 (port->flags & ~ASYNC_USR_MASK))) { 1940 (port->port.flags & ~ASYNC_USR_MASK))) {
1941 func_exit(); 1941 func_exit();
1942 unlock_kernel(); 1942 unlock_kernel();
1943 return -EPERM; 1943 return -EPERM;
1944 } 1944 }
1945 port->flags = ((port->flags & ~ASYNC_USR_MASK) | 1945 port->port.flags = ((port->port.flags & ~ASYNC_USR_MASK) |
1946 (tmp.flags & ASYNC_USR_MASK)); 1946 (tmp.flags & ASYNC_USR_MASK));
1947 port->custom_divisor = tmp.custom_divisor; 1947 port->custom_divisor = tmp.custom_divisor;
1948 } else { 1948 } else {
1949 port->flags = ((port->flags & ~ASYNC_FLAGS) | 1949 port->port.flags = ((port->port.flags & ~ASYNC_FLAGS) |
1950 (tmp.flags & ASYNC_FLAGS)); 1950 (tmp.flags & ASYNC_FLAGS));
1951 port->close_delay = tmp.close_delay; 1951 port->port.close_delay = tmp.close_delay;
1952 port->closing_wait = tmp.closing_wait; 1952 port->port.closing_wait = tmp.closing_wait;
1953 port->custom_divisor = tmp.custom_divisor; 1953 port->custom_divisor = tmp.custom_divisor;
1954 } 1954 }
1955 if (change_speed) { 1955 if (change_speed) {
@@ -1975,10 +1975,10 @@ static inline int sx_get_serial_info(struct specialix_port * port,
1975 tmp.line = port - sx_port; 1975 tmp.line = port - sx_port;
1976 tmp.port = bp->base; 1976 tmp.port = bp->base;
1977 tmp.irq = bp->irq; 1977 tmp.irq = bp->irq;
1978 tmp.flags = port->flags; 1978 tmp.flags = port->port.flags;
1979 tmp.baud_base = (SX_OSCFREQ + CD186x_TPC/2) / CD186x_TPC; 1979 tmp.baud_base = (SX_OSCFREQ + CD186x_TPC/2) / CD186x_TPC;
1980 tmp.close_delay = port->close_delay * HZ/100; 1980 tmp.close_delay = port->port.close_delay * HZ/100;
1981 tmp.closing_wait = port->closing_wait * HZ/100; 1981 tmp.closing_wait = port->port.closing_wait * HZ/100;
1982 tmp.custom_divisor = port->custom_divisor; 1982 tmp.custom_divisor = port->custom_divisor;
1983 tmp.xmit_fifo_size = CD186x_NFIFO; 1983 tmp.xmit_fifo_size = CD186x_NFIFO;
1984 unlock_kernel(); 1984 unlock_kernel();
@@ -2199,17 +2199,17 @@ static void sx_hangup(struct tty_struct * tty)
2199 2199
2200 sx_shutdown_port(bp, port); 2200 sx_shutdown_port(bp, port);
2201 spin_lock_irqsave(&port->lock, flags); 2201 spin_lock_irqsave(&port->lock, flags);
2202 bp->count -= port->count; 2202 bp->count -= port->port.count;
2203 if (bp->count < 0) { 2203 if (bp->count < 0) {
2204 printk(KERN_ERR "sx%d: sx_hangup: bad board count: %d port: %d\n", 2204 printk(KERN_ERR "sx%d: sx_hangup: bad board count: %d port: %d\n",
2205 board_No(bp), bp->count, tty->index); 2205 board_No(bp), bp->count, tty->index);
2206 bp->count = 0; 2206 bp->count = 0;
2207 } 2207 }
2208 port->count = 0; 2208 port->port.count = 0;
2209 port->flags &= ~ASYNC_NORMAL_ACTIVE; 2209 port->port.flags &= ~ASYNC_NORMAL_ACTIVE;
2210 port->tty = NULL; 2210 port->port.tty = NULL;
2211 spin_unlock_irqrestore(&port->lock, flags); 2211 spin_unlock_irqrestore(&port->lock, flags);
2212 wake_up_interruptible(&port->open_wait); 2212 wake_up_interruptible(&port->port.open_wait);
2213 2213
2214 func_exit(); 2214 func_exit();
2215} 2215}
@@ -2224,10 +2224,6 @@ static void sx_set_termios(struct tty_struct * tty, struct ktermios * old_termio
2224 if (sx_paranoia_check(port, tty->name, "sx_set_termios")) 2224 if (sx_paranoia_check(port, tty->name, "sx_set_termios"))
2225 return; 2225 return;
2226 2226
2227 if (tty->termios->c_cflag == old_termios->c_cflag &&
2228 tty->termios->c_iflag == old_termios->c_iflag)
2229 return;
2230
2231 bp = port_Board(port); 2227 bp = port_Board(port);
2232 spin_lock_irqsave(&port->lock, flags); 2228 spin_lock_irqsave(&port->lock, flags);
2233 sx_change_speed(port_Board(port), port); 2229 sx_change_speed(port_Board(port), port);
@@ -2297,10 +2293,7 @@ static int sx_init_drivers(void)
2297 memset(sx_port, 0, sizeof(sx_port)); 2293 memset(sx_port, 0, sizeof(sx_port));
2298 for (i = 0; i < SX_NPORT * SX_NBOARD; i++) { 2294 for (i = 0; i < SX_NPORT * SX_NBOARD; i++) {
2299 sx_port[i].magic = SPECIALIX_MAGIC; 2295 sx_port[i].magic = SPECIALIX_MAGIC;
2300 sx_port[i].close_delay = 50 * HZ/100; 2296 tty_port_init(&sx_port[i].port);
2301 sx_port[i].closing_wait = 3000 * HZ/100;
2302 init_waitqueue_head(&sx_port[i].open_wait);
2303 init_waitqueue_head(&sx_port[i].close_wait);
2304 spin_lock_init(&sx_port[i].lock); 2297 spin_lock_init(&sx_port[i].lock);
2305 } 2298 }
2306 2299
diff --git a/drivers/char/specialix_io8.h b/drivers/char/specialix_io8.h
index 3f2f85bdf516..c63005274d9b 100644
--- a/drivers/char/specialix_io8.h
+++ b/drivers/char/specialix_io8.h
@@ -107,23 +107,17 @@ struct specialix_board {
107 107
108struct specialix_port { 108struct specialix_port {
109 int magic; 109 int magic;
110 struct tty_port port;
110 int baud_base; 111 int baud_base;
111 int flags; 112 int flags;
112 struct tty_struct * tty;
113 int count;
114 int blocked_open;
115 int timeout; 113 int timeout;
116 int close_delay;
117 unsigned char * xmit_buf; 114 unsigned char * xmit_buf;
118 int custom_divisor; 115 int custom_divisor;
119 int xmit_head; 116 int xmit_head;
120 int xmit_tail; 117 int xmit_tail;
121 int xmit_cnt; 118 int xmit_cnt;
122 wait_queue_head_t open_wait;
123 wait_queue_head_t close_wait;
124 short wakeup_chars; 119 short wakeup_chars;
125 short break_length; 120 short break_length;
126 unsigned short closing_wait;
127 unsigned char mark_mask; 121 unsigned char mark_mask;
128 unsigned char IER; 122 unsigned char IER;
129 unsigned char MSVR; 123 unsigned char MSVR;
diff --git a/drivers/char/stallion.c b/drivers/char/stallion.c
index d17be10c5d21..0243efb0be95 100644
--- a/drivers/char/stallion.c
+++ b/drivers/char/stallion.c
@@ -613,17 +613,17 @@ static void stl_cd_change(struct stlport *portp)
613{ 613{
614 unsigned int oldsigs = portp->sigs; 614 unsigned int oldsigs = portp->sigs;
615 615
616 if (!portp->tty) 616 if (!portp->port.tty)
617 return; 617 return;
618 618
619 portp->sigs = stl_getsignals(portp); 619 portp->sigs = stl_getsignals(portp);
620 620
621 if ((portp->sigs & TIOCM_CD) && ((oldsigs & TIOCM_CD) == 0)) 621 if ((portp->sigs & TIOCM_CD) && ((oldsigs & TIOCM_CD) == 0))
622 wake_up_interruptible(&portp->open_wait); 622 wake_up_interruptible(&portp->port.open_wait);
623 623
624 if ((oldsigs & TIOCM_CD) && ((portp->sigs & TIOCM_CD) == 0)) 624 if ((oldsigs & TIOCM_CD) && ((portp->sigs & TIOCM_CD) == 0))
625 if (portp->flags & ASYNC_CHECK_CD) 625 if (portp->port.flags & ASYNC_CHECK_CD)
626 tty_hangup(portp->tty); 626 tty_hangup(portp->port.tty);
627} 627}
628 628
629/* 629/*
@@ -734,11 +734,11 @@ static int stl_open(struct tty_struct *tty, struct file *filp)
734 * On the first open of the device setup the port hardware, and 734 * On the first open of the device setup the port hardware, and
735 * initialize the per port data structure. 735 * initialize the per port data structure.
736 */ 736 */
737 portp->tty = tty; 737 portp->port.tty = tty;
738 tty->driver_data = portp; 738 tty->driver_data = portp;
739 portp->refcount++; 739 portp->port.count++;
740 740
741 if ((portp->flags & ASYNC_INITIALIZED) == 0) { 741 if ((portp->port.flags & ASYNC_INITIALIZED) == 0) {
742 if (!portp->tx.buf) { 742 if (!portp->tx.buf) {
743 portp->tx.buf = kmalloc(STL_TXBUFSIZE, GFP_KERNEL); 743 portp->tx.buf = kmalloc(STL_TXBUFSIZE, GFP_KERNEL);
744 if (!portp->tx.buf) 744 if (!portp->tx.buf)
@@ -752,7 +752,7 @@ static int stl_open(struct tty_struct *tty, struct file *filp)
752 stl_enablerxtx(portp, 1, 1); 752 stl_enablerxtx(portp, 1, 1);
753 stl_startrxtx(portp, 1, 0); 753 stl_startrxtx(portp, 1, 0);
754 clear_bit(TTY_IO_ERROR, &tty->flags); 754 clear_bit(TTY_IO_ERROR, &tty->flags);
755 portp->flags |= ASYNC_INITIALIZED; 755 portp->port.flags |= ASYNC_INITIALIZED;
756 } 756 }
757 757
758/* 758/*
@@ -761,9 +761,9 @@ static int stl_open(struct tty_struct *tty, struct file *filp)
761 * The sleep here does not need interrupt protection since the wakeup 761 * The sleep here does not need interrupt protection since the wakeup
762 * for it is done with the same context. 762 * for it is done with the same context.
763 */ 763 */
764 if (portp->flags & ASYNC_CLOSING) { 764 if (portp->port.flags & ASYNC_CLOSING) {
765 interruptible_sleep_on(&portp->close_wait); 765 interruptible_sleep_on(&portp->port.close_wait);
766 if (portp->flags & ASYNC_HUP_NOTIFY) 766 if (portp->port.flags & ASYNC_HUP_NOTIFY)
767 return -EAGAIN; 767 return -EAGAIN;
768 return -ERESTARTSYS; 768 return -ERESTARTSYS;
769 } 769 }
@@ -777,7 +777,7 @@ static int stl_open(struct tty_struct *tty, struct file *filp)
777 if ((rc = stl_waitcarrier(portp, filp)) != 0) 777 if ((rc = stl_waitcarrier(portp, filp)) != 0)
778 return rc; 778 return rc;
779 779
780 portp->flags |= ASYNC_NORMAL_ACTIVE; 780 portp->port.flags |= ASYNC_NORMAL_ACTIVE;
781 781
782 return 0; 782 return 0;
783} 783}
@@ -801,25 +801,25 @@ static int stl_waitcarrier(struct stlport *portp, struct file *filp)
801 801
802 spin_lock_irqsave(&stallion_lock, flags); 802 spin_lock_irqsave(&stallion_lock, flags);
803 803
804 if (portp->tty->termios->c_cflag & CLOCAL) 804 if (portp->port.tty->termios->c_cflag & CLOCAL)
805 doclocal++; 805 doclocal++;
806 806
807 portp->openwaitcnt++; 807 portp->openwaitcnt++;
808 if (! tty_hung_up_p(filp)) 808 if (! tty_hung_up_p(filp))
809 portp->refcount--; 809 portp->port.count--;
810 810
811 for (;;) { 811 for (;;) {
812 /* Takes brd_lock internally */ 812 /* Takes brd_lock internally */
813 stl_setsignals(portp, 1, 1); 813 stl_setsignals(portp, 1, 1);
814 if (tty_hung_up_p(filp) || 814 if (tty_hung_up_p(filp) ||
815 ((portp->flags & ASYNC_INITIALIZED) == 0)) { 815 ((portp->port.flags & ASYNC_INITIALIZED) == 0)) {
816 if (portp->flags & ASYNC_HUP_NOTIFY) 816 if (portp->port.flags & ASYNC_HUP_NOTIFY)
817 rc = -EBUSY; 817 rc = -EBUSY;
818 else 818 else
819 rc = -ERESTARTSYS; 819 rc = -ERESTARTSYS;
820 break; 820 break;
821 } 821 }
822 if (((portp->flags & ASYNC_CLOSING) == 0) && 822 if (((portp->port.flags & ASYNC_CLOSING) == 0) &&
823 (doclocal || (portp->sigs & TIOCM_CD))) 823 (doclocal || (portp->sigs & TIOCM_CD)))
824 break; 824 break;
825 if (signal_pending(current)) { 825 if (signal_pending(current)) {
@@ -827,11 +827,11 @@ static int stl_waitcarrier(struct stlport *portp, struct file *filp)
827 break; 827 break;
828 } 828 }
829 /* FIXME */ 829 /* FIXME */
830 interruptible_sleep_on(&portp->open_wait); 830 interruptible_sleep_on(&portp->port.open_wait);
831 } 831 }
832 832
833 if (! tty_hung_up_p(filp)) 833 if (! tty_hung_up_p(filp))
834 portp->refcount++; 834 portp->port.count++;
835 portp->openwaitcnt--; 835 portp->openwaitcnt--;
836 spin_unlock_irqrestore(&stallion_lock, flags); 836 spin_unlock_irqrestore(&stallion_lock, flags);
837 837
@@ -904,15 +904,15 @@ static void stl_close(struct tty_struct *tty, struct file *filp)
904 spin_unlock_irqrestore(&stallion_lock, flags); 904 spin_unlock_irqrestore(&stallion_lock, flags);
905 return; 905 return;
906 } 906 }
907 if ((tty->count == 1) && (portp->refcount != 1)) 907 if ((tty->count == 1) && (portp->port.count != 1))
908 portp->refcount = 1; 908 portp->port.count = 1;
909 if (portp->refcount-- > 1) { 909 if (portp->port.count-- > 1) {
910 spin_unlock_irqrestore(&stallion_lock, flags); 910 spin_unlock_irqrestore(&stallion_lock, flags);
911 return; 911 return;
912 } 912 }
913 913
914 portp->refcount = 0; 914 portp->port.count = 0;
915 portp->flags |= ASYNC_CLOSING; 915 portp->port.flags |= ASYNC_CLOSING;
916 916
917/* 917/*
918 * May want to wait for any data to drain before closing. The BUSY 918 * May want to wait for any data to drain before closing. The BUSY
@@ -930,7 +930,7 @@ static void stl_close(struct tty_struct *tty, struct file *filp)
930 930
931 931
932 spin_lock_irqsave(&stallion_lock, flags); 932 spin_lock_irqsave(&stallion_lock, flags);
933 portp->flags &= ~ASYNC_INITIALIZED; 933 portp->port.flags &= ~ASYNC_INITIALIZED;
934 spin_unlock_irqrestore(&stallion_lock, flags); 934 spin_unlock_irqrestore(&stallion_lock, flags);
935 935
936 stl_disableintrs(portp); 936 stl_disableintrs(portp);
@@ -949,16 +949,16 @@ static void stl_close(struct tty_struct *tty, struct file *filp)
949 tty_ldisc_flush(tty); 949 tty_ldisc_flush(tty);
950 950
951 tty->closing = 0; 951 tty->closing = 0;
952 portp->tty = NULL; 952 portp->port.tty = NULL;
953 953
954 if (portp->openwaitcnt) { 954 if (portp->openwaitcnt) {
955 if (portp->close_delay) 955 if (portp->close_delay)
956 msleep_interruptible(jiffies_to_msecs(portp->close_delay)); 956 msleep_interruptible(jiffies_to_msecs(portp->close_delay));
957 wake_up_interruptible(&portp->open_wait); 957 wake_up_interruptible(&portp->port.open_wait);
958 } 958 }
959 959
960 portp->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); 960 portp->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
961 wake_up_interruptible(&portp->close_wait); 961 wake_up_interruptible(&portp->port.close_wait);
962} 962}
963 963
964/*****************************************************************************/ 964/*****************************************************************************/
@@ -1153,7 +1153,7 @@ static int stl_getserial(struct stlport *portp, struct serial_struct __user *sp)
1153 memset(&sio, 0, sizeof(struct serial_struct)); 1153 memset(&sio, 0, sizeof(struct serial_struct));
1154 sio.line = portp->portnr; 1154 sio.line = portp->portnr;
1155 sio.port = portp->ioaddr; 1155 sio.port = portp->ioaddr;
1156 sio.flags = portp->flags; 1156 sio.flags = portp->port.flags;
1157 sio.baud_base = portp->baud_base; 1157 sio.baud_base = portp->baud_base;
1158 sio.close_delay = portp->close_delay; 1158 sio.close_delay = portp->close_delay;
1159 sio.closing_wait = portp->closing_wait; 1159 sio.closing_wait = portp->closing_wait;
@@ -1194,17 +1194,17 @@ static int stl_setserial(struct stlport *portp, struct serial_struct __user *sp)
1194 if ((sio.baud_base != portp->baud_base) || 1194 if ((sio.baud_base != portp->baud_base) ||
1195 (sio.close_delay != portp->close_delay) || 1195 (sio.close_delay != portp->close_delay) ||
1196 ((sio.flags & ~ASYNC_USR_MASK) != 1196 ((sio.flags & ~ASYNC_USR_MASK) !=
1197 (portp->flags & ~ASYNC_USR_MASK))) 1197 (portp->port.flags & ~ASYNC_USR_MASK)))
1198 return -EPERM; 1198 return -EPERM;
1199 } 1199 }
1200 1200
1201 portp->flags = (portp->flags & ~ASYNC_USR_MASK) | 1201 portp->port.flags = (portp->port.flags & ~ASYNC_USR_MASK) |
1202 (sio.flags & ASYNC_USR_MASK); 1202 (sio.flags & ASYNC_USR_MASK);
1203 portp->baud_base = sio.baud_base; 1203 portp->baud_base = sio.baud_base;
1204 portp->close_delay = sio.close_delay; 1204 portp->close_delay = sio.close_delay;
1205 portp->closing_wait = sio.closing_wait; 1205 portp->closing_wait = sio.closing_wait;
1206 portp->custom_divisor = sio.custom_divisor; 1206 portp->custom_divisor = sio.custom_divisor;
1207 stl_setport(portp, portp->tty->termios); 1207 stl_setport(portp, portp->port.tty->termios);
1208 return 0; 1208 return 0;
1209} 1209}
1210 1210
@@ -1353,7 +1353,7 @@ static void stl_settermios(struct tty_struct *tty, struct ktermios *old)
1353 stl_start(tty); 1353 stl_start(tty);
1354 } 1354 }
1355 if (((old->c_cflag & CLOCAL) == 0) && (tiosp->c_cflag & CLOCAL)) 1355 if (((old->c_cflag & CLOCAL) == 0) && (tiosp->c_cflag & CLOCAL))
1356 wake_up_interruptible(&portp->open_wait); 1356 wake_up_interruptible(&portp->port.open_wait);
1357} 1357}
1358 1358
1359/*****************************************************************************/ 1359/*****************************************************************************/
@@ -1438,7 +1438,7 @@ static void stl_hangup(struct tty_struct *tty)
1438 if (portp == NULL) 1438 if (portp == NULL)
1439 return; 1439 return;
1440 1440
1441 portp->flags &= ~ASYNC_INITIALIZED; 1441 portp->port.flags &= ~ASYNC_INITIALIZED;
1442 stl_disableintrs(portp); 1442 stl_disableintrs(portp);
1443 if (tty->termios->c_cflag & HUPCL) 1443 if (tty->termios->c_cflag & HUPCL)
1444 stl_setsignals(portp, 0, 0); 1444 stl_setsignals(portp, 0, 0);
@@ -1452,10 +1452,10 @@ static void stl_hangup(struct tty_struct *tty)
1452 portp->tx.head = NULL; 1452 portp->tx.head = NULL;
1453 portp->tx.tail = NULL; 1453 portp->tx.tail = NULL;
1454 } 1454 }
1455 portp->tty = NULL; 1455 portp->port.tty = NULL;
1456 portp->flags &= ~ASYNC_NORMAL_ACTIVE; 1456 portp->port.flags &= ~ASYNC_NORMAL_ACTIVE;
1457 portp->refcount = 0; 1457 portp->port.count = 0;
1458 wake_up_interruptible(&portp->open_wait); 1458 wake_up_interruptible(&portp->port.open_wait);
1459} 1459}
1460 1460
1461/*****************************************************************************/ 1461/*****************************************************************************/
@@ -1814,8 +1814,8 @@ static int __devinit stl_initports(struct stlbrd *brdp, struct stlpanel *panelp)
1814 portp->baud_base = STL_BAUDBASE; 1814 portp->baud_base = STL_BAUDBASE;
1815 portp->close_delay = STL_CLOSEDELAY; 1815 portp->close_delay = STL_CLOSEDELAY;
1816 portp->closing_wait = 30 * HZ; 1816 portp->closing_wait = 30 * HZ;
1817 init_waitqueue_head(&portp->open_wait); 1817 init_waitqueue_head(&portp->port.open_wait);
1818 init_waitqueue_head(&portp->close_wait); 1818 init_waitqueue_head(&portp->port.close_wait);
1819 portp->stats.brd = portp->brdnr; 1819 portp->stats.brd = portp->brdnr;
1820 portp->stats.panel = portp->panelnr; 1820 portp->stats.panel = portp->panelnr;
1821 portp->stats.port = portp->portnr; 1821 portp->stats.port = portp->portnr;
@@ -1840,8 +1840,8 @@ static void stl_cleanup_panels(struct stlbrd *brdp)
1840 portp = panelp->ports[k]; 1840 portp = panelp->ports[k];
1841 if (portp == NULL) 1841 if (portp == NULL)
1842 continue; 1842 continue;
1843 if (portp->tty != NULL) 1843 if (portp->port.tty != NULL)
1844 stl_hangup(portp->tty); 1844 stl_hangup(portp->port.tty);
1845 kfree(portp->tx.buf); 1845 kfree(portp->tx.buf);
1846 kfree(portp); 1846 kfree(portp);
1847 } 1847 }
@@ -2513,7 +2513,7 @@ static int stl_getportstats(struct stlport *portp, comstats_t __user *cp)
2513 } 2513 }
2514 2514
2515 portp->stats.state = portp->istate; 2515 portp->stats.state = portp->istate;
2516 portp->stats.flags = portp->flags; 2516 portp->stats.flags = portp->port.flags;
2517 portp->stats.hwid = portp->hwid; 2517 portp->stats.hwid = portp->hwid;
2518 2518
2519 portp->stats.ttystate = 0; 2519 portp->stats.ttystate = 0;
@@ -2524,16 +2524,16 @@ static int stl_getportstats(struct stlport *portp, comstats_t __user *cp)
2524 portp->stats.rxbuffered = 0; 2524 portp->stats.rxbuffered = 0;
2525 2525
2526 spin_lock_irqsave(&stallion_lock, flags); 2526 spin_lock_irqsave(&stallion_lock, flags);
2527 if (portp->tty != NULL) 2527 if (portp->port.tty != NULL)
2528 if (portp->tty->driver_data == portp) { 2528 if (portp->port.tty->driver_data == portp) {
2529 portp->stats.ttystate = portp->tty->flags; 2529 portp->stats.ttystate = portp->port.tty->flags;
2530 /* No longer available as a statistic */ 2530 /* No longer available as a statistic */
2531 portp->stats.rxbuffered = 1; /*portp->tty->flip.count; */ 2531 portp->stats.rxbuffered = 1; /*portp->port.tty->flip.count; */
2532 if (portp->tty->termios != NULL) { 2532 if (portp->port.tty->termios != NULL) {
2533 portp->stats.cflags = portp->tty->termios->c_cflag; 2533 portp->stats.cflags = portp->port.tty->termios->c_cflag;
2534 portp->stats.iflags = portp->tty->termios->c_iflag; 2534 portp->stats.iflags = portp->port.tty->termios->c_iflag;
2535 portp->stats.oflags = portp->tty->termios->c_oflag; 2535 portp->stats.oflags = portp->port.tty->termios->c_oflag;
2536 portp->stats.lflags = portp->tty->termios->c_lflag; 2536 portp->stats.lflags = portp->port.tty->termios->c_lflag;
2537 } 2537 }
2538 } 2538 }
2539 spin_unlock_irqrestore(&stallion_lock, flags); 2539 spin_unlock_irqrestore(&stallion_lock, flags);
@@ -2939,15 +2939,15 @@ static void stl_cd1400setport(struct stlport *portp, struct ktermios *tiosp)
2939 } 2939 }
2940 baudrate = stl_baudrates[baudrate]; 2940 baudrate = stl_baudrates[baudrate];
2941 if ((tiosp->c_cflag & CBAUD) == B38400) { 2941 if ((tiosp->c_cflag & CBAUD) == B38400) {
2942 if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) 2942 if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
2943 baudrate = 57600; 2943 baudrate = 57600;
2944 else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) 2944 else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
2945 baudrate = 115200; 2945 baudrate = 115200;
2946 else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) 2946 else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
2947 baudrate = 230400; 2947 baudrate = 230400;
2948 else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) 2948 else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
2949 baudrate = 460800; 2949 baudrate = 460800;
2950 else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) 2950 else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)
2951 baudrate = (portp->baud_base / portp->custom_divisor); 2951 baudrate = (portp->baud_base / portp->custom_divisor);
2952 } 2952 }
2953 if (baudrate > STL_CD1400MAXBAUD) 2953 if (baudrate > STL_CD1400MAXBAUD)
@@ -2969,9 +2969,9 @@ static void stl_cd1400setport(struct stlport *portp, struct ktermios *tiosp)
2969 mcor1 |= MCOR1_DCD; 2969 mcor1 |= MCOR1_DCD;
2970 mcor2 |= MCOR2_DCD; 2970 mcor2 |= MCOR2_DCD;
2971 sreron |= SRER_MODEM; 2971 sreron |= SRER_MODEM;
2972 portp->flags |= ASYNC_CHECK_CD; 2972 portp->port.flags |= ASYNC_CHECK_CD;
2973 } else 2973 } else
2974 portp->flags &= ~ASYNC_CHECK_CD; 2974 portp->port.flags &= ~ASYNC_CHECK_CD;
2975 2975
2976/* 2976/*
2977 * Setup cd1400 enhanced modes if we can. In particular we want to 2977 * Setup cd1400 enhanced modes if we can. In particular we want to
@@ -3242,7 +3242,7 @@ static void stl_cd1400flowctrl(struct stlport *portp, int state)
3242 3242
3243 if (portp == NULL) 3243 if (portp == NULL)
3244 return; 3244 return;
3245 tty = portp->tty; 3245 tty = portp->port.tty;
3246 if (tty == NULL) 3246 if (tty == NULL)
3247 return; 3247 return;
3248 3248
@@ -3304,7 +3304,7 @@ static void stl_cd1400sendflow(struct stlport *portp, int state)
3304 3304
3305 if (portp == NULL) 3305 if (portp == NULL)
3306 return; 3306 return;
3307 tty = portp->tty; 3307 tty = portp->port.tty;
3308 if (tty == NULL) 3308 if (tty == NULL)
3309 return; 3309 return;
3310 3310
@@ -3503,8 +3503,8 @@ static void stl_cd1400txisr(struct stlpanel *panelp, int ioaddr)
3503 if ((len == 0) || ((len < STL_TXBUFLOW) && 3503 if ((len == 0) || ((len < STL_TXBUFLOW) &&
3504 (test_bit(ASYI_TXLOW, &portp->istate) == 0))) { 3504 (test_bit(ASYI_TXLOW, &portp->istate) == 0))) {
3505 set_bit(ASYI_TXLOW, &portp->istate); 3505 set_bit(ASYI_TXLOW, &portp->istate);
3506 if (portp->tty) 3506 if (portp->port.tty)
3507 tty_wakeup(portp->tty); 3507 tty_wakeup(portp->port.tty);
3508 } 3508 }
3509 3509
3510 if (len == 0) { 3510 if (len == 0) {
@@ -3568,7 +3568,7 @@ static void stl_cd1400rxisr(struct stlpanel *panelp, int ioaddr)
3568 return; 3568 return;
3569 } 3569 }
3570 portp = panelp->ports[(ioack >> 3)]; 3570 portp = panelp->ports[(ioack >> 3)];
3571 tty = portp->tty; 3571 tty = portp->port.tty;
3572 3572
3573 if ((ioack & ACK_TYPMASK) == ACK_TYPRXGOOD) { 3573 if ((ioack & ACK_TYPMASK) == ACK_TYPRXGOOD) {
3574 outb((RDCR + portp->uartaddr), ioaddr); 3574 outb((RDCR + portp->uartaddr), ioaddr);
@@ -3613,7 +3613,7 @@ static void stl_cd1400rxisr(struct stlpanel *panelp, int ioaddr)
3613 if (portp->rxmarkmsk & status) { 3613 if (portp->rxmarkmsk & status) {
3614 if (status & ST_BREAK) { 3614 if (status & ST_BREAK) {
3615 status = TTY_BREAK; 3615 status = TTY_BREAK;
3616 if (portp->flags & ASYNC_SAK) { 3616 if (portp->port.flags & ASYNC_SAK) {
3617 do_SAK(tty); 3617 do_SAK(tty);
3618 BRDENABLE(portp->brdnr, portp->pagenr); 3618 BRDENABLE(portp->brdnr, portp->pagenr);
3619 } 3619 }
@@ -3899,15 +3899,15 @@ static void stl_sc26198setport(struct stlport *portp, struct ktermios *tiosp)
3899 } 3899 }
3900 baudrate = stl_baudrates[baudrate]; 3900 baudrate = stl_baudrates[baudrate];
3901 if ((tiosp->c_cflag & CBAUD) == B38400) { 3901 if ((tiosp->c_cflag & CBAUD) == B38400) {
3902 if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI) 3902 if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_HI)
3903 baudrate = 57600; 3903 baudrate = 57600;
3904 else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI) 3904 else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
3905 baudrate = 115200; 3905 baudrate = 115200;
3906 else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI) 3906 else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_SHI)
3907 baudrate = 230400; 3907 baudrate = 230400;
3908 else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP) 3908 else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_WARP)
3909 baudrate = 460800; 3909 baudrate = 460800;
3910 else if ((portp->flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST) 3910 else if ((portp->port.flags & ASYNC_SPD_MASK) == ASYNC_SPD_CUST)
3911 baudrate = (portp->baud_base / portp->custom_divisor); 3911 baudrate = (portp->baud_base / portp->custom_divisor);
3912 } 3912 }
3913 if (baudrate > STL_SC26198MAXBAUD) 3913 if (baudrate > STL_SC26198MAXBAUD)
@@ -3922,11 +3922,11 @@ static void stl_sc26198setport(struct stlport *portp, struct ktermios *tiosp)
3922 * Check what form of modem signaling is required and set it up. 3922 * Check what form of modem signaling is required and set it up.
3923 */ 3923 */
3924 if (tiosp->c_cflag & CLOCAL) { 3924 if (tiosp->c_cflag & CLOCAL) {
3925 portp->flags &= ~ASYNC_CHECK_CD; 3925 portp->port.flags &= ~ASYNC_CHECK_CD;
3926 } else { 3926 } else {
3927 iopr |= IOPR_DCDCOS; 3927 iopr |= IOPR_DCDCOS;
3928 imron |= IR_IOPORT; 3928 imron |= IR_IOPORT;
3929 portp->flags |= ASYNC_CHECK_CD; 3929 portp->port.flags |= ASYNC_CHECK_CD;
3930 } 3930 }
3931 3931
3932/* 3932/*
@@ -4174,7 +4174,7 @@ static void stl_sc26198flowctrl(struct stlport *portp, int state)
4174 4174
4175 if (portp == NULL) 4175 if (portp == NULL)
4176 return; 4176 return;
4177 tty = portp->tty; 4177 tty = portp->port.tty;
4178 if (tty == NULL) 4178 if (tty == NULL)
4179 return; 4179 return;
4180 4180
@@ -4243,7 +4243,7 @@ static void stl_sc26198sendflow(struct stlport *portp, int state)
4243 4243
4244 if (portp == NULL) 4244 if (portp == NULL)
4245 return; 4245 return;
4246 tty = portp->tty; 4246 tty = portp->port.tty;
4247 if (tty == NULL) 4247 if (tty == NULL)
4248 return; 4248 return;
4249 4249
@@ -4421,8 +4421,8 @@ static void stl_sc26198txisr(struct stlport *portp)
4421 if ((len == 0) || ((len < STL_TXBUFLOW) && 4421 if ((len == 0) || ((len < STL_TXBUFLOW) &&
4422 (test_bit(ASYI_TXLOW, &portp->istate) == 0))) { 4422 (test_bit(ASYI_TXLOW, &portp->istate) == 0))) {
4423 set_bit(ASYI_TXLOW, &portp->istate); 4423 set_bit(ASYI_TXLOW, &portp->istate);
4424 if (portp->tty) 4424 if (portp->port.tty)
4425 tty_wakeup(portp->tty); 4425 tty_wakeup(portp->port.tty);
4426 } 4426 }
4427 4427
4428 if (len == 0) { 4428 if (len == 0) {
@@ -4475,7 +4475,7 @@ static void stl_sc26198rxisr(struct stlport *portp, unsigned int iack)
4475 4475
4476 pr_debug("stl_sc26198rxisr(portp=%p,iack=%x)\n", portp, iack); 4476 pr_debug("stl_sc26198rxisr(portp=%p,iack=%x)\n", portp, iack);
4477 4477
4478 tty = portp->tty; 4478 tty = portp->port.tty;
4479 ioaddr = portp->ioaddr; 4479 ioaddr = portp->ioaddr;
4480 outb(GIBCR, (ioaddr + XP_ADDR)); 4480 outb(GIBCR, (ioaddr + XP_ADDR));
4481 len = inb(ioaddr + XP_DATA) + 1; 4481 len = inb(ioaddr + XP_DATA) + 1;
@@ -4527,7 +4527,7 @@ static void stl_sc26198rxbadch(struct stlport *portp, unsigned char status, char
4527 struct tty_struct *tty; 4527 struct tty_struct *tty;
4528 unsigned int ioaddr; 4528 unsigned int ioaddr;
4529 4529
4530 tty = portp->tty; 4530 tty = portp->port.tty;
4531 ioaddr = portp->ioaddr; 4531 ioaddr = portp->ioaddr;
4532 4532
4533 if (status & SR_RXPARITY) 4533 if (status & SR_RXPARITY)
@@ -4544,7 +4544,7 @@ static void stl_sc26198rxbadch(struct stlport *portp, unsigned char status, char
4544 if (portp->rxmarkmsk & status) { 4544 if (portp->rxmarkmsk & status) {
4545 if (status & SR_RXBREAK) { 4545 if (status & SR_RXBREAK) {
4546 status = TTY_BREAK; 4546 status = TTY_BREAK;
4547 if (portp->flags & ASYNC_SAK) { 4547 if (portp->port.flags & ASYNC_SAK) {
4548 do_SAK(tty); 4548 do_SAK(tty);
4549 BRDENABLE(portp->brdnr, portp->pagenr); 4549 BRDENABLE(portp->brdnr, portp->pagenr);
4550 } 4550 }
diff --git a/drivers/char/sx.c b/drivers/char/sx.c
index b1a7a8cb65ea..d5cffcd6a572 100644
--- a/drivers/char/sx.c
+++ b/drivers/char/sx.c
@@ -1,4 +1,3 @@
1
2/* sx.c -- driver for the Specialix SX series cards. 1/* sx.c -- driver for the Specialix SX series cards.
3 * 2 *
4 * This driver will also support the older SI, and XIO cards. 3 * This driver will also support the older SI, and XIO cards.
@@ -930,7 +929,7 @@ static int sx_set_real_termios(void *ptr)
930 929
931 func_enter2(); 930 func_enter2();
932 931
933 if (!port->gs.tty) 932 if (!port->gs.port.tty)
934 return 0; 933 return 0;
935 934
936 /* What is this doing here? -- REW 935 /* What is this doing here? -- REW
@@ -941,19 +940,19 @@ static int sx_set_real_termios(void *ptr)
941 940
942 sx_set_baud(port); 941 sx_set_baud(port);
943 942
944#define CFLAG port->gs.tty->termios->c_cflag 943#define CFLAG port->gs.port.tty->termios->c_cflag
945 sx_write_channel_byte(port, hi_mr1, 944 sx_write_channel_byte(port, hi_mr1,
946 (C_PARENB(port->gs.tty) ? MR1_WITH : MR1_NONE) | 945 (C_PARENB(port->gs.port.tty) ? MR1_WITH : MR1_NONE) |
947 (C_PARODD(port->gs.tty) ? MR1_ODD : MR1_EVEN) | 946 (C_PARODD(port->gs.port.tty) ? MR1_ODD : MR1_EVEN) |
948 (C_CRTSCTS(port->gs.tty) ? MR1_RTS_RXFLOW : 0) | 947 (C_CRTSCTS(port->gs.port.tty) ? MR1_RTS_RXFLOW : 0) |
949 (((CFLAG & CSIZE) == CS8) ? MR1_8_BITS : 0) | 948 (((CFLAG & CSIZE) == CS8) ? MR1_8_BITS : 0) |
950 (((CFLAG & CSIZE) == CS7) ? MR1_7_BITS : 0) | 949 (((CFLAG & CSIZE) == CS7) ? MR1_7_BITS : 0) |
951 (((CFLAG & CSIZE) == CS6) ? MR1_6_BITS : 0) | 950 (((CFLAG & CSIZE) == CS6) ? MR1_6_BITS : 0) |
952 (((CFLAG & CSIZE) == CS5) ? MR1_5_BITS : 0)); 951 (((CFLAG & CSIZE) == CS5) ? MR1_5_BITS : 0));
953 952
954 sx_write_channel_byte(port, hi_mr2, 953 sx_write_channel_byte(port, hi_mr2,
955 (C_CRTSCTS(port->gs.tty) ? MR2_CTS_TXFLOW : 0) | 954 (C_CRTSCTS(port->gs.port.tty) ? MR2_CTS_TXFLOW : 0) |
956 (C_CSTOPB(port->gs.tty) ? MR2_2_STOP : 955 (C_CSTOPB(port->gs.port.tty) ? MR2_2_STOP :
957 MR2_1_STOP)); 956 MR2_1_STOP));
958 957
959 switch (CFLAG & CSIZE) { 958 switch (CFLAG & CSIZE) {
@@ -976,44 +975,44 @@ static int sx_set_real_termios(void *ptr)
976 } 975 }
977 976
978 sx_write_channel_byte(port, hi_prtcl, 977 sx_write_channel_byte(port, hi_prtcl,
979 (I_IXON(port->gs.tty) ? SP_TXEN : 0) | 978 (I_IXON(port->gs.port.tty) ? SP_TXEN : 0) |
980 (I_IXOFF(port->gs.tty) ? SP_RXEN : 0) | 979 (I_IXOFF(port->gs.port.tty) ? SP_RXEN : 0) |
981 (I_IXANY(port->gs.tty) ? SP_TANY : 0) | SP_DCEN); 980 (I_IXANY(port->gs.port.tty) ? SP_TANY : 0) | SP_DCEN);
982 981
983 sx_write_channel_byte(port, hi_break, 982 sx_write_channel_byte(port, hi_break,
984 (I_IGNBRK(port->gs.tty) ? BR_IGN : 0 | 983 (I_IGNBRK(port->gs.port.tty) ? BR_IGN : 0 |
985 I_BRKINT(port->gs.tty) ? BR_INT : 0)); 984 I_BRKINT(port->gs.port.tty) ? BR_INT : 0));
986 985
987 sx_write_channel_byte(port, hi_txon, START_CHAR(port->gs.tty)); 986 sx_write_channel_byte(port, hi_txon, START_CHAR(port->gs.port.tty));
988 sx_write_channel_byte(port, hi_rxon, START_CHAR(port->gs.tty)); 987 sx_write_channel_byte(port, hi_rxon, START_CHAR(port->gs.port.tty));
989 sx_write_channel_byte(port, hi_txoff, STOP_CHAR(port->gs.tty)); 988 sx_write_channel_byte(port, hi_txoff, STOP_CHAR(port->gs.port.tty));
990 sx_write_channel_byte(port, hi_rxoff, STOP_CHAR(port->gs.tty)); 989 sx_write_channel_byte(port, hi_rxoff, STOP_CHAR(port->gs.port.tty));
991 990
992 sx_reconfigure_port(port); 991 sx_reconfigure_port(port);
993 992
994 /* Tell line discipline whether we will do input cooking */ 993 /* Tell line discipline whether we will do input cooking */
995 if (I_OTHER(port->gs.tty)) { 994 if (I_OTHER(port->gs.port.tty)) {
996 clear_bit(TTY_HW_COOK_IN, &port->gs.tty->flags); 995 clear_bit(TTY_HW_COOK_IN, &port->gs.port.tty->flags);
997 } else { 996 } else {
998 set_bit(TTY_HW_COOK_IN, &port->gs.tty->flags); 997 set_bit(TTY_HW_COOK_IN, &port->gs.port.tty->flags);
999 } 998 }
1000 sx_dprintk(SX_DEBUG_TERMIOS, "iflags: %x(%d) ", 999 sx_dprintk(SX_DEBUG_TERMIOS, "iflags: %x(%d) ",
1001 (unsigned int)port->gs.tty->termios->c_iflag, 1000 (unsigned int)port->gs.port.tty->termios->c_iflag,
1002 I_OTHER(port->gs.tty)); 1001 I_OTHER(port->gs.port.tty));
1003 1002
1004/* Tell line discipline whether we will do output cooking. 1003/* Tell line discipline whether we will do output cooking.
1005 * If OPOST is set and no other output flags are set then we can do output 1004 * If OPOST is set and no other output flags are set then we can do output
1006 * processing. Even if only *one* other flag in the O_OTHER group is set 1005 * processing. Even if only *one* other flag in the O_OTHER group is set
1007 * we do cooking in software. 1006 * we do cooking in software.
1008 */ 1007 */
1009 if (O_OPOST(port->gs.tty) && !O_OTHER(port->gs.tty)) { 1008 if (O_OPOST(port->gs.port.tty) && !O_OTHER(port->gs.port.tty)) {
1010 set_bit(TTY_HW_COOK_OUT, &port->gs.tty->flags); 1009 set_bit(TTY_HW_COOK_OUT, &port->gs.port.tty->flags);
1011 } else { 1010 } else {
1012 clear_bit(TTY_HW_COOK_OUT, &port->gs.tty->flags); 1011 clear_bit(TTY_HW_COOK_OUT, &port->gs.port.tty->flags);
1013 } 1012 }
1014 sx_dprintk(SX_DEBUG_TERMIOS, "oflags: %x(%d)\n", 1013 sx_dprintk(SX_DEBUG_TERMIOS, "oflags: %x(%d)\n",
1015 (unsigned int)port->gs.tty->termios->c_oflag, 1014 (unsigned int)port->gs.port.tty->termios->c_oflag,
1016 O_OTHER(port->gs.tty)); 1015 O_OTHER(port->gs.port.tty));
1017 /* port->c_dcd = sx_get_CD (port); */ 1016 /* port->c_dcd = sx_get_CD (port); */
1018 func_exit(); 1017 func_exit();
1019 return 0; 1018 return 0;
@@ -1102,8 +1101,8 @@ static void sx_transmit_chars(struct sx_port *port)
1102 sx_disable_tx_interrupts(port); 1101 sx_disable_tx_interrupts(port);
1103 } 1102 }
1104 1103
1105 if ((port->gs.xmit_cnt <= port->gs.wakeup_chars) && port->gs.tty) { 1104 if ((port->gs.xmit_cnt <= port->gs.wakeup_chars) && port->gs.port.tty) {
1106 tty_wakeup(port->gs.tty); 1105 tty_wakeup(port->gs.port.tty);
1107 sx_dprintk(SX_DEBUG_TRANSMIT, "Waking up.... ldisc (%d)....\n", 1106 sx_dprintk(SX_DEBUG_TRANSMIT, "Waking up.... ldisc (%d)....\n",
1108 port->gs.wakeup_chars); 1107 port->gs.wakeup_chars);
1109 } 1108 }
@@ -1126,7 +1125,7 @@ static inline void sx_receive_chars(struct sx_port *port)
1126 unsigned char *rp; 1125 unsigned char *rp;
1127 1126
1128 func_enter2(); 1127 func_enter2();
1129 tty = port->gs.tty; 1128 tty = port->gs.port.tty;
1130 while (1) { 1129 while (1) {
1131 rx_op = sx_read_channel_byte(port, hi_rxopos); 1130 rx_op = sx_read_channel_byte(port, hi_rxopos);
1132 c = (sx_read_channel_byte(port, hi_rxipos) - rx_op) & 0xff; 1131 c = (sx_read_channel_byte(port, hi_rxipos) - rx_op) & 0xff;
@@ -1211,12 +1210,12 @@ static inline void sx_check_modem_signals(struct sx_port *port)
1211 /* DCD went UP */ 1210 /* DCD went UP */
1212 if ((sx_read_channel_byte(port, hi_hstat) != 1211 if ((sx_read_channel_byte(port, hi_hstat) !=
1213 HS_IDLE_CLOSED) && 1212 HS_IDLE_CLOSED) &&
1214 !(port->gs.tty->termios-> 1213 !(port->gs.port.tty->termios->
1215 c_cflag & CLOCAL)) { 1214 c_cflag & CLOCAL)) {
1216 /* Are we blocking in open? */ 1215 /* Are we blocking in open? */
1217 sx_dprintk(SX_DEBUG_MODEMSIGNALS, "DCD " 1216 sx_dprintk(SX_DEBUG_MODEMSIGNALS, "DCD "
1218 "active, unblocking open\n"); 1217 "active, unblocking open\n");
1219 wake_up_interruptible(&port->gs. 1218 wake_up_interruptible(&port->gs.port.
1220 open_wait); 1219 open_wait);
1221 } else { 1220 } else {
1222 sx_dprintk(SX_DEBUG_MODEMSIGNALS, "DCD " 1221 sx_dprintk(SX_DEBUG_MODEMSIGNALS, "DCD "
@@ -1224,10 +1223,10 @@ static inline void sx_check_modem_signals(struct sx_port *port)
1224 } 1223 }
1225 } else { 1224 } else {
1226 /* DCD went down! */ 1225 /* DCD went down! */
1227 if (!(port->gs.tty->termios->c_cflag & CLOCAL)){ 1226 if (!(port->gs.port.tty->termios->c_cflag & CLOCAL)){
1228 sx_dprintk(SX_DEBUG_MODEMSIGNALS, "DCD " 1227 sx_dprintk(SX_DEBUG_MODEMSIGNALS, "DCD "
1229 "dropped. hanging up....\n"); 1228 "dropped. hanging up....\n");
1230 tty_hangup(port->gs.tty); 1229 tty_hangup(port->gs.port.tty);
1231 } else { 1230 } else {
1232 sx_dprintk(SX_DEBUG_MODEMSIGNALS, "DCD " 1231 sx_dprintk(SX_DEBUG_MODEMSIGNALS, "DCD "
1233 "dropped. ignoring.\n"); 1232 "dropped. ignoring.\n");
@@ -1325,7 +1324,7 @@ static irqreturn_t sx_interrupt(int irq, void *ptr)
1325 1324
1326 for (i = 0; i < board->nports; i++) { 1325 for (i = 0; i < board->nports; i++) {
1327 port = &board->ports[i]; 1326 port = &board->ports[i];
1328 if (port->gs.flags & GS_ACTIVE) { 1327 if (port->gs.port.flags & GS_ACTIVE) {
1329 if (sx_read_channel_byte(port, hi_state)) { 1328 if (sx_read_channel_byte(port, hi_state)) {
1330 sx_dprintk(SX_DEBUG_INTERRUPTS, "Port %d: " 1329 sx_dprintk(SX_DEBUG_INTERRUPTS, "Port %d: "
1331 "modem signal change?... \n",i); 1330 "modem signal change?... \n",i);
@@ -1334,7 +1333,7 @@ static irqreturn_t sx_interrupt(int irq, void *ptr)
1334 if (port->gs.xmit_cnt) { 1333 if (port->gs.xmit_cnt) {
1335 sx_transmit_chars(port); 1334 sx_transmit_chars(port);
1336 } 1335 }
1337 if (!(port->gs.flags & SX_RX_THROTTLE)) { 1336 if (!(port->gs.port.flags & SX_RX_THROTTLE)) {
1338 sx_receive_chars(port); 1337 sx_receive_chars(port);
1339 } 1338 }
1340 } 1339 }
@@ -1373,7 +1372,7 @@ static void sx_disable_tx_interrupts(void *ptr)
1373 struct sx_port *port = ptr; 1372 struct sx_port *port = ptr;
1374 func_enter2(); 1373 func_enter2();
1375 1374
1376 port->gs.flags &= ~GS_TX_INTEN; 1375 port->gs.port.flags &= ~GS_TX_INTEN;
1377 1376
1378 func_exit(); 1377 func_exit();
1379} 1378}
@@ -1394,7 +1393,7 @@ static void sx_enable_tx_interrupts(void *ptr)
1394 1393
1395 /* XXX Must be "HIGH_WATER" for SI card according to doc. */ 1394 /* XXX Must be "HIGH_WATER" for SI card according to doc. */
1396 if (data_in_buffer < LOW_WATER) 1395 if (data_in_buffer < LOW_WATER)
1397 port->gs.flags &= ~GS_TX_INTEN; 1396 port->gs.port.flags &= ~GS_TX_INTEN;
1398 1397
1399 func_exit(); 1398 func_exit();
1400} 1399}
@@ -1442,8 +1441,8 @@ static void sx_shutdown_port(void *ptr)
1442 1441
1443 func_enter(); 1442 func_enter();
1444 1443
1445 port->gs.flags &= ~GS_ACTIVE; 1444 port->gs.port.flags &= ~GS_ACTIVE;
1446 if (port->gs.tty && (port->gs.tty->termios->c_cflag & HUPCL)) { 1445 if (port->gs.port.tty && (port->gs.port.tty->termios->c_cflag & HUPCL)) {
1447 sx_setsignals(port, 0, 0); 1446 sx_setsignals(port, 0, 0);
1448 sx_reconfigure_port(port); 1447 sx_reconfigure_port(port);
1449 } 1448 }
@@ -1485,8 +1484,8 @@ static int sx_open(struct tty_struct *tty, struct file *filp)
1485 spin_lock_irqsave(&port->gs.driver_lock, flags); 1484 spin_lock_irqsave(&port->gs.driver_lock, flags);
1486 1485
1487 tty->driver_data = port; 1486 tty->driver_data = port;
1488 port->gs.tty = tty; 1487 port->gs.port.tty = tty;
1489 port->gs.count++; 1488 port->gs.port.count++;
1490 spin_unlock_irqrestore(&port->gs.driver_lock, flags); 1489 spin_unlock_irqrestore(&port->gs.driver_lock, flags);
1491 1490
1492 sx_dprintk(SX_DEBUG_OPEN, "starting port\n"); 1491 sx_dprintk(SX_DEBUG_OPEN, "starting port\n");
@@ -1497,12 +1496,12 @@ static int sx_open(struct tty_struct *tty, struct file *filp)
1497 retval = gs_init_port(&port->gs); 1496 retval = gs_init_port(&port->gs);
1498 sx_dprintk(SX_DEBUG_OPEN, "done gs_init\n"); 1497 sx_dprintk(SX_DEBUG_OPEN, "done gs_init\n");
1499 if (retval) { 1498 if (retval) {
1500 port->gs.count--; 1499 port->gs.port.count--;
1501 return retval; 1500 return retval;
1502 } 1501 }
1503 1502
1504 port->gs.flags |= GS_ACTIVE; 1503 port->gs.port.flags |= GS_ACTIVE;
1505 if (port->gs.count <= 1) 1504 if (port->gs.port.count <= 1)
1506 sx_setsignals(port, 1, 1); 1505 sx_setsignals(port, 1, 1);
1507 1506
1508#if 0 1507#if 0
@@ -1513,12 +1512,12 @@ static int sx_open(struct tty_struct *tty, struct file *filp)
1513 my_hd_io(port->board->base + port->ch_base, sizeof(*port)); 1512 my_hd_io(port->board->base + port->ch_base, sizeof(*port));
1514#endif 1513#endif
1515 1514
1516 if (port->gs.count <= 1) { 1515 if (port->gs.port.count <= 1) {
1517 if (sx_send_command(port, HS_LOPEN, -1, HS_IDLE_OPEN) != 1) { 1516 if (sx_send_command(port, HS_LOPEN, -1, HS_IDLE_OPEN) != 1) {
1518 printk(KERN_ERR "sx: Card didn't respond to LOPEN " 1517 printk(KERN_ERR "sx: Card didn't respond to LOPEN "
1519 "command.\n"); 1518 "command.\n");
1520 spin_lock_irqsave(&port->gs.driver_lock, flags); 1519 spin_lock_irqsave(&port->gs.driver_lock, flags);
1521 port->gs.count--; 1520 port->gs.port.count--;
1522 spin_unlock_irqrestore(&port->gs.driver_lock, flags); 1521 spin_unlock_irqrestore(&port->gs.driver_lock, flags);
1523 return -EIO; 1522 return -EIO;
1524 } 1523 }
@@ -1526,11 +1525,11 @@ static int sx_open(struct tty_struct *tty, struct file *filp)
1526 1525
1527 retval = gs_block_til_ready(port, filp); 1526 retval = gs_block_til_ready(port, filp);
1528 sx_dprintk(SX_DEBUG_OPEN, "Block til ready returned %d. Count=%d\n", 1527 sx_dprintk(SX_DEBUG_OPEN, "Block til ready returned %d. Count=%d\n",
1529 retval, port->gs.count); 1528 retval, port->gs.port.count);
1530 1529
1531 if (retval) { 1530 if (retval) {
1532/* 1531/*
1533 * Don't lower gs.count here because sx_close() will be called later 1532 * Don't lower gs.port.count here because sx_close() will be called later
1534 */ 1533 */
1535 1534
1536 return retval; 1535 return retval;
@@ -1571,14 +1570,14 @@ static void sx_close(void *ptr)
1571 } 1570 }
1572 1571
1573 sx_dprintk(SX_DEBUG_CLOSE, "waited %d jiffies for close. count=%d\n", 1572 sx_dprintk(SX_DEBUG_CLOSE, "waited %d jiffies for close. count=%d\n",
1574 5 * HZ - to - 1, port->gs.count); 1573 5 * HZ - to - 1, port->gs.port.count);
1575 1574
1576 if (port->gs.count) { 1575 if (port->gs.port.count) {
1577 sx_dprintk(SX_DEBUG_CLOSE, "WARNING port count:%d\n", 1576 sx_dprintk(SX_DEBUG_CLOSE, "WARNING port count:%d\n",
1578 port->gs.count); 1577 port->gs.port.count);
1579 /*printk("%s SETTING port count to zero: %p count: %d\n", 1578 /*printk("%s SETTING port count to zero: %p count: %d\n",
1580 __func__, port, port->gs.count); 1579 __func__, port, port->gs.port.count);
1581 port->gs.count = 0;*/ 1580 port->gs.port.count = 0;*/
1582 } 1581 }
1583 1582
1584 func_exit(); 1583 func_exit();
@@ -1939,7 +1938,7 @@ static void sx_throttle(struct tty_struct *tty)
1939 * control then throttle the port. 1938 * control then throttle the port.
1940 */ 1939 */
1941 if ((tty->termios->c_cflag & CRTSCTS) || (I_IXOFF(tty))) { 1940 if ((tty->termios->c_cflag & CRTSCTS) || (I_IXOFF(tty))) {
1942 port->gs.flags |= SX_RX_THROTTLE; 1941 port->gs.port.flags |= SX_RX_THROTTLE;
1943 } 1942 }
1944 func_exit(); 1943 func_exit();
1945} 1944}
@@ -1953,7 +1952,7 @@ static void sx_unthrottle(struct tty_struct *tty)
1953 * this port in case we disabled flow control while the port 1952 * this port in case we disabled flow control while the port
1954 * was throttled 1953 * was throttled
1955 */ 1954 */
1956 port->gs.flags &= ~SX_RX_THROTTLE; 1955 port->gs.port.flags &= ~SX_RX_THROTTLE;
1957 func_exit(); 1956 func_exit();
1958 return; 1957 return;
1959} 1958}
@@ -2396,6 +2395,7 @@ static int sx_init_portstructs(int nboards, int nports)
2396 board->ports = port; 2395 board->ports = port;
2397 for (j = 0; j < boards[i].nports; j++) { 2396 for (j = 0; j < boards[i].nports; j++) {
2398 sx_dprintk(SX_DEBUG_INIT, "initing port %d\n", j); 2397 sx_dprintk(SX_DEBUG_INIT, "initing port %d\n", j);
2398 tty_port_init(&port->gs.port);
2399 port->gs.magic = SX_MAGIC; 2399 port->gs.magic = SX_MAGIC;
2400 port->gs.close_delay = HZ / 2; 2400 port->gs.close_delay = HZ / 2;
2401 port->gs.closing_wait = 30 * HZ; 2401 port->gs.closing_wait = 30 * HZ;
@@ -2408,9 +2408,6 @@ static int sx_init_portstructs(int nboards, int nports)
2408 /* 2408 /*
2409 * Initializing wait queue 2409 * Initializing wait queue
2410 */ 2410 */
2411 init_waitqueue_head(&port->gs.open_wait);
2412 init_waitqueue_head(&port->gs.close_wait);
2413
2414 port++; 2411 port++;
2415 } 2412 }
2416 } 2413 }
diff --git a/drivers/char/synclink.c b/drivers/char/synclink.c
index ac5080df2565..527d220aa4aa 100644
--- a/drivers/char/synclink.c
+++ b/drivers/char/synclink.c
@@ -180,19 +180,14 @@ struct tx_holding_buffer {
180 180
181struct mgsl_struct { 181struct mgsl_struct {
182 int magic; 182 int magic;
183 int flags; 183 struct tty_port port;
184 int count; /* count of opens */
185 int line; 184 int line;
186 int hw_version; 185 int hw_version;
187 unsigned short close_delay;
188 unsigned short closing_wait; /* time to wait before closing */
189 186
190 struct mgsl_icount icount; 187 struct mgsl_icount icount;
191 188
192 struct tty_struct *tty;
193 int timeout; 189 int timeout;
194 int x_char; /* xon/xoff character */ 190 int x_char; /* xon/xoff character */
195 int blocked_open; /* # of blocked opens */
196 u16 read_status_mask; 191 u16 read_status_mask;
197 u16 ignore_status_mask; 192 u16 ignore_status_mask;
198 unsigned char *xmit_buf; 193 unsigned char *xmit_buf;
@@ -200,9 +195,6 @@ struct mgsl_struct {
200 int xmit_tail; 195 int xmit_tail;
201 int xmit_cnt; 196 int xmit_cnt;
202 197
203 wait_queue_head_t open_wait;
204 wait_queue_head_t close_wait;
205
206 wait_queue_head_t status_event_wait_q; 198 wait_queue_head_t status_event_wait_q;
207 wait_queue_head_t event_wait_q; 199 wait_queue_head_t event_wait_q;
208 struct timer_list tx_timer; /* HDLC transmit timeout timer */ 200 struct timer_list tx_timer; /* HDLC transmit timeout timer */
@@ -975,8 +967,8 @@ static void ldisc_receive_buf(struct tty_struct *tty,
975 return; 967 return;
976 ld = tty_ldisc_ref(tty); 968 ld = tty_ldisc_ref(tty);
977 if (ld) { 969 if (ld) {
978 if (ld->receive_buf) 970 if (ld->ops->receive_buf)
979 ld->receive_buf(tty, data, flags, count); 971 ld->ops->receive_buf(tty, data, flags, count);
980 tty_ldisc_deref(ld); 972 tty_ldisc_deref(ld);
981 } 973 }
982} 974}
@@ -1134,7 +1126,7 @@ static void mgsl_bh_receive(struct mgsl_struct *info)
1134 1126
1135static void mgsl_bh_transmit(struct mgsl_struct *info) 1127static void mgsl_bh_transmit(struct mgsl_struct *info)
1136{ 1128{
1137 struct tty_struct *tty = info->tty; 1129 struct tty_struct *tty = info->port.tty;
1138 unsigned long flags; 1130 unsigned long flags;
1139 1131
1140 if ( debug_level >= DEBUG_LEVEL_BH ) 1132 if ( debug_level >= DEBUG_LEVEL_BH )
@@ -1276,7 +1268,7 @@ static void mgsl_isr_transmit_status( struct mgsl_struct *info )
1276 else 1268 else
1277#endif 1269#endif
1278 { 1270 {
1279 if (info->tty->stopped || info->tty->hw_stopped) { 1271 if (info->port.tty->stopped || info->port.tty->hw_stopped) {
1280 usc_stop_transmitter(info); 1272 usc_stop_transmitter(info);
1281 return; 1273 return;
1282 } 1274 }
@@ -1357,29 +1349,29 @@ static void mgsl_isr_io_pin( struct mgsl_struct *info )
1357 wake_up_interruptible(&info->status_event_wait_q); 1349 wake_up_interruptible(&info->status_event_wait_q);
1358 wake_up_interruptible(&info->event_wait_q); 1350 wake_up_interruptible(&info->event_wait_q);
1359 1351
1360 if ( (info->flags & ASYNC_CHECK_CD) && 1352 if ( (info->port.flags & ASYNC_CHECK_CD) &&
1361 (status & MISCSTATUS_DCD_LATCHED) ) { 1353 (status & MISCSTATUS_DCD_LATCHED) ) {
1362 if ( debug_level >= DEBUG_LEVEL_ISR ) 1354 if ( debug_level >= DEBUG_LEVEL_ISR )
1363 printk("%s CD now %s...", info->device_name, 1355 printk("%s CD now %s...", info->device_name,
1364 (status & MISCSTATUS_DCD) ? "on" : "off"); 1356 (status & MISCSTATUS_DCD) ? "on" : "off");
1365 if (status & MISCSTATUS_DCD) 1357 if (status & MISCSTATUS_DCD)
1366 wake_up_interruptible(&info->open_wait); 1358 wake_up_interruptible(&info->port.open_wait);
1367 else { 1359 else {
1368 if ( debug_level >= DEBUG_LEVEL_ISR ) 1360 if ( debug_level >= DEBUG_LEVEL_ISR )
1369 printk("doing serial hangup..."); 1361 printk("doing serial hangup...");
1370 if (info->tty) 1362 if (info->port.tty)
1371 tty_hangup(info->tty); 1363 tty_hangup(info->port.tty);
1372 } 1364 }
1373 } 1365 }
1374 1366
1375 if ( (info->flags & ASYNC_CTS_FLOW) && 1367 if ( (info->port.flags & ASYNC_CTS_FLOW) &&
1376 (status & MISCSTATUS_CTS_LATCHED) ) { 1368 (status & MISCSTATUS_CTS_LATCHED) ) {
1377 if (info->tty->hw_stopped) { 1369 if (info->port.tty->hw_stopped) {
1378 if (status & MISCSTATUS_CTS) { 1370 if (status & MISCSTATUS_CTS) {
1379 if ( debug_level >= DEBUG_LEVEL_ISR ) 1371 if ( debug_level >= DEBUG_LEVEL_ISR )
1380 printk("CTS tx start..."); 1372 printk("CTS tx start...");
1381 if (info->tty) 1373 if (info->port.tty)
1382 info->tty->hw_stopped = 0; 1374 info->port.tty->hw_stopped = 0;
1383 usc_start_transmitter(info); 1375 usc_start_transmitter(info);
1384 info->pending_bh |= BH_TRANSMIT; 1376 info->pending_bh |= BH_TRANSMIT;
1385 return; 1377 return;
@@ -1388,8 +1380,8 @@ static void mgsl_isr_io_pin( struct mgsl_struct *info )
1388 if (!(status & MISCSTATUS_CTS)) { 1380 if (!(status & MISCSTATUS_CTS)) {
1389 if ( debug_level >= DEBUG_LEVEL_ISR ) 1381 if ( debug_level >= DEBUG_LEVEL_ISR )
1390 printk("CTS tx stop..."); 1382 printk("CTS tx stop...");
1391 if (info->tty) 1383 if (info->port.tty)
1392 info->tty->hw_stopped = 1; 1384 info->port.tty->hw_stopped = 1;
1393 usc_stop_transmitter(info); 1385 usc_stop_transmitter(info);
1394 } 1386 }
1395 } 1387 }
@@ -1423,7 +1415,7 @@ static void mgsl_isr_transmit_data( struct mgsl_struct *info )
1423 1415
1424 usc_ClearIrqPendingBits( info, TRANSMIT_DATA ); 1416 usc_ClearIrqPendingBits( info, TRANSMIT_DATA );
1425 1417
1426 if (info->tty->stopped || info->tty->hw_stopped) { 1418 if (info->port.tty->stopped || info->port.tty->hw_stopped) {
1427 usc_stop_transmitter(info); 1419 usc_stop_transmitter(info);
1428 return; 1420 return;
1429 } 1421 }
@@ -1453,7 +1445,7 @@ static void mgsl_isr_receive_data( struct mgsl_struct *info )
1453 u16 status; 1445 u16 status;
1454 int work = 0; 1446 int work = 0;
1455 unsigned char DataByte; 1447 unsigned char DataByte;
1456 struct tty_struct *tty = info->tty; 1448 struct tty_struct *tty = info->port.tty;
1457 struct mgsl_icount *icount = &info->icount; 1449 struct mgsl_icount *icount = &info->icount;
1458 1450
1459 if ( debug_level >= DEBUG_LEVEL_ISR ) 1451 if ( debug_level >= DEBUG_LEVEL_ISR )
@@ -1514,7 +1506,7 @@ static void mgsl_isr_receive_data( struct mgsl_struct *info )
1514 1506
1515 if (status & RXSTATUS_BREAK_RECEIVED) { 1507 if (status & RXSTATUS_BREAK_RECEIVED) {
1516 flag = TTY_BREAK; 1508 flag = TTY_BREAK;
1517 if (info->flags & ASYNC_SAK) 1509 if (info->port.flags & ASYNC_SAK)
1518 do_SAK(tty); 1510 do_SAK(tty);
1519 } else if (status & RXSTATUS_PARITY_ERROR) 1511 } else if (status & RXSTATUS_PARITY_ERROR)
1520 flag = TTY_PARITY; 1512 flag = TTY_PARITY;
@@ -1771,7 +1763,7 @@ static int startup(struct mgsl_struct * info)
1771 if ( debug_level >= DEBUG_LEVEL_INFO ) 1763 if ( debug_level >= DEBUG_LEVEL_INFO )
1772 printk("%s(%d):mgsl_startup(%s)\n",__FILE__,__LINE__,info->device_name); 1764 printk("%s(%d):mgsl_startup(%s)\n",__FILE__,__LINE__,info->device_name);
1773 1765
1774 if (info->flags & ASYNC_INITIALIZED) 1766 if (info->port.flags & ASYNC_INITIALIZED)
1775 return 0; 1767 return 0;
1776 1768
1777 if (!info->xmit_buf) { 1769 if (!info->xmit_buf) {
@@ -1798,8 +1790,8 @@ static int startup(struct mgsl_struct * info)
1798 retval = mgsl_adapter_test(info); 1790 retval = mgsl_adapter_test(info);
1799 1791
1800 if ( retval ) { 1792 if ( retval ) {
1801 if (capable(CAP_SYS_ADMIN) && info->tty) 1793 if (capable(CAP_SYS_ADMIN) && info->port.tty)
1802 set_bit(TTY_IO_ERROR, &info->tty->flags); 1794 set_bit(TTY_IO_ERROR, &info->port.tty->flags);
1803 mgsl_release_resources(info); 1795 mgsl_release_resources(info);
1804 return retval; 1796 return retval;
1805 } 1797 }
@@ -1807,10 +1799,10 @@ static int startup(struct mgsl_struct * info)
1807 /* program hardware for current parameters */ 1799 /* program hardware for current parameters */
1808 mgsl_change_params(info); 1800 mgsl_change_params(info);
1809 1801
1810 if (info->tty) 1802 if (info->port.tty)
1811 clear_bit(TTY_IO_ERROR, &info->tty->flags); 1803 clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
1812 1804
1813 info->flags |= ASYNC_INITIALIZED; 1805 info->port.flags |= ASYNC_INITIALIZED;
1814 1806
1815 return 0; 1807 return 0;
1816 1808
@@ -1827,7 +1819,7 @@ static void shutdown(struct mgsl_struct * info)
1827{ 1819{
1828 unsigned long flags; 1820 unsigned long flags;
1829 1821
1830 if (!(info->flags & ASYNC_INITIALIZED)) 1822 if (!(info->port.flags & ASYNC_INITIALIZED))
1831 return; 1823 return;
1832 1824
1833 if (debug_level >= DEBUG_LEVEL_INFO) 1825 if (debug_level >= DEBUG_LEVEL_INFO)
@@ -1864,7 +1856,7 @@ static void shutdown(struct mgsl_struct * info)
1864 /* on the ISA adapter. This has no effect for the PCI adapter */ 1856 /* on the ISA adapter. This has no effect for the PCI adapter */
1865 usc_OutReg(info, PCR, (u16)((usc_InReg(info, PCR) | BIT13) | BIT12)); 1857 usc_OutReg(info, PCR, (u16)((usc_InReg(info, PCR) | BIT13) | BIT12));
1866 1858
1867 if (!info->tty || info->tty->termios->c_cflag & HUPCL) { 1859 if (!info->port.tty || info->port.tty->termios->c_cflag & HUPCL) {
1868 info->serial_signals &= ~(SerialSignal_DTR + SerialSignal_RTS); 1860 info->serial_signals &= ~(SerialSignal_DTR + SerialSignal_RTS);
1869 usc_set_serial_signals(info); 1861 usc_set_serial_signals(info);
1870 } 1862 }
@@ -1873,10 +1865,10 @@ static void shutdown(struct mgsl_struct * info)
1873 1865
1874 mgsl_release_resources(info); 1866 mgsl_release_resources(info);
1875 1867
1876 if (info->tty) 1868 if (info->port.tty)
1877 set_bit(TTY_IO_ERROR, &info->tty->flags); 1869 set_bit(TTY_IO_ERROR, &info->port.tty->flags);
1878 1870
1879 info->flags &= ~ASYNC_INITIALIZED; 1871 info->port.flags &= ~ASYNC_INITIALIZED;
1880 1872
1881} /* end of shutdown() */ 1873} /* end of shutdown() */
1882 1874
@@ -1908,7 +1900,7 @@ static void mgsl_program_hw(struct mgsl_struct *info)
1908 usc_EnableInterrupts(info, IO_PIN); 1900 usc_EnableInterrupts(info, IO_PIN);
1909 usc_get_serial_signals(info); 1901 usc_get_serial_signals(info);
1910 1902
1911 if (info->netcount || info->tty->termios->c_cflag & CREAD) 1903 if (info->netcount || info->port.tty->termios->c_cflag & CREAD)
1912 usc_start_receiver(info); 1904 usc_start_receiver(info);
1913 1905
1914 spin_unlock_irqrestore(&info->irq_spinlock,flags); 1906 spin_unlock_irqrestore(&info->irq_spinlock,flags);
@@ -1921,14 +1913,14 @@ static void mgsl_change_params(struct mgsl_struct *info)
1921 unsigned cflag; 1913 unsigned cflag;
1922 int bits_per_char; 1914 int bits_per_char;
1923 1915
1924 if (!info->tty || !info->tty->termios) 1916 if (!info->port.tty || !info->port.tty->termios)
1925 return; 1917 return;
1926 1918
1927 if (debug_level >= DEBUG_LEVEL_INFO) 1919 if (debug_level >= DEBUG_LEVEL_INFO)
1928 printk("%s(%d):mgsl_change_params(%s)\n", 1920 printk("%s(%d):mgsl_change_params(%s)\n",
1929 __FILE__,__LINE__, info->device_name ); 1921 __FILE__,__LINE__, info->device_name );
1930 1922
1931 cflag = info->tty->termios->c_cflag; 1923 cflag = info->port.tty->termios->c_cflag;
1932 1924
1933 /* if B0 rate (hangup) specified then negate DTR and RTS */ 1925 /* if B0 rate (hangup) specified then negate DTR and RTS */
1934 /* otherwise assert DTR and RTS */ 1926 /* otherwise assert DTR and RTS */
@@ -1976,7 +1968,7 @@ static void mgsl_change_params(struct mgsl_struct *info)
1976 * current data rate. 1968 * current data rate.
1977 */ 1969 */
1978 if (info->params.data_rate <= 460800) 1970 if (info->params.data_rate <= 460800)
1979 info->params.data_rate = tty_get_baud_rate(info->tty); 1971 info->params.data_rate = tty_get_baud_rate(info->port.tty);
1980 1972
1981 if ( info->params.data_rate ) { 1973 if ( info->params.data_rate ) {
1982 info->timeout = (32*HZ*bits_per_char) / 1974 info->timeout = (32*HZ*bits_per_char) /
@@ -1985,31 +1977,31 @@ static void mgsl_change_params(struct mgsl_struct *info)
1985 info->timeout += HZ/50; /* Add .02 seconds of slop */ 1977 info->timeout += HZ/50; /* Add .02 seconds of slop */
1986 1978
1987 if (cflag & CRTSCTS) 1979 if (cflag & CRTSCTS)
1988 info->flags |= ASYNC_CTS_FLOW; 1980 info->port.flags |= ASYNC_CTS_FLOW;
1989 else 1981 else
1990 info->flags &= ~ASYNC_CTS_FLOW; 1982 info->port.flags &= ~ASYNC_CTS_FLOW;
1991 1983
1992 if (cflag & CLOCAL) 1984 if (cflag & CLOCAL)
1993 info->flags &= ~ASYNC_CHECK_CD; 1985 info->port.flags &= ~ASYNC_CHECK_CD;
1994 else 1986 else
1995 info->flags |= ASYNC_CHECK_CD; 1987 info->port.flags |= ASYNC_CHECK_CD;
1996 1988
1997 /* process tty input control flags */ 1989 /* process tty input control flags */
1998 1990
1999 info->read_status_mask = RXSTATUS_OVERRUN; 1991 info->read_status_mask = RXSTATUS_OVERRUN;
2000 if (I_INPCK(info->tty)) 1992 if (I_INPCK(info->port.tty))
2001 info->read_status_mask |= RXSTATUS_PARITY_ERROR | RXSTATUS_FRAMING_ERROR; 1993 info->read_status_mask |= RXSTATUS_PARITY_ERROR | RXSTATUS_FRAMING_ERROR;
2002 if (I_BRKINT(info->tty) || I_PARMRK(info->tty)) 1994 if (I_BRKINT(info->port.tty) || I_PARMRK(info->port.tty))
2003 info->read_status_mask |= RXSTATUS_BREAK_RECEIVED; 1995 info->read_status_mask |= RXSTATUS_BREAK_RECEIVED;
2004 1996
2005 if (I_IGNPAR(info->tty)) 1997 if (I_IGNPAR(info->port.tty))
2006 info->ignore_status_mask |= RXSTATUS_PARITY_ERROR | RXSTATUS_FRAMING_ERROR; 1998 info->ignore_status_mask |= RXSTATUS_PARITY_ERROR | RXSTATUS_FRAMING_ERROR;
2007 if (I_IGNBRK(info->tty)) { 1999 if (I_IGNBRK(info->port.tty)) {
2008 info->ignore_status_mask |= RXSTATUS_BREAK_RECEIVED; 2000 info->ignore_status_mask |= RXSTATUS_BREAK_RECEIVED;
2009 /* If ignoring parity and break indicators, ignore 2001 /* If ignoring parity and break indicators, ignore
2010 * overruns too. (For real raw support). 2002 * overruns too. (For real raw support).
2011 */ 2003 */
2012 if (I_IGNPAR(info->tty)) 2004 if (I_IGNPAR(info->port.tty))
2013 info->ignore_status_mask |= RXSTATUS_OVERRUN; 2005 info->ignore_status_mask |= RXSTATUS_OVERRUN;
2014 } 2006 }
2015 2007
@@ -3113,32 +3105,32 @@ static void mgsl_close(struct tty_struct *tty, struct file * filp)
3113 3105
3114 if (debug_level >= DEBUG_LEVEL_INFO) 3106 if (debug_level >= DEBUG_LEVEL_INFO)
3115 printk("%s(%d):mgsl_close(%s) entry, count=%d\n", 3107 printk("%s(%d):mgsl_close(%s) entry, count=%d\n",
3116 __FILE__,__LINE__, info->device_name, info->count); 3108 __FILE__,__LINE__, info->device_name, info->port.count);
3117 3109
3118 if (!info->count) 3110 if (!info->port.count)
3119 return; 3111 return;
3120 3112
3121 if (tty_hung_up_p(filp)) 3113 if (tty_hung_up_p(filp))
3122 goto cleanup; 3114 goto cleanup;
3123 3115
3124 if ((tty->count == 1) && (info->count != 1)) { 3116 if ((tty->count == 1) && (info->port.count != 1)) {
3125 /* 3117 /*
3126 * tty->count is 1 and the tty structure will be freed. 3118 * tty->count is 1 and the tty structure will be freed.
3127 * info->count should be one in this case. 3119 * info->port.count should be one in this case.
3128 * if it's not, correct it so that the port is shutdown. 3120 * if it's not, correct it so that the port is shutdown.
3129 */ 3121 */
3130 printk("mgsl_close: bad refcount; tty->count is 1, " 3122 printk("mgsl_close: bad refcount; tty->count is 1, "
3131 "info->count is %d\n", info->count); 3123 "info->port.count is %d\n", info->port.count);
3132 info->count = 1; 3124 info->port.count = 1;
3133 } 3125 }
3134 3126
3135 info->count--; 3127 info->port.count--;
3136 3128
3137 /* if at least one open remaining, leave hardware active */ 3129 /* if at least one open remaining, leave hardware active */
3138 if (info->count) 3130 if (info->port.count)
3139 goto cleanup; 3131 goto cleanup;
3140 3132
3141 info->flags |= ASYNC_CLOSING; 3133 info->port.flags |= ASYNC_CLOSING;
3142 3134
3143 /* set tty->closing to notify line discipline to 3135 /* set tty->closing to notify line discipline to
3144 * only process XON/XOFF characters. Only the N_TTY 3136 * only process XON/XOFF characters. Only the N_TTY
@@ -3148,14 +3140,14 @@ static void mgsl_close(struct tty_struct *tty, struct file * filp)
3148 3140
3149 /* wait for transmit data to clear all layers */ 3141 /* wait for transmit data to clear all layers */
3150 3142
3151 if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE) { 3143 if (info->port.closing_wait != ASYNC_CLOSING_WAIT_NONE) {
3152 if (debug_level >= DEBUG_LEVEL_INFO) 3144 if (debug_level >= DEBUG_LEVEL_INFO)
3153 printk("%s(%d):mgsl_close(%s) calling tty_wait_until_sent\n", 3145 printk("%s(%d):mgsl_close(%s) calling tty_wait_until_sent\n",
3154 __FILE__,__LINE__, info->device_name ); 3146 __FILE__,__LINE__, info->device_name );
3155 tty_wait_until_sent(tty, info->closing_wait); 3147 tty_wait_until_sent(tty, info->port.closing_wait);
3156 } 3148 }
3157 3149
3158 if (info->flags & ASYNC_INITIALIZED) 3150 if (info->port.flags & ASYNC_INITIALIZED)
3159 mgsl_wait_until_sent(tty, info->timeout); 3151 mgsl_wait_until_sent(tty, info->timeout);
3160 3152
3161 mgsl_flush_buffer(tty); 3153 mgsl_flush_buffer(tty);
@@ -3165,23 +3157,23 @@ static void mgsl_close(struct tty_struct *tty, struct file * filp)
3165 shutdown(info); 3157 shutdown(info);
3166 3158
3167 tty->closing = 0; 3159 tty->closing = 0;
3168 info->tty = NULL; 3160 info->port.tty = NULL;
3169 3161
3170 if (info->blocked_open) { 3162 if (info->port.blocked_open) {
3171 if (info->close_delay) { 3163 if (info->port.close_delay) {
3172 msleep_interruptible(jiffies_to_msecs(info->close_delay)); 3164 msleep_interruptible(jiffies_to_msecs(info->port.close_delay));
3173 } 3165 }
3174 wake_up_interruptible(&info->open_wait); 3166 wake_up_interruptible(&info->port.open_wait);
3175 } 3167 }
3176 3168
3177 info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); 3169 info->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
3178 3170
3179 wake_up_interruptible(&info->close_wait); 3171 wake_up_interruptible(&info->port.close_wait);
3180 3172
3181cleanup: 3173cleanup:
3182 if (debug_level >= DEBUG_LEVEL_INFO) 3174 if (debug_level >= DEBUG_LEVEL_INFO)
3183 printk("%s(%d):mgsl_close(%s) exit, count=%d\n", __FILE__,__LINE__, 3175 printk("%s(%d):mgsl_close(%s) exit, count=%d\n", __FILE__,__LINE__,
3184 tty->driver->name, info->count); 3176 tty->driver->name, info->port.count);
3185 3177
3186} /* end of mgsl_close() */ 3178} /* end of mgsl_close() */
3187 3179
@@ -3211,7 +3203,7 @@ static void mgsl_wait_until_sent(struct tty_struct *tty, int timeout)
3211 if (mgsl_paranoia_check(info, tty->name, "mgsl_wait_until_sent")) 3203 if (mgsl_paranoia_check(info, tty->name, "mgsl_wait_until_sent"))
3212 return; 3204 return;
3213 3205
3214 if (!(info->flags & ASYNC_INITIALIZED)) 3206 if (!(info->port.flags & ASYNC_INITIALIZED))
3215 goto exit; 3207 goto exit;
3216 3208
3217 orig_jiffies = jiffies; 3209 orig_jiffies = jiffies;
@@ -3283,11 +3275,11 @@ static void mgsl_hangup(struct tty_struct *tty)
3283 mgsl_flush_buffer(tty); 3275 mgsl_flush_buffer(tty);
3284 shutdown(info); 3276 shutdown(info);
3285 3277
3286 info->count = 0; 3278 info->port.count = 0;
3287 info->flags &= ~ASYNC_NORMAL_ACTIVE; 3279 info->port.flags &= ~ASYNC_NORMAL_ACTIVE;
3288 info->tty = NULL; 3280 info->port.tty = NULL;
3289 3281
3290 wake_up_interruptible(&info->open_wait); 3282 wake_up_interruptible(&info->port.open_wait);
3291 3283
3292} /* end of mgsl_hangup() */ 3284} /* end of mgsl_hangup() */
3293 3285
@@ -3319,7 +3311,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
3319 3311
3320 if (filp->f_flags & O_NONBLOCK || tty->flags & (1 << TTY_IO_ERROR)){ 3312 if (filp->f_flags & O_NONBLOCK || tty->flags & (1 << TTY_IO_ERROR)){
3321 /* nonblock mode is set or port is not enabled */ 3313 /* nonblock mode is set or port is not enabled */
3322 info->flags |= ASYNC_NORMAL_ACTIVE; 3314 info->port.flags |= ASYNC_NORMAL_ACTIVE;
3323 return 0; 3315 return 0;
3324 } 3316 }
3325 3317
@@ -3328,25 +3320,25 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
3328 3320
3329 /* Wait for carrier detect and the line to become 3321 /* Wait for carrier detect and the line to become
3330 * free (i.e., not in use by the callout). While we are in 3322 * free (i.e., not in use by the callout). While we are in
3331 * this loop, info->count is dropped by one, so that 3323 * this loop, info->port.count is dropped by one, so that
3332 * mgsl_close() knows when to free things. We restore it upon 3324 * mgsl_close() knows when to free things. We restore it upon
3333 * exit, either normal or abnormal. 3325 * exit, either normal or abnormal.
3334 */ 3326 */
3335 3327
3336 retval = 0; 3328 retval = 0;
3337 add_wait_queue(&info->open_wait, &wait); 3329 add_wait_queue(&info->port.open_wait, &wait);
3338 3330
3339 if (debug_level >= DEBUG_LEVEL_INFO) 3331 if (debug_level >= DEBUG_LEVEL_INFO)
3340 printk("%s(%d):block_til_ready before block on %s count=%d\n", 3332 printk("%s(%d):block_til_ready before block on %s count=%d\n",
3341 __FILE__,__LINE__, tty->driver->name, info->count ); 3333 __FILE__,__LINE__, tty->driver->name, info->port.count );
3342 3334
3343 spin_lock_irqsave(&info->irq_spinlock, flags); 3335 spin_lock_irqsave(&info->irq_spinlock, flags);
3344 if (!tty_hung_up_p(filp)) { 3336 if (!tty_hung_up_p(filp)) {
3345 extra_count = true; 3337 extra_count = true;
3346 info->count--; 3338 info->port.count--;
3347 } 3339 }
3348 spin_unlock_irqrestore(&info->irq_spinlock, flags); 3340 spin_unlock_irqrestore(&info->irq_spinlock, flags);
3349 info->blocked_open++; 3341 info->port.blocked_open++;
3350 3342
3351 while (1) { 3343 while (1) {
3352 if (tty->termios->c_cflag & CBAUD) { 3344 if (tty->termios->c_cflag & CBAUD) {
@@ -3358,8 +3350,8 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
3358 3350
3359 set_current_state(TASK_INTERRUPTIBLE); 3351 set_current_state(TASK_INTERRUPTIBLE);
3360 3352
3361 if (tty_hung_up_p(filp) || !(info->flags & ASYNC_INITIALIZED)){ 3353 if (tty_hung_up_p(filp) || !(info->port.flags & ASYNC_INITIALIZED)){
3362 retval = (info->flags & ASYNC_HUP_NOTIFY) ? 3354 retval = (info->port.flags & ASYNC_HUP_NOTIFY) ?
3363 -EAGAIN : -ERESTARTSYS; 3355 -EAGAIN : -ERESTARTSYS;
3364 break; 3356 break;
3365 } 3357 }
@@ -3368,7 +3360,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
3368 usc_get_serial_signals(info); 3360 usc_get_serial_signals(info);
3369 spin_unlock_irqrestore(&info->irq_spinlock,flags); 3361 spin_unlock_irqrestore(&info->irq_spinlock,flags);
3370 3362
3371 if (!(info->flags & ASYNC_CLOSING) && 3363 if (!(info->port.flags & ASYNC_CLOSING) &&
3372 (do_clocal || (info->serial_signals & SerialSignal_DCD)) ) { 3364 (do_clocal || (info->serial_signals & SerialSignal_DCD)) ) {
3373 break; 3365 break;
3374 } 3366 }
@@ -3380,24 +3372,24 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
3380 3372
3381 if (debug_level >= DEBUG_LEVEL_INFO) 3373 if (debug_level >= DEBUG_LEVEL_INFO)
3382 printk("%s(%d):block_til_ready blocking on %s count=%d\n", 3374 printk("%s(%d):block_til_ready blocking on %s count=%d\n",
3383 __FILE__,__LINE__, tty->driver->name, info->count ); 3375 __FILE__,__LINE__, tty->driver->name, info->port.count );
3384 3376
3385 schedule(); 3377 schedule();
3386 } 3378 }
3387 3379
3388 set_current_state(TASK_RUNNING); 3380 set_current_state(TASK_RUNNING);
3389 remove_wait_queue(&info->open_wait, &wait); 3381 remove_wait_queue(&info->port.open_wait, &wait);
3390 3382
3391 if (extra_count) 3383 if (extra_count)
3392 info->count++; 3384 info->port.count++;
3393 info->blocked_open--; 3385 info->port.blocked_open--;
3394 3386
3395 if (debug_level >= DEBUG_LEVEL_INFO) 3387 if (debug_level >= DEBUG_LEVEL_INFO)
3396 printk("%s(%d):block_til_ready after blocking on %s count=%d\n", 3388 printk("%s(%d):block_til_ready after blocking on %s count=%d\n",
3397 __FILE__,__LINE__, tty->driver->name, info->count ); 3389 __FILE__,__LINE__, tty->driver->name, info->port.count );
3398 3390
3399 if (!retval) 3391 if (!retval)
3400 info->flags |= ASYNC_NORMAL_ACTIVE; 3392 info->port.flags |= ASYNC_NORMAL_ACTIVE;
3401 3393
3402 return retval; 3394 return retval;
3403 3395
@@ -3435,22 +3427,22 @@ static int mgsl_open(struct tty_struct *tty, struct file * filp)
3435 return -ENODEV; 3427 return -ENODEV;
3436 3428
3437 tty->driver_data = info; 3429 tty->driver_data = info;
3438 info->tty = tty; 3430 info->port.tty = tty;
3439 3431
3440 if (debug_level >= DEBUG_LEVEL_INFO) 3432 if (debug_level >= DEBUG_LEVEL_INFO)
3441 printk("%s(%d):mgsl_open(%s), old ref count = %d\n", 3433 printk("%s(%d):mgsl_open(%s), old ref count = %d\n",
3442 __FILE__,__LINE__,tty->driver->name, info->count); 3434 __FILE__,__LINE__,tty->driver->name, info->port.count);
3443 3435
3444 /* If port is closing, signal caller to try again */ 3436 /* If port is closing, signal caller to try again */
3445 if (tty_hung_up_p(filp) || info->flags & ASYNC_CLOSING){ 3437 if (tty_hung_up_p(filp) || info->port.flags & ASYNC_CLOSING){
3446 if (info->flags & ASYNC_CLOSING) 3438 if (info->port.flags & ASYNC_CLOSING)
3447 interruptible_sleep_on(&info->close_wait); 3439 interruptible_sleep_on(&info->port.close_wait);
3448 retval = ((info->flags & ASYNC_HUP_NOTIFY) ? 3440 retval = ((info->port.flags & ASYNC_HUP_NOTIFY) ?
3449 -EAGAIN : -ERESTARTSYS); 3441 -EAGAIN : -ERESTARTSYS);
3450 goto cleanup; 3442 goto cleanup;
3451 } 3443 }
3452 3444
3453 info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; 3445 info->port.tty->low_latency = (info->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0;
3454 3446
3455 spin_lock_irqsave(&info->netlock, flags); 3447 spin_lock_irqsave(&info->netlock, flags);
3456 if (info->netcount) { 3448 if (info->netcount) {
@@ -3458,10 +3450,10 @@ static int mgsl_open(struct tty_struct *tty, struct file * filp)
3458 spin_unlock_irqrestore(&info->netlock, flags); 3450 spin_unlock_irqrestore(&info->netlock, flags);
3459 goto cleanup; 3451 goto cleanup;
3460 } 3452 }
3461 info->count++; 3453 info->port.count++;
3462 spin_unlock_irqrestore(&info->netlock, flags); 3454 spin_unlock_irqrestore(&info->netlock, flags);
3463 3455
3464 if (info->count == 1) { 3456 if (info->port.count == 1) {
3465 /* 1st open on this device, init hardware */ 3457 /* 1st open on this device, init hardware */
3466 retval = startup(info); 3458 retval = startup(info);
3467 if (retval < 0) 3459 if (retval < 0)
@@ -3484,9 +3476,9 @@ static int mgsl_open(struct tty_struct *tty, struct file * filp)
3484cleanup: 3476cleanup:
3485 if (retval) { 3477 if (retval) {
3486 if (tty->count == 1) 3478 if (tty->count == 1)
3487 info->tty = NULL; /* tty layer will release tty struct */ 3479 info->port.tty = NULL; /* tty layer will release tty struct */
3488 if(info->count) 3480 if(info->port.count)
3489 info->count--; 3481 info->port.count--;
3490 } 3482 }
3491 3483
3492 return retval; 3484 return retval;
@@ -4332,13 +4324,12 @@ static struct mgsl_struct* mgsl_allocate_device(void)
4332 if (!info) { 4324 if (!info) {
4333 printk("Error can't allocate device instance data\n"); 4325 printk("Error can't allocate device instance data\n");
4334 } else { 4326 } else {
4327 tty_port_init(&info->port);
4335 info->magic = MGSL_MAGIC; 4328 info->magic = MGSL_MAGIC;
4336 INIT_WORK(&info->task, mgsl_bh_handler); 4329 INIT_WORK(&info->task, mgsl_bh_handler);
4337 info->max_frame_size = 4096; 4330 info->max_frame_size = 4096;
4338 info->close_delay = 5*HZ/10; 4331 info->port.close_delay = 5*HZ/10;
4339 info->closing_wait = 30*HZ; 4332 info->port.closing_wait = 30*HZ;
4340 init_waitqueue_head(&info->open_wait);
4341 init_waitqueue_head(&info->close_wait);
4342 init_waitqueue_head(&info->status_event_wait_q); 4333 init_waitqueue_head(&info->status_event_wait_q);
4343 init_waitqueue_head(&info->event_wait_q); 4334 init_waitqueue_head(&info->event_wait_q);
4344 spin_lock_init(&info->irq_spinlock); 4335 spin_lock_init(&info->irq_spinlock);
@@ -6575,7 +6566,7 @@ static bool mgsl_get_rx_frame(struct mgsl_struct *info)
6575 unsigned int framesize = 0; 6566 unsigned int framesize = 0;
6576 bool ReturnCode = false; 6567 bool ReturnCode = false;
6577 unsigned long flags; 6568 unsigned long flags;
6578 struct tty_struct *tty = info->tty; 6569 struct tty_struct *tty = info->port.tty;
6579 bool return_frame = false; 6570 bool return_frame = false;
6580 6571
6581 /* 6572 /*
@@ -6640,9 +6631,8 @@ static bool mgsl_get_rx_frame(struct mgsl_struct *info)
6640 framesize = 0; 6631 framesize = 0;
6641#if SYNCLINK_GENERIC_HDLC 6632#if SYNCLINK_GENERIC_HDLC
6642 { 6633 {
6643 struct net_device_stats *stats = hdlc_stats(info->netdev); 6634 info->netdev->stats.rx_errors++;
6644 stats->rx_errors++; 6635 info->netdev->stats.rx_frame_errors++;
6645 stats->rx_frame_errors++;
6646 } 6636 }
6647#endif 6637#endif
6648 } else 6638 } else
@@ -6774,7 +6764,7 @@ static bool mgsl_get_raw_rx_frame(struct mgsl_struct *info)
6774 unsigned int framesize = 0; 6764 unsigned int framesize = 0;
6775 bool ReturnCode = false; 6765 bool ReturnCode = false;
6776 unsigned long flags; 6766 unsigned long flags;
6777 struct tty_struct *tty = info->tty; 6767 struct tty_struct *tty = info->port.tty;
6778 6768
6779 /* 6769 /*
6780 * current_rx_buffer points to the 1st buffer of the next available 6770 * current_rx_buffer points to the 1st buffer of the next available
@@ -7711,7 +7701,7 @@ static int hdlcdev_attach(struct net_device *dev, unsigned short encoding,
7711 unsigned short new_crctype; 7701 unsigned short new_crctype;
7712 7702
7713 /* return error if TTY interface open */ 7703 /* return error if TTY interface open */
7714 if (info->count) 7704 if (info->port.count)
7715 return -EBUSY; 7705 return -EBUSY;
7716 7706
7717 switch (encoding) 7707 switch (encoding)
@@ -7753,7 +7743,6 @@ static int hdlcdev_attach(struct net_device *dev, unsigned short encoding,
7753static int hdlcdev_xmit(struct sk_buff *skb, struct net_device *dev) 7743static int hdlcdev_xmit(struct sk_buff *skb, struct net_device *dev)
7754{ 7744{
7755 struct mgsl_struct *info = dev_to_port(dev); 7745 struct mgsl_struct *info = dev_to_port(dev);
7756 struct net_device_stats *stats = hdlc_stats(dev);
7757 unsigned long flags; 7746 unsigned long flags;
7758 7747
7759 if (debug_level >= DEBUG_LEVEL_INFO) 7748 if (debug_level >= DEBUG_LEVEL_INFO)
@@ -7767,8 +7756,8 @@ static int hdlcdev_xmit(struct sk_buff *skb, struct net_device *dev)
7767 mgsl_load_tx_dma_buffer(info, skb->data, skb->len); 7756 mgsl_load_tx_dma_buffer(info, skb->data, skb->len);
7768 7757
7769 /* update network statistics */ 7758 /* update network statistics */
7770 stats->tx_packets++; 7759 dev->stats.tx_packets++;
7771 stats->tx_bytes += skb->len; 7760 dev->stats.tx_bytes += skb->len;
7772 7761
7773 /* done with socket buffer, so free it */ 7762 /* done with socket buffer, so free it */
7774 dev_kfree_skb(skb); 7763 dev_kfree_skb(skb);
@@ -7808,7 +7797,7 @@ static int hdlcdev_open(struct net_device *dev)
7808 7797
7809 /* arbitrate between network and tty opens */ 7798 /* arbitrate between network and tty opens */
7810 spin_lock_irqsave(&info->netlock, flags); 7799 spin_lock_irqsave(&info->netlock, flags);
7811 if (info->count != 0 || info->netcount != 0) { 7800 if (info->port.count != 0 || info->netcount != 0) {
7812 printk(KERN_WARNING "%s: hdlc_open returning busy\n", dev->name); 7801 printk(KERN_WARNING "%s: hdlc_open returning busy\n", dev->name);
7813 spin_unlock_irqrestore(&info->netlock, flags); 7802 spin_unlock_irqrestore(&info->netlock, flags);
7814 return -EBUSY; 7803 return -EBUSY;
@@ -7894,7 +7883,7 @@ static int hdlcdev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
7894 printk("%s:hdlcdev_ioctl(%s)\n",__FILE__,dev->name); 7883 printk("%s:hdlcdev_ioctl(%s)\n",__FILE__,dev->name);
7895 7884
7896 /* return error if TTY interface open */ 7885 /* return error if TTY interface open */
7897 if (info->count) 7886 if (info->port.count)
7898 return -EBUSY; 7887 return -EBUSY;
7899 7888
7900 if (cmd != SIOCWANDEV) 7889 if (cmd != SIOCWANDEV)
@@ -7984,14 +7973,13 @@ static int hdlcdev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
7984static void hdlcdev_tx_timeout(struct net_device *dev) 7973static void hdlcdev_tx_timeout(struct net_device *dev)
7985{ 7974{
7986 struct mgsl_struct *info = dev_to_port(dev); 7975 struct mgsl_struct *info = dev_to_port(dev);
7987 struct net_device_stats *stats = hdlc_stats(dev);
7988 unsigned long flags; 7976 unsigned long flags;
7989 7977
7990 if (debug_level >= DEBUG_LEVEL_INFO) 7978 if (debug_level >= DEBUG_LEVEL_INFO)
7991 printk("hdlcdev_tx_timeout(%s)\n",dev->name); 7979 printk("hdlcdev_tx_timeout(%s)\n",dev->name);
7992 7980
7993 stats->tx_errors++; 7981 dev->stats.tx_errors++;
7994 stats->tx_aborted_errors++; 7982 dev->stats.tx_aborted_errors++;
7995 7983
7996 spin_lock_irqsave(&info->irq_spinlock,flags); 7984 spin_lock_irqsave(&info->irq_spinlock,flags);
7997 usc_stop_transmitter(info); 7985 usc_stop_transmitter(info);
@@ -8024,27 +8012,27 @@ static void hdlcdev_rx(struct mgsl_struct *info, char *buf, int size)
8024{ 8012{
8025 struct sk_buff *skb = dev_alloc_skb(size); 8013 struct sk_buff *skb = dev_alloc_skb(size);
8026 struct net_device *dev = info->netdev; 8014 struct net_device *dev = info->netdev;
8027 struct net_device_stats *stats = hdlc_stats(dev);
8028 8015
8029 if (debug_level >= DEBUG_LEVEL_INFO) 8016 if (debug_level >= DEBUG_LEVEL_INFO)
8030 printk("hdlcdev_rx(%s)\n",dev->name); 8017 printk("hdlcdev_rx(%s)\n", dev->name);
8031 8018
8032 if (skb == NULL) { 8019 if (skb == NULL) {
8033 printk(KERN_NOTICE "%s: can't alloc skb, dropping packet\n", dev->name); 8020 printk(KERN_NOTICE "%s: can't alloc skb, dropping packet\n",
8034 stats->rx_dropped++; 8021 dev->name);
8022 dev->stats.rx_dropped++;
8035 return; 8023 return;
8036 } 8024 }
8037 8025
8038 memcpy(skb_put(skb, size),buf,size); 8026 memcpy(skb_put(skb, size), buf, size);
8039 8027
8040 skb->protocol = hdlc_type_trans(skb, info->netdev); 8028 skb->protocol = hdlc_type_trans(skb, dev);
8041 8029
8042 stats->rx_packets++; 8030 dev->stats.rx_packets++;
8043 stats->rx_bytes += size; 8031 dev->stats.rx_bytes += size;
8044 8032
8045 netif_rx(skb); 8033 netif_rx(skb);
8046 8034
8047 info->netdev->last_rx = jiffies; 8035 dev->last_rx = jiffies;
8048} 8036}
8049 8037
8050/** 8038/**
diff --git a/drivers/char/synclink_gt.c b/drivers/char/synclink_gt.c
index 55c1653be00c..2c3e43bb2cc9 100644
--- a/drivers/char/synclink_gt.c
+++ b/drivers/char/synclink_gt.c
@@ -244,11 +244,11 @@ struct _input_signal_events {
244 */ 244 */
245struct slgt_info { 245struct slgt_info {
246 void *if_ptr; /* General purpose pointer (used by SPPP) */ 246 void *if_ptr; /* General purpose pointer (used by SPPP) */
247 struct tty_port port;
247 248
248 struct slgt_info *next_device; /* device list link */ 249 struct slgt_info *next_device; /* device list link */
249 250
250 int magic; 251 int magic;
251 int flags;
252 252
253 char device_name[25]; 253 char device_name[25];
254 struct pci_dev *pdev; 254 struct pci_dev *pdev;
@@ -260,23 +260,15 @@ struct slgt_info {
260 /* array of pointers to port contexts on this adapter */ 260 /* array of pointers to port contexts on this adapter */
261 struct slgt_info *port_array[SLGT_MAX_PORTS]; 261 struct slgt_info *port_array[SLGT_MAX_PORTS];
262 262
263 int count; /* count of opens */
264 int line; /* tty line instance number */ 263 int line; /* tty line instance number */
265 unsigned short close_delay;
266 unsigned short closing_wait; /* time to wait before closing */
267 264
268 struct mgsl_icount icount; 265 struct mgsl_icount icount;
269 266
270 struct tty_struct *tty;
271 int timeout; 267 int timeout;
272 int x_char; /* xon/xoff character */ 268 int x_char; /* xon/xoff character */
273 int blocked_open; /* # of blocked opens */
274 unsigned int read_status_mask; 269 unsigned int read_status_mask;
275 unsigned int ignore_status_mask; 270 unsigned int ignore_status_mask;
276 271
277 wait_queue_head_t open_wait;
278 wait_queue_head_t close_wait;
279
280 wait_queue_head_t status_event_wait_q; 272 wait_queue_head_t status_event_wait_q;
281 wait_queue_head_t event_wait_q; 273 wait_queue_head_t event_wait_q;
282 struct timer_list tx_timer; 274 struct timer_list tx_timer;
@@ -641,8 +633,8 @@ static void ldisc_receive_buf(struct tty_struct *tty,
641 return; 633 return;
642 ld = tty_ldisc_ref(tty); 634 ld = tty_ldisc_ref(tty);
643 if (ld) { 635 if (ld) {
644 if (ld->receive_buf) 636 if (ld->ops->receive_buf)
645 ld->receive_buf(tty, data, flags, count); 637 ld->ops->receive_buf(tty, data, flags, count);
646 tty_ldisc_deref(ld); 638 tty_ldisc_deref(ld);
647 } 639 }
648} 640}
@@ -672,20 +664,20 @@ static int open(struct tty_struct *tty, struct file *filp)
672 } 664 }
673 665
674 tty->driver_data = info; 666 tty->driver_data = info;
675 info->tty = tty; 667 info->port.tty = tty;
676 668
677 DBGINFO(("%s open, old ref count = %d\n", info->device_name, info->count)); 669 DBGINFO(("%s open, old ref count = %d\n", info->device_name, info->port.count));
678 670
679 /* If port is closing, signal caller to try again */ 671 /* If port is closing, signal caller to try again */
680 if (tty_hung_up_p(filp) || info->flags & ASYNC_CLOSING){ 672 if (tty_hung_up_p(filp) || info->port.flags & ASYNC_CLOSING){
681 if (info->flags & ASYNC_CLOSING) 673 if (info->port.flags & ASYNC_CLOSING)
682 interruptible_sleep_on(&info->close_wait); 674 interruptible_sleep_on(&info->port.close_wait);
683 retval = ((info->flags & ASYNC_HUP_NOTIFY) ? 675 retval = ((info->port.flags & ASYNC_HUP_NOTIFY) ?
684 -EAGAIN : -ERESTARTSYS); 676 -EAGAIN : -ERESTARTSYS);
685 goto cleanup; 677 goto cleanup;
686 } 678 }
687 679
688 info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; 680 info->port.tty->low_latency = (info->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0;
689 681
690 spin_lock_irqsave(&info->netlock, flags); 682 spin_lock_irqsave(&info->netlock, flags);
691 if (info->netcount) { 683 if (info->netcount) {
@@ -693,10 +685,10 @@ static int open(struct tty_struct *tty, struct file *filp)
693 spin_unlock_irqrestore(&info->netlock, flags); 685 spin_unlock_irqrestore(&info->netlock, flags);
694 goto cleanup; 686 goto cleanup;
695 } 687 }
696 info->count++; 688 info->port.count++;
697 spin_unlock_irqrestore(&info->netlock, flags); 689 spin_unlock_irqrestore(&info->netlock, flags);
698 690
699 if (info->count == 1) { 691 if (info->port.count == 1) {
700 /* 1st open on this device, init hardware */ 692 /* 1st open on this device, init hardware */
701 retval = startup(info); 693 retval = startup(info);
702 if (retval < 0) 694 if (retval < 0)
@@ -714,9 +706,9 @@ static int open(struct tty_struct *tty, struct file *filp)
714cleanup: 706cleanup:
715 if (retval) { 707 if (retval) {
716 if (tty->count == 1) 708 if (tty->count == 1)
717 info->tty = NULL; /* tty layer will release tty struct */ 709 info->port.tty = NULL; /* tty layer will release tty struct */
718 if(info->count) 710 if(info->port.count)
719 info->count--; 711 info->port.count--;
720 } 712 }
721 713
722 DBGINFO(("%s open rc=%d\n", info->device_name, retval)); 714 DBGINFO(("%s open rc=%d\n", info->device_name, retval));
@@ -729,32 +721,32 @@ static void close(struct tty_struct *tty, struct file *filp)
729 721
730 if (sanity_check(info, tty->name, "close")) 722 if (sanity_check(info, tty->name, "close"))
731 return; 723 return;
732 DBGINFO(("%s close entry, count=%d\n", info->device_name, info->count)); 724 DBGINFO(("%s close entry, count=%d\n", info->device_name, info->port.count));
733 725
734 if (!info->count) 726 if (!info->port.count)
735 return; 727 return;
736 728
737 if (tty_hung_up_p(filp)) 729 if (tty_hung_up_p(filp))
738 goto cleanup; 730 goto cleanup;
739 731
740 if ((tty->count == 1) && (info->count != 1)) { 732 if ((tty->count == 1) && (info->port.count != 1)) {
741 /* 733 /*
742 * tty->count is 1 and the tty structure will be freed. 734 * tty->count is 1 and the tty structure will be freed.
743 * info->count should be one in this case. 735 * info->port.count should be one in this case.
744 * if it's not, correct it so that the port is shutdown. 736 * if it's not, correct it so that the port is shutdown.
745 */ 737 */
746 DBGERR(("%s close: bad refcount; tty->count=1, " 738 DBGERR(("%s close: bad refcount; tty->count=1, "
747 "info->count=%d\n", info->device_name, info->count)); 739 "info->port.count=%d\n", info->device_name, info->port.count));
748 info->count = 1; 740 info->port.count = 1;
749 } 741 }
750 742
751 info->count--; 743 info->port.count--;
752 744
753 /* if at least one open remaining, leave hardware active */ 745 /* if at least one open remaining, leave hardware active */
754 if (info->count) 746 if (info->port.count)
755 goto cleanup; 747 goto cleanup;
756 748
757 info->flags |= ASYNC_CLOSING; 749 info->port.flags |= ASYNC_CLOSING;
758 750
759 /* set tty->closing to notify line discipline to 751 /* set tty->closing to notify line discipline to
760 * only process XON/XOFF characters. Only the N_TTY 752 * only process XON/XOFF characters. Only the N_TTY
@@ -764,12 +756,12 @@ static void close(struct tty_struct *tty, struct file *filp)
764 756
765 /* wait for transmit data to clear all layers */ 757 /* wait for transmit data to clear all layers */
766 758
767 if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE) { 759 if (info->port.closing_wait != ASYNC_CLOSING_WAIT_NONE) {
768 DBGINFO(("%s call tty_wait_until_sent\n", info->device_name)); 760 DBGINFO(("%s call tty_wait_until_sent\n", info->device_name));
769 tty_wait_until_sent(tty, info->closing_wait); 761 tty_wait_until_sent(tty, info->port.closing_wait);
770 } 762 }
771 763
772 if (info->flags & ASYNC_INITIALIZED) 764 if (info->port.flags & ASYNC_INITIALIZED)
773 wait_until_sent(tty, info->timeout); 765 wait_until_sent(tty, info->timeout);
774 flush_buffer(tty); 766 flush_buffer(tty);
775 tty_ldisc_flush(tty); 767 tty_ldisc_flush(tty);
@@ -777,21 +769,21 @@ static void close(struct tty_struct *tty, struct file *filp)
777 shutdown(info); 769 shutdown(info);
778 770
779 tty->closing = 0; 771 tty->closing = 0;
780 info->tty = NULL; 772 info->port.tty = NULL;
781 773
782 if (info->blocked_open) { 774 if (info->port.blocked_open) {
783 if (info->close_delay) { 775 if (info->port.close_delay) {
784 msleep_interruptible(jiffies_to_msecs(info->close_delay)); 776 msleep_interruptible(jiffies_to_msecs(info->port.close_delay));
785 } 777 }
786 wake_up_interruptible(&info->open_wait); 778 wake_up_interruptible(&info->port.open_wait);
787 } 779 }
788 780
789 info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); 781 info->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
790 782
791 wake_up_interruptible(&info->close_wait); 783 wake_up_interruptible(&info->port.close_wait);
792 784
793cleanup: 785cleanup:
794 DBGINFO(("%s close exit, count=%d\n", tty->driver->name, info->count)); 786 DBGINFO(("%s close exit, count=%d\n", tty->driver->name, info->port.count));
795} 787}
796 788
797static void hangup(struct tty_struct *tty) 789static void hangup(struct tty_struct *tty)
@@ -805,11 +797,11 @@ static void hangup(struct tty_struct *tty)
805 flush_buffer(tty); 797 flush_buffer(tty);
806 shutdown(info); 798 shutdown(info);
807 799
808 info->count = 0; 800 info->port.count = 0;
809 info->flags &= ~ASYNC_NORMAL_ACTIVE; 801 info->port.flags &= ~ASYNC_NORMAL_ACTIVE;
810 info->tty = NULL; 802 info->port.tty = NULL;
811 803
812 wake_up_interruptible(&info->open_wait); 804 wake_up_interruptible(&info->port.open_wait);
813} 805}
814 806
815static void set_termios(struct tty_struct *tty, struct ktermios *old_termios) 807static void set_termios(struct tty_struct *tty, struct ktermios *old_termios)
@@ -959,7 +951,7 @@ static void wait_until_sent(struct tty_struct *tty, int timeout)
959 if (sanity_check(info, tty->name, "wait_until_sent")) 951 if (sanity_check(info, tty->name, "wait_until_sent"))
960 return; 952 return;
961 DBGINFO(("%s wait_until_sent entry\n", info->device_name)); 953 DBGINFO(("%s wait_until_sent entry\n", info->device_name));
962 if (!(info->flags & ASYNC_INITIALIZED)) 954 if (!(info->port.flags & ASYNC_INITIALIZED))
963 goto exit; 955 goto exit;
964 956
965 orig_jiffies = jiffies; 957 orig_jiffies = jiffies;
@@ -1500,7 +1492,7 @@ static int hdlcdev_attach(struct net_device *dev, unsigned short encoding,
1500 unsigned short new_crctype; 1492 unsigned short new_crctype;
1501 1493
1502 /* return error if TTY interface open */ 1494 /* return error if TTY interface open */
1503 if (info->count) 1495 if (info->port.count)
1504 return -EBUSY; 1496 return -EBUSY;
1505 1497
1506 DBGINFO(("%s hdlcdev_attach\n", info->device_name)); 1498 DBGINFO(("%s hdlcdev_attach\n", info->device_name));
@@ -1544,7 +1536,6 @@ static int hdlcdev_attach(struct net_device *dev, unsigned short encoding,
1544static int hdlcdev_xmit(struct sk_buff *skb, struct net_device *dev) 1536static int hdlcdev_xmit(struct sk_buff *skb, struct net_device *dev)
1545{ 1537{
1546 struct slgt_info *info = dev_to_port(dev); 1538 struct slgt_info *info = dev_to_port(dev);
1547 struct net_device_stats *stats = hdlc_stats(dev);
1548 unsigned long flags; 1539 unsigned long flags;
1549 1540
1550 DBGINFO(("%s hdlc_xmit\n", dev->name)); 1541 DBGINFO(("%s hdlc_xmit\n", dev->name));
@@ -1557,8 +1548,8 @@ static int hdlcdev_xmit(struct sk_buff *skb, struct net_device *dev)
1557 tx_load(info, skb->data, skb->len); 1548 tx_load(info, skb->data, skb->len);
1558 1549
1559 /* update network statistics */ 1550 /* update network statistics */
1560 stats->tx_packets++; 1551 dev->stats.tx_packets++;
1561 stats->tx_bytes += skb->len; 1552 dev->stats.tx_bytes += skb->len;
1562 1553
1563 /* done with socket buffer, so free it */ 1554 /* done with socket buffer, so free it */
1564 dev_kfree_skb(skb); 1555 dev_kfree_skb(skb);
@@ -1600,7 +1591,7 @@ static int hdlcdev_open(struct net_device *dev)
1600 1591
1601 /* arbitrate between network and tty opens */ 1592 /* arbitrate between network and tty opens */
1602 spin_lock_irqsave(&info->netlock, flags); 1593 spin_lock_irqsave(&info->netlock, flags);
1603 if (info->count != 0 || info->netcount != 0) { 1594 if (info->port.count != 0 || info->netcount != 0) {
1604 DBGINFO(("%s hdlc_open busy\n", dev->name)); 1595 DBGINFO(("%s hdlc_open busy\n", dev->name));
1605 spin_unlock_irqrestore(&info->netlock, flags); 1596 spin_unlock_irqrestore(&info->netlock, flags);
1606 return -EBUSY; 1597 return -EBUSY;
@@ -1685,7 +1676,7 @@ static int hdlcdev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1685 DBGINFO(("%s hdlcdev_ioctl\n", dev->name)); 1676 DBGINFO(("%s hdlcdev_ioctl\n", dev->name));
1686 1677
1687 /* return error if TTY interface open */ 1678 /* return error if TTY interface open */
1688 if (info->count) 1679 if (info->port.count)
1689 return -EBUSY; 1680 return -EBUSY;
1690 1681
1691 if (cmd != SIOCWANDEV) 1682 if (cmd != SIOCWANDEV)
@@ -1775,13 +1766,12 @@ static int hdlcdev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1775static void hdlcdev_tx_timeout(struct net_device *dev) 1766static void hdlcdev_tx_timeout(struct net_device *dev)
1776{ 1767{
1777 struct slgt_info *info = dev_to_port(dev); 1768 struct slgt_info *info = dev_to_port(dev);
1778 struct net_device_stats *stats = hdlc_stats(dev);
1779 unsigned long flags; 1769 unsigned long flags;
1780 1770
1781 DBGINFO(("%s hdlcdev_tx_timeout\n", dev->name)); 1771 DBGINFO(("%s hdlcdev_tx_timeout\n", dev->name));
1782 1772
1783 stats->tx_errors++; 1773 dev->stats.tx_errors++;
1784 stats->tx_aborted_errors++; 1774 dev->stats.tx_aborted_errors++;
1785 1775
1786 spin_lock_irqsave(&info->lock,flags); 1776 spin_lock_irqsave(&info->lock,flags);
1787 tx_stop(info); 1777 tx_stop(info);
@@ -1814,26 +1804,25 @@ static void hdlcdev_rx(struct slgt_info *info, char *buf, int size)
1814{ 1804{
1815 struct sk_buff *skb = dev_alloc_skb(size); 1805 struct sk_buff *skb = dev_alloc_skb(size);
1816 struct net_device *dev = info->netdev; 1806 struct net_device *dev = info->netdev;
1817 struct net_device_stats *stats = hdlc_stats(dev);
1818 1807
1819 DBGINFO(("%s hdlcdev_rx\n", dev->name)); 1808 DBGINFO(("%s hdlcdev_rx\n", dev->name));
1820 1809
1821 if (skb == NULL) { 1810 if (skb == NULL) {
1822 DBGERR(("%s: can't alloc skb, drop packet\n", dev->name)); 1811 DBGERR(("%s: can't alloc skb, drop packet\n", dev->name));
1823 stats->rx_dropped++; 1812 dev->stats.rx_dropped++;
1824 return; 1813 return;
1825 } 1814 }
1826 1815
1827 memcpy(skb_put(skb, size),buf,size); 1816 memcpy(skb_put(skb, size), buf, size);
1828 1817
1829 skb->protocol = hdlc_type_trans(skb, info->netdev); 1818 skb->protocol = hdlc_type_trans(skb, dev);
1830 1819
1831 stats->rx_packets++; 1820 dev->stats.rx_packets++;
1832 stats->rx_bytes += size; 1821 dev->stats.rx_bytes += size;
1833 1822
1834 netif_rx(skb); 1823 netif_rx(skb);
1835 1824
1836 info->netdev->last_rx = jiffies; 1825 dev->last_rx = jiffies;
1837} 1826}
1838 1827
1839/** 1828/**
@@ -1906,7 +1895,7 @@ static void hdlcdev_exit(struct slgt_info *info)
1906 */ 1895 */
1907static void rx_async(struct slgt_info *info) 1896static void rx_async(struct slgt_info *info)
1908{ 1897{
1909 struct tty_struct *tty = info->tty; 1898 struct tty_struct *tty = info->port.tty;
1910 struct mgsl_icount *icount = &info->icount; 1899 struct mgsl_icount *icount = &info->icount;
1911 unsigned int start, end; 1900 unsigned int start, end;
1912 unsigned char *p; 1901 unsigned char *p;
@@ -2057,7 +2046,7 @@ static void bh_handler(struct work_struct *work)
2057 2046
2058static void bh_transmit(struct slgt_info *info) 2047static void bh_transmit(struct slgt_info *info)
2059{ 2048{
2060 struct tty_struct *tty = info->tty; 2049 struct tty_struct *tty = info->port.tty;
2061 2050
2062 DBGBH(("%s bh_transmit\n", info->device_name)); 2051 DBGBH(("%s bh_transmit\n", info->device_name));
2063 if (tty) 2052 if (tty)
@@ -2103,17 +2092,17 @@ static void cts_change(struct slgt_info *info, unsigned short status)
2103 wake_up_interruptible(&info->event_wait_q); 2092 wake_up_interruptible(&info->event_wait_q);
2104 info->pending_bh |= BH_STATUS; 2093 info->pending_bh |= BH_STATUS;
2105 2094
2106 if (info->flags & ASYNC_CTS_FLOW) { 2095 if (info->port.flags & ASYNC_CTS_FLOW) {
2107 if (info->tty) { 2096 if (info->port.tty) {
2108 if (info->tty->hw_stopped) { 2097 if (info->port.tty->hw_stopped) {
2109 if (info->signals & SerialSignal_CTS) { 2098 if (info->signals & SerialSignal_CTS) {
2110 info->tty->hw_stopped = 0; 2099 info->port.tty->hw_stopped = 0;
2111 info->pending_bh |= BH_TRANSMIT; 2100 info->pending_bh |= BH_TRANSMIT;
2112 return; 2101 return;
2113 } 2102 }
2114 } else { 2103 } else {
2115 if (!(info->signals & SerialSignal_CTS)) 2104 if (!(info->signals & SerialSignal_CTS))
2116 info->tty->hw_stopped = 1; 2105 info->port.tty->hw_stopped = 1;
2117 } 2106 }
2118 } 2107 }
2119 } 2108 }
@@ -2146,12 +2135,12 @@ static void dcd_change(struct slgt_info *info, unsigned short status)
2146 wake_up_interruptible(&info->event_wait_q); 2135 wake_up_interruptible(&info->event_wait_q);
2147 info->pending_bh |= BH_STATUS; 2136 info->pending_bh |= BH_STATUS;
2148 2137
2149 if (info->flags & ASYNC_CHECK_CD) { 2138 if (info->port.flags & ASYNC_CHECK_CD) {
2150 if (info->signals & SerialSignal_DCD) 2139 if (info->signals & SerialSignal_DCD)
2151 wake_up_interruptible(&info->open_wait); 2140 wake_up_interruptible(&info->port.open_wait);
2152 else { 2141 else {
2153 if (info->tty) 2142 if (info->port.tty)
2154 tty_hangup(info->tty); 2143 tty_hangup(info->port.tty);
2155 } 2144 }
2156 } 2145 }
2157} 2146}
@@ -2194,12 +2183,12 @@ static void isr_serial(struct slgt_info *info)
2194 if ((status & IRQ_RXBREAK) && (status & RXBREAK)) { 2183 if ((status & IRQ_RXBREAK) && (status & RXBREAK)) {
2195 info->icount.brk++; 2184 info->icount.brk++;
2196 /* process break detection if tty control allows */ 2185 /* process break detection if tty control allows */
2197 if (info->tty) { 2186 if (info->port.tty) {
2198 if (!(status & info->ignore_status_mask)) { 2187 if (!(status & info->ignore_status_mask)) {
2199 if (info->read_status_mask & MASK_BREAK) { 2188 if (info->read_status_mask & MASK_BREAK) {
2200 tty_insert_flip_char(info->tty, 0, TTY_BREAK); 2189 tty_insert_flip_char(info->port.tty, 0, TTY_BREAK);
2201 if (info->flags & ASYNC_SAK) 2190 if (info->port.flags & ASYNC_SAK)
2202 do_SAK(info->tty); 2191 do_SAK(info->port.tty);
2203 } 2192 }
2204 } 2193 }
2205 } 2194 }
@@ -2319,7 +2308,7 @@ static void isr_txeom(struct slgt_info *info, unsigned short status)
2319 else 2308 else
2320#endif 2309#endif
2321 { 2310 {
2322 if (info->tty && (info->tty->stopped || info->tty->hw_stopped)) { 2311 if (info->port.tty && (info->port.tty->stopped || info->port.tty->hw_stopped)) {
2323 tx_stop(info); 2312 tx_stop(info);
2324 return; 2313 return;
2325 } 2314 }
@@ -2395,7 +2384,7 @@ static irqreturn_t slgt_interrupt(int dummy, void *dev_id)
2395 for(i=0; i < info->port_count ; i++) { 2384 for(i=0; i < info->port_count ; i++) {
2396 struct slgt_info *port = info->port_array[i]; 2385 struct slgt_info *port = info->port_array[i];
2397 2386
2398 if (port && (port->count || port->netcount) && 2387 if (port && (port->port.count || port->netcount) &&
2399 port->pending_bh && !port->bh_running && 2388 port->pending_bh && !port->bh_running &&
2400 !port->bh_requested) { 2389 !port->bh_requested) {
2401 DBGISR(("%s bh queued\n", port->device_name)); 2390 DBGISR(("%s bh queued\n", port->device_name));
@@ -2414,7 +2403,7 @@ static int startup(struct slgt_info *info)
2414{ 2403{
2415 DBGINFO(("%s startup\n", info->device_name)); 2404 DBGINFO(("%s startup\n", info->device_name));
2416 2405
2417 if (info->flags & ASYNC_INITIALIZED) 2406 if (info->port.flags & ASYNC_INITIALIZED)
2418 return 0; 2407 return 0;
2419 2408
2420 if (!info->tx_buf) { 2409 if (!info->tx_buf) {
@@ -2432,10 +2421,10 @@ static int startup(struct slgt_info *info)
2432 /* program hardware for current parameters */ 2421 /* program hardware for current parameters */
2433 change_params(info); 2422 change_params(info);
2434 2423
2435 if (info->tty) 2424 if (info->port.tty)
2436 clear_bit(TTY_IO_ERROR, &info->tty->flags); 2425 clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
2437 2426
2438 info->flags |= ASYNC_INITIALIZED; 2427 info->port.flags |= ASYNC_INITIALIZED;
2439 2428
2440 return 0; 2429 return 0;
2441} 2430}
@@ -2447,7 +2436,7 @@ static void shutdown(struct slgt_info *info)
2447{ 2436{
2448 unsigned long flags; 2437 unsigned long flags;
2449 2438
2450 if (!(info->flags & ASYNC_INITIALIZED)) 2439 if (!(info->port.flags & ASYNC_INITIALIZED))
2451 return; 2440 return;
2452 2441
2453 DBGINFO(("%s shutdown\n", info->device_name)); 2442 DBGINFO(("%s shutdown\n", info->device_name));
@@ -2470,7 +2459,7 @@ static void shutdown(struct slgt_info *info)
2470 2459
2471 slgt_irq_off(info, IRQ_ALL | IRQ_MASTER); 2460 slgt_irq_off(info, IRQ_ALL | IRQ_MASTER);
2472 2461
2473 if (!info->tty || info->tty->termios->c_cflag & HUPCL) { 2462 if (!info->port.tty || info->port.tty->termios->c_cflag & HUPCL) {
2474 info->signals &= ~(SerialSignal_DTR + SerialSignal_RTS); 2463 info->signals &= ~(SerialSignal_DTR + SerialSignal_RTS);
2475 set_signals(info); 2464 set_signals(info);
2476 } 2465 }
@@ -2479,10 +2468,10 @@ static void shutdown(struct slgt_info *info)
2479 2468
2480 spin_unlock_irqrestore(&info->lock,flags); 2469 spin_unlock_irqrestore(&info->lock,flags);
2481 2470
2482 if (info->tty) 2471 if (info->port.tty)
2483 set_bit(TTY_IO_ERROR, &info->tty->flags); 2472 set_bit(TTY_IO_ERROR, &info->port.tty->flags);
2484 2473
2485 info->flags &= ~ASYNC_INITIALIZED; 2474 info->port.flags &= ~ASYNC_INITIALIZED;
2486} 2475}
2487 2476
2488static void program_hw(struct slgt_info *info) 2477static void program_hw(struct slgt_info *info)
@@ -2511,7 +2500,7 @@ static void program_hw(struct slgt_info *info)
2511 get_signals(info); 2500 get_signals(info);
2512 2501
2513 if (info->netcount || 2502 if (info->netcount ||
2514 (info->tty && info->tty->termios->c_cflag & CREAD)) 2503 (info->port.tty && info->port.tty->termios->c_cflag & CREAD))
2515 rx_start(info); 2504 rx_start(info);
2516 2505
2517 spin_unlock_irqrestore(&info->lock,flags); 2506 spin_unlock_irqrestore(&info->lock,flags);
@@ -2525,11 +2514,11 @@ static void change_params(struct slgt_info *info)
2525 unsigned cflag; 2514 unsigned cflag;
2526 int bits_per_char; 2515 int bits_per_char;
2527 2516
2528 if (!info->tty || !info->tty->termios) 2517 if (!info->port.tty || !info->port.tty->termios)
2529 return; 2518 return;
2530 DBGINFO(("%s change_params\n", info->device_name)); 2519 DBGINFO(("%s change_params\n", info->device_name));
2531 2520
2532 cflag = info->tty->termios->c_cflag; 2521 cflag = info->port.tty->termios->c_cflag;
2533 2522
2534 /* if B0 rate (hangup) specified then negate DTR and RTS */ 2523 /* if B0 rate (hangup) specified then negate DTR and RTS */
2535 /* otherwise assert DTR and RTS */ 2524 /* otherwise assert DTR and RTS */
@@ -2561,7 +2550,7 @@ static void change_params(struct slgt_info *info)
2561 bits_per_char = info->params.data_bits + 2550 bits_per_char = info->params.data_bits +
2562 info->params.stop_bits + 1; 2551 info->params.stop_bits + 1;
2563 2552
2564 info->params.data_rate = tty_get_baud_rate(info->tty); 2553 info->params.data_rate = tty_get_baud_rate(info->port.tty);
2565 2554
2566 if (info->params.data_rate) { 2555 if (info->params.data_rate) {
2567 info->timeout = (32*HZ*bits_per_char) / 2556 info->timeout = (32*HZ*bits_per_char) /
@@ -2570,30 +2559,30 @@ static void change_params(struct slgt_info *info)
2570 info->timeout += HZ/50; /* Add .02 seconds of slop */ 2559 info->timeout += HZ/50; /* Add .02 seconds of slop */
2571 2560
2572 if (cflag & CRTSCTS) 2561 if (cflag & CRTSCTS)
2573 info->flags |= ASYNC_CTS_FLOW; 2562 info->port.flags |= ASYNC_CTS_FLOW;
2574 else 2563 else
2575 info->flags &= ~ASYNC_CTS_FLOW; 2564 info->port.flags &= ~ASYNC_CTS_FLOW;
2576 2565
2577 if (cflag & CLOCAL) 2566 if (cflag & CLOCAL)
2578 info->flags &= ~ASYNC_CHECK_CD; 2567 info->port.flags &= ~ASYNC_CHECK_CD;
2579 else 2568 else
2580 info->flags |= ASYNC_CHECK_CD; 2569 info->port.flags |= ASYNC_CHECK_CD;
2581 2570
2582 /* process tty input control flags */ 2571 /* process tty input control flags */
2583 2572
2584 info->read_status_mask = IRQ_RXOVER; 2573 info->read_status_mask = IRQ_RXOVER;
2585 if (I_INPCK(info->tty)) 2574 if (I_INPCK(info->port.tty))
2586 info->read_status_mask |= MASK_PARITY | MASK_FRAMING; 2575 info->read_status_mask |= MASK_PARITY | MASK_FRAMING;
2587 if (I_BRKINT(info->tty) || I_PARMRK(info->tty)) 2576 if (I_BRKINT(info->port.tty) || I_PARMRK(info->port.tty))
2588 info->read_status_mask |= MASK_BREAK; 2577 info->read_status_mask |= MASK_BREAK;
2589 if (I_IGNPAR(info->tty)) 2578 if (I_IGNPAR(info->port.tty))
2590 info->ignore_status_mask |= MASK_PARITY | MASK_FRAMING; 2579 info->ignore_status_mask |= MASK_PARITY | MASK_FRAMING;
2591 if (I_IGNBRK(info->tty)) { 2580 if (I_IGNBRK(info->port.tty)) {
2592 info->ignore_status_mask |= MASK_BREAK; 2581 info->ignore_status_mask |= MASK_BREAK;
2593 /* If ignoring parity and break indicators, ignore 2582 /* If ignoring parity and break indicators, ignore
2594 * overruns too. (For real raw support). 2583 * overruns too. (For real raw support).
2595 */ 2584 */
2596 if (I_IGNPAR(info->tty)) 2585 if (I_IGNPAR(info->port.tty))
2597 info->ignore_status_mask |= MASK_OVERRUN; 2586 info->ignore_status_mask |= MASK_OVERRUN;
2598 } 2587 }
2599 2588
@@ -3144,7 +3133,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
3144 3133
3145 if (filp->f_flags & O_NONBLOCK || tty->flags & (1 << TTY_IO_ERROR)){ 3134 if (filp->f_flags & O_NONBLOCK || tty->flags & (1 << TTY_IO_ERROR)){
3146 /* nonblock mode is set or port is not enabled */ 3135 /* nonblock mode is set or port is not enabled */
3147 info->flags |= ASYNC_NORMAL_ACTIVE; 3136 info->port.flags |= ASYNC_NORMAL_ACTIVE;
3148 return 0; 3137 return 0;
3149 } 3138 }
3150 3139
@@ -3153,21 +3142,21 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
3153 3142
3154 /* Wait for carrier detect and the line to become 3143 /* Wait for carrier detect and the line to become
3155 * free (i.e., not in use by the callout). While we are in 3144 * free (i.e., not in use by the callout). While we are in
3156 * this loop, info->count is dropped by one, so that 3145 * this loop, info->port.count is dropped by one, so that
3157 * close() knows when to free things. We restore it upon 3146 * close() knows when to free things. We restore it upon
3158 * exit, either normal or abnormal. 3147 * exit, either normal or abnormal.
3159 */ 3148 */
3160 3149
3161 retval = 0; 3150 retval = 0;
3162 add_wait_queue(&info->open_wait, &wait); 3151 add_wait_queue(&info->port.open_wait, &wait);
3163 3152
3164 spin_lock_irqsave(&info->lock, flags); 3153 spin_lock_irqsave(&info->lock, flags);
3165 if (!tty_hung_up_p(filp)) { 3154 if (!tty_hung_up_p(filp)) {
3166 extra_count = true; 3155 extra_count = true;
3167 info->count--; 3156 info->port.count--;
3168 } 3157 }
3169 spin_unlock_irqrestore(&info->lock, flags); 3158 spin_unlock_irqrestore(&info->lock, flags);
3170 info->blocked_open++; 3159 info->port.blocked_open++;
3171 3160
3172 while (1) { 3161 while (1) {
3173 if ((tty->termios->c_cflag & CBAUD)) { 3162 if ((tty->termios->c_cflag & CBAUD)) {
@@ -3179,8 +3168,8 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
3179 3168
3180 set_current_state(TASK_INTERRUPTIBLE); 3169 set_current_state(TASK_INTERRUPTIBLE);
3181 3170
3182 if (tty_hung_up_p(filp) || !(info->flags & ASYNC_INITIALIZED)){ 3171 if (tty_hung_up_p(filp) || !(info->port.flags & ASYNC_INITIALIZED)){
3183 retval = (info->flags & ASYNC_HUP_NOTIFY) ? 3172 retval = (info->port.flags & ASYNC_HUP_NOTIFY) ?
3184 -EAGAIN : -ERESTARTSYS; 3173 -EAGAIN : -ERESTARTSYS;
3185 break; 3174 break;
3186 } 3175 }
@@ -3189,7 +3178,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
3189 get_signals(info); 3178 get_signals(info);
3190 spin_unlock_irqrestore(&info->lock,flags); 3179 spin_unlock_irqrestore(&info->lock,flags);
3191 3180
3192 if (!(info->flags & ASYNC_CLOSING) && 3181 if (!(info->port.flags & ASYNC_CLOSING) &&
3193 (do_clocal || (info->signals & SerialSignal_DCD)) ) { 3182 (do_clocal || (info->signals & SerialSignal_DCD)) ) {
3194 break; 3183 break;
3195 } 3184 }
@@ -3204,14 +3193,14 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
3204 } 3193 }
3205 3194
3206 set_current_state(TASK_RUNNING); 3195 set_current_state(TASK_RUNNING);
3207 remove_wait_queue(&info->open_wait, &wait); 3196 remove_wait_queue(&info->port.open_wait, &wait);
3208 3197
3209 if (extra_count) 3198 if (extra_count)
3210 info->count++; 3199 info->port.count++;
3211 info->blocked_open--; 3200 info->port.blocked_open--;
3212 3201
3213 if (!retval) 3202 if (!retval)
3214 info->flags |= ASYNC_NORMAL_ACTIVE; 3203 info->port.flags |= ASYNC_NORMAL_ACTIVE;
3215 3204
3216 DBGINFO(("%s block_til_ready ready, rc=%d\n", tty->driver->name, retval)); 3205 DBGINFO(("%s block_til_ready ready, rc=%d\n", tty->driver->name, retval));
3217 return retval; 3206 return retval;
@@ -3454,14 +3443,13 @@ static struct slgt_info *alloc_dev(int adapter_num, int port_num, struct pci_dev
3454 DBGERR(("%s device alloc failed adapter=%d port=%d\n", 3443 DBGERR(("%s device alloc failed adapter=%d port=%d\n",
3455 driver_name, adapter_num, port_num)); 3444 driver_name, adapter_num, port_num));
3456 } else { 3445 } else {
3446 tty_port_init(&info->port);
3457 info->magic = MGSL_MAGIC; 3447 info->magic = MGSL_MAGIC;
3458 INIT_WORK(&info->task, bh_handler); 3448 INIT_WORK(&info->task, bh_handler);
3459 info->max_frame_size = 4096; 3449 info->max_frame_size = 4096;
3460 info->raw_rx_size = DMABUFSIZE; 3450 info->raw_rx_size = DMABUFSIZE;
3461 info->close_delay = 5*HZ/10; 3451 info->port.close_delay = 5*HZ/10;
3462 info->closing_wait = 30*HZ; 3452 info->port.closing_wait = 30*HZ;
3463 init_waitqueue_head(&info->open_wait);
3464 init_waitqueue_head(&info->close_wait);
3465 init_waitqueue_head(&info->status_event_wait_q); 3453 init_waitqueue_head(&info->status_event_wait_q);
3466 init_waitqueue_head(&info->event_wait_q); 3454 init_waitqueue_head(&info->event_wait_q);
3467 spin_lock_init(&info->netlock); 3455 spin_lock_init(&info->netlock);
@@ -4505,7 +4493,7 @@ static bool rx_get_frame(struct slgt_info *info)
4505 unsigned short status; 4493 unsigned short status;
4506 unsigned int framesize = 0; 4494 unsigned int framesize = 0;
4507 unsigned long flags; 4495 unsigned long flags;
4508 struct tty_struct *tty = info->tty; 4496 struct tty_struct *tty = info->port.tty;
4509 unsigned char addr_field = 0xff; 4497 unsigned char addr_field = 0xff;
4510 unsigned int crc_size = 0; 4498 unsigned int crc_size = 0;
4511 4499
@@ -4577,9 +4565,8 @@ check_again:
4577 4565
4578#if SYNCLINK_GENERIC_HDLC 4566#if SYNCLINK_GENERIC_HDLC
4579 if (framesize == 0) { 4567 if (framesize == 0) {
4580 struct net_device_stats *stats = hdlc_stats(info->netdev); 4568 info->netdev->stats.rx_errors++;
4581 stats->rx_errors++; 4569 info->netdev->stats.rx_frame_errors++;
4582 stats->rx_frame_errors++;
4583 } 4570 }
4584#endif 4571#endif
4585 4572
@@ -4656,7 +4643,7 @@ static bool rx_get_buf(struct slgt_info *info)
4656 DBGDATA(info, info->rbufs[i].buf, count, "rx"); 4643 DBGDATA(info, info->rbufs[i].buf, count, "rx");
4657 DBGINFO(("rx_get_buf size=%d\n", count)); 4644 DBGINFO(("rx_get_buf size=%d\n", count));
4658 if (count) 4645 if (count)
4659 ldisc_receive_buf(info->tty, info->rbufs[i].buf, 4646 ldisc_receive_buf(info->port.tty, info->rbufs[i].buf,
4660 info->flag_buf, count); 4647 info->flag_buf, count);
4661 free_rbufs(info, i, i); 4648 free_rbufs(info, i, i);
4662 return true; 4649 return true;
@@ -4765,11 +4752,11 @@ static int irq_test(struct slgt_info *info)
4765{ 4752{
4766 unsigned long timeout; 4753 unsigned long timeout;
4767 unsigned long flags; 4754 unsigned long flags;
4768 struct tty_struct *oldtty = info->tty; 4755 struct tty_struct *oldtty = info->port.tty;
4769 u32 speed = info->params.data_rate; 4756 u32 speed = info->params.data_rate;
4770 4757
4771 info->params.data_rate = 921600; 4758 info->params.data_rate = 921600;
4772 info->tty = NULL; 4759 info->port.tty = NULL;
4773 4760
4774 spin_lock_irqsave(&info->lock, flags); 4761 spin_lock_irqsave(&info->lock, flags);
4775 async_mode(info); 4762 async_mode(info);
@@ -4797,7 +4784,7 @@ static int irq_test(struct slgt_info *info)
4797 spin_unlock_irqrestore(&info->lock,flags); 4784 spin_unlock_irqrestore(&info->lock,flags);
4798 4785
4799 info->params.data_rate = speed; 4786 info->params.data_rate = speed;
4800 info->tty = oldtty; 4787 info->port.tty = oldtty;
4801 4788
4802 info->init_error = info->irq_occurred ? 0 : DiagStatus_IrqFailure; 4789 info->init_error = info->irq_occurred ? 0 : DiagStatus_IrqFailure;
4803 return info->irq_occurred ? 0 : -ENODEV; 4790 return info->irq_occurred ? 0 : -ENODEV;
@@ -4837,7 +4824,7 @@ static int loopback_test(struct slgt_info *info)
4837 int rc = -ENODEV; 4824 int rc = -ENODEV;
4838 unsigned long flags; 4825 unsigned long flags;
4839 4826
4840 struct tty_struct *oldtty = info->tty; 4827 struct tty_struct *oldtty = info->port.tty;
4841 MGSL_PARAMS params; 4828 MGSL_PARAMS params;
4842 4829
4843 memcpy(&params, &info->params, sizeof(params)); 4830 memcpy(&params, &info->params, sizeof(params));
@@ -4845,7 +4832,7 @@ static int loopback_test(struct slgt_info *info)
4845 info->params.mode = MGSL_MODE_ASYNC; 4832 info->params.mode = MGSL_MODE_ASYNC;
4846 info->params.data_rate = 921600; 4833 info->params.data_rate = 921600;
4847 info->params.loopback = 1; 4834 info->params.loopback = 1;
4848 info->tty = NULL; 4835 info->port.tty = NULL;
4849 4836
4850 /* build and send transmit frame */ 4837 /* build and send transmit frame */
4851 for (count = 0; count < TESTFRAMESIZE; ++count) 4838 for (count = 0; count < TESTFRAMESIZE; ++count)
@@ -4883,7 +4870,7 @@ static int loopback_test(struct slgt_info *info)
4883 spin_unlock_irqrestore(&info->lock,flags); 4870 spin_unlock_irqrestore(&info->lock,flags);
4884 4871
4885 memcpy(&info->params, &params, sizeof(info->params)); 4872 memcpy(&info->params, &params, sizeof(info->params));
4886 info->tty = oldtty; 4873 info->port.tty = oldtty;
4887 4874
4888 info->init_error = rc ? DiagStatus_DmaFailure : 0; 4875 info->init_error = rc ? DiagStatus_DmaFailure : 0;
4889 return rc; 4876 return rc;
diff --git a/drivers/char/synclinkmp.c b/drivers/char/synclinkmp.c
index bec54866e0bb..5768c4136342 100644
--- a/drivers/char/synclinkmp.c
+++ b/drivers/char/synclinkmp.c
@@ -151,18 +151,15 @@ struct _input_signal_events {
151typedef struct _synclinkmp_info { 151typedef struct _synclinkmp_info {
152 void *if_ptr; /* General purpose pointer (used by SPPP) */ 152 void *if_ptr; /* General purpose pointer (used by SPPP) */
153 int magic; 153 int magic;
154 int flags; 154 struct tty_port port;
155 int count; /* count of opens */
156 int line; 155 int line;
157 unsigned short close_delay; 156 unsigned short close_delay;
158 unsigned short closing_wait; /* time to wait before closing */ 157 unsigned short closing_wait; /* time to wait before closing */
159 158
160 struct mgsl_icount icount; 159 struct mgsl_icount icount;
161 160
162 struct tty_struct *tty;
163 int timeout; 161 int timeout;
164 int x_char; /* xon/xoff character */ 162 int x_char; /* xon/xoff character */
165 int blocked_open; /* # of blocked opens */
166 u16 read_status_mask1; /* break detection (SR1 indications) */ 163 u16 read_status_mask1; /* break detection (SR1 indications) */
167 u16 read_status_mask2; /* parity/framing/overun (SR2 indications) */ 164 u16 read_status_mask2; /* parity/framing/overun (SR2 indications) */
168 unsigned char ignore_status_mask1; /* break detection (SR1 indications) */ 165 unsigned char ignore_status_mask1; /* break detection (SR1 indications) */
@@ -172,9 +169,6 @@ typedef struct _synclinkmp_info {
172 int tx_get; 169 int tx_get;
173 int tx_count; 170 int tx_count;
174 171
175 wait_queue_head_t open_wait;
176 wait_queue_head_t close_wait;
177
178 wait_queue_head_t status_event_wait_q; 172 wait_queue_head_t status_event_wait_q;
179 wait_queue_head_t event_wait_q; 173 wait_queue_head_t event_wait_q;
180 struct timer_list tx_timer; /* HDLC transmit timeout timer */ 174 struct timer_list tx_timer; /* HDLC transmit timeout timer */
@@ -462,13 +456,13 @@ static int synclinkmp_device_count = 0;
462 * .text section address and breakpoint on module load. 456 * .text section address and breakpoint on module load.
463 * This is useful for use with gdb and add-symbol-file command. 457 * This is useful for use with gdb and add-symbol-file command.
464 */ 458 */
465static int break_on_load=0; 459static int break_on_load = 0;
466 460
467/* 461/*
468 * Driver major number, defaults to zero to get auto 462 * Driver major number, defaults to zero to get auto
469 * assigned major number. May be forced as module parameter. 463 * assigned major number. May be forced as module parameter.
470 */ 464 */
471static int ttymajor=0; 465static int ttymajor = 0;
472 466
473/* 467/*
474 * Array of user specified options for ISA adapters. 468 * Array of user specified options for ISA adapters.
@@ -712,8 +706,8 @@ static void ldisc_receive_buf(struct tty_struct *tty,
712 return; 706 return;
713 ld = tty_ldisc_ref(tty); 707 ld = tty_ldisc_ref(tty);
714 if (ld) { 708 if (ld) {
715 if (ld->receive_buf) 709 if (ld->ops->receive_buf)
716 ld->receive_buf(tty, data, flags, count); 710 ld->ops->receive_buf(tty, data, flags, count);
717 tty_ldisc_deref(ld); 711 tty_ldisc_deref(ld);
718 } 712 }
719} 713}
@@ -747,22 +741,22 @@ static int open(struct tty_struct *tty, struct file *filp)
747 } 741 }
748 742
749 tty->driver_data = info; 743 tty->driver_data = info;
750 info->tty = tty; 744 info->port.tty = tty;
751 745
752 if (debug_level >= DEBUG_LEVEL_INFO) 746 if (debug_level >= DEBUG_LEVEL_INFO)
753 printk("%s(%d):%s open(), old ref count = %d\n", 747 printk("%s(%d):%s open(), old ref count = %d\n",
754 __FILE__,__LINE__,tty->driver->name, info->count); 748 __FILE__,__LINE__,tty->driver->name, info->port.count);
755 749
756 /* If port is closing, signal caller to try again */ 750 /* If port is closing, signal caller to try again */
757 if (tty_hung_up_p(filp) || info->flags & ASYNC_CLOSING){ 751 if (tty_hung_up_p(filp) || info->port.flags & ASYNC_CLOSING){
758 if (info->flags & ASYNC_CLOSING) 752 if (info->port.flags & ASYNC_CLOSING)
759 interruptible_sleep_on(&info->close_wait); 753 interruptible_sleep_on(&info->port.close_wait);
760 retval = ((info->flags & ASYNC_HUP_NOTIFY) ? 754 retval = ((info->port.flags & ASYNC_HUP_NOTIFY) ?
761 -EAGAIN : -ERESTARTSYS); 755 -EAGAIN : -ERESTARTSYS);
762 goto cleanup; 756 goto cleanup;
763 } 757 }
764 758
765 info->tty->low_latency = (info->flags & ASYNC_LOW_LATENCY) ? 1 : 0; 759 info->port.tty->low_latency = (info->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0;
766 760
767 spin_lock_irqsave(&info->netlock, flags); 761 spin_lock_irqsave(&info->netlock, flags);
768 if (info->netcount) { 762 if (info->netcount) {
@@ -770,10 +764,10 @@ static int open(struct tty_struct *tty, struct file *filp)
770 spin_unlock_irqrestore(&info->netlock, flags); 764 spin_unlock_irqrestore(&info->netlock, flags);
771 goto cleanup; 765 goto cleanup;
772 } 766 }
773 info->count++; 767 info->port.count++;
774 spin_unlock_irqrestore(&info->netlock, flags); 768 spin_unlock_irqrestore(&info->netlock, flags);
775 769
776 if (info->count == 1) { 770 if (info->port.count == 1) {
777 /* 1st open on this device, init hardware */ 771 /* 1st open on this device, init hardware */
778 retval = startup(info); 772 retval = startup(info);
779 if (retval < 0) 773 if (retval < 0)
@@ -796,9 +790,9 @@ static int open(struct tty_struct *tty, struct file *filp)
796cleanup: 790cleanup:
797 if (retval) { 791 if (retval) {
798 if (tty->count == 1) 792 if (tty->count == 1)
799 info->tty = NULL; /* tty layer will release tty struct */ 793 info->port.tty = NULL; /* tty layer will release tty struct */
800 if(info->count) 794 if(info->port.count)
801 info->count--; 795 info->port.count--;
802 } 796 }
803 797
804 return retval; 798 return retval;
@@ -816,33 +810,33 @@ static void close(struct tty_struct *tty, struct file *filp)
816 810
817 if (debug_level >= DEBUG_LEVEL_INFO) 811 if (debug_level >= DEBUG_LEVEL_INFO)
818 printk("%s(%d):%s close() entry, count=%d\n", 812 printk("%s(%d):%s close() entry, count=%d\n",
819 __FILE__,__LINE__, info->device_name, info->count); 813 __FILE__,__LINE__, info->device_name, info->port.count);
820 814
821 if (!info->count) 815 if (!info->port.count)
822 return; 816 return;
823 817
824 if (tty_hung_up_p(filp)) 818 if (tty_hung_up_p(filp))
825 goto cleanup; 819 goto cleanup;
826 820
827 if ((tty->count == 1) && (info->count != 1)) { 821 if ((tty->count == 1) && (info->port.count != 1)) {
828 /* 822 /*
829 * tty->count is 1 and the tty structure will be freed. 823 * tty->count is 1 and the tty structure will be freed.
830 * info->count should be one in this case. 824 * info->port.count should be one in this case.
831 * if it's not, correct it so that the port is shutdown. 825 * if it's not, correct it so that the port is shutdown.
832 */ 826 */
833 printk("%s(%d):%s close: bad refcount; tty->count is 1, " 827 printk("%s(%d):%s close: bad refcount; tty->count is 1, "
834 "info->count is %d\n", 828 "info->port.count is %d\n",
835 __FILE__,__LINE__, info->device_name, info->count); 829 __FILE__,__LINE__, info->device_name, info->port.count);
836 info->count = 1; 830 info->port.count = 1;
837 } 831 }
838 832
839 info->count--; 833 info->port.count--;
840 834
841 /* if at least one open remaining, leave hardware active */ 835 /* if at least one open remaining, leave hardware active */
842 if (info->count) 836 if (info->port.count)
843 goto cleanup; 837 goto cleanup;
844 838
845 info->flags |= ASYNC_CLOSING; 839 info->port.flags |= ASYNC_CLOSING;
846 840
847 /* set tty->closing to notify line discipline to 841 /* set tty->closing to notify line discipline to
848 * only process XON/XOFF characters. Only the N_TTY 842 * only process XON/XOFF characters. Only the N_TTY
@@ -852,14 +846,14 @@ static void close(struct tty_struct *tty, struct file *filp)
852 846
853 /* wait for transmit data to clear all layers */ 847 /* wait for transmit data to clear all layers */
854 848
855 if (info->closing_wait != ASYNC_CLOSING_WAIT_NONE) { 849 if (info->port.closing_wait != ASYNC_CLOSING_WAIT_NONE) {
856 if (debug_level >= DEBUG_LEVEL_INFO) 850 if (debug_level >= DEBUG_LEVEL_INFO)
857 printk("%s(%d):%s close() calling tty_wait_until_sent\n", 851 printk("%s(%d):%s close() calling tty_wait_until_sent\n",
858 __FILE__,__LINE__, info->device_name ); 852 __FILE__,__LINE__, info->device_name );
859 tty_wait_until_sent(tty, info->closing_wait); 853 tty_wait_until_sent(tty, info->port.closing_wait);
860 } 854 }
861 855
862 if (info->flags & ASYNC_INITIALIZED) 856 if (info->port.flags & ASYNC_INITIALIZED)
863 wait_until_sent(tty, info->timeout); 857 wait_until_sent(tty, info->timeout);
864 858
865 flush_buffer(tty); 859 flush_buffer(tty);
@@ -869,23 +863,23 @@ static void close(struct tty_struct *tty, struct file *filp)
869 shutdown(info); 863 shutdown(info);
870 864
871 tty->closing = 0; 865 tty->closing = 0;
872 info->tty = NULL; 866 info->port.tty = NULL;
873 867
874 if (info->blocked_open) { 868 if (info->port.blocked_open) {
875 if (info->close_delay) { 869 if (info->port.close_delay) {
876 msleep_interruptible(jiffies_to_msecs(info->close_delay)); 870 msleep_interruptible(jiffies_to_msecs(info->port.close_delay));
877 } 871 }
878 wake_up_interruptible(&info->open_wait); 872 wake_up_interruptible(&info->port.open_wait);
879 } 873 }
880 874
881 info->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); 875 info->port.flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
882 876
883 wake_up_interruptible(&info->close_wait); 877 wake_up_interruptible(&info->port.close_wait);
884 878
885cleanup: 879cleanup:
886 if (debug_level >= DEBUG_LEVEL_INFO) 880 if (debug_level >= DEBUG_LEVEL_INFO)
887 printk("%s(%d):%s close() exit, count=%d\n", __FILE__,__LINE__, 881 printk("%s(%d):%s close() exit, count=%d\n", __FILE__,__LINE__,
888 tty->driver->name, info->count); 882 tty->driver->name, info->port.count);
889} 883}
890 884
891/* Called by tty_hangup() when a hangup is signaled. 885/* Called by tty_hangup() when a hangup is signaled.
@@ -905,11 +899,11 @@ static void hangup(struct tty_struct *tty)
905 flush_buffer(tty); 899 flush_buffer(tty);
906 shutdown(info); 900 shutdown(info);
907 901
908 info->count = 0; 902 info->port.count = 0;
909 info->flags &= ~ASYNC_NORMAL_ACTIVE; 903 info->port.flags &= ~ASYNC_NORMAL_ACTIVE;
910 info->tty = NULL; 904 info->port.tty = NULL;
911 905
912 wake_up_interruptible(&info->open_wait); 906 wake_up_interruptible(&info->port.open_wait);
913} 907}
914 908
915/* Set new termios settings 909/* Set new termios settings
@@ -1123,7 +1117,7 @@ static void wait_until_sent(struct tty_struct *tty, int timeout)
1123 1117
1124 lock_kernel(); 1118 lock_kernel();
1125 1119
1126 if (!(info->flags & ASYNC_INITIALIZED)) 1120 if (!(info->port.flags & ASYNC_INITIALIZED))
1127 goto exit; 1121 goto exit;
1128 1122
1129 orig_jiffies = jiffies; 1123 orig_jiffies = jiffies;
@@ -1636,7 +1630,7 @@ static int hdlcdev_attach(struct net_device *dev, unsigned short encoding,
1636 unsigned short new_crctype; 1630 unsigned short new_crctype;
1637 1631
1638 /* return error if TTY interface open */ 1632 /* return error if TTY interface open */
1639 if (info->count) 1633 if (info->port.count)
1640 return -EBUSY; 1634 return -EBUSY;
1641 1635
1642 switch (encoding) 1636 switch (encoding)
@@ -1678,7 +1672,6 @@ static int hdlcdev_attach(struct net_device *dev, unsigned short encoding,
1678static int hdlcdev_xmit(struct sk_buff *skb, struct net_device *dev) 1672static int hdlcdev_xmit(struct sk_buff *skb, struct net_device *dev)
1679{ 1673{
1680 SLMP_INFO *info = dev_to_port(dev); 1674 SLMP_INFO *info = dev_to_port(dev);
1681 struct net_device_stats *stats = hdlc_stats(dev);
1682 unsigned long flags; 1675 unsigned long flags;
1683 1676
1684 if (debug_level >= DEBUG_LEVEL_INFO) 1677 if (debug_level >= DEBUG_LEVEL_INFO)
@@ -1692,8 +1685,8 @@ static int hdlcdev_xmit(struct sk_buff *skb, struct net_device *dev)
1692 tx_load_dma_buffer(info, skb->data, skb->len); 1685 tx_load_dma_buffer(info, skb->data, skb->len);
1693 1686
1694 /* update network statistics */ 1687 /* update network statistics */
1695 stats->tx_packets++; 1688 dev->stats.tx_packets++;
1696 stats->tx_bytes += skb->len; 1689 dev->stats.tx_bytes += skb->len;
1697 1690
1698 /* done with socket buffer, so free it */ 1691 /* done with socket buffer, so free it */
1699 dev_kfree_skb(skb); 1692 dev_kfree_skb(skb);
@@ -1733,7 +1726,7 @@ static int hdlcdev_open(struct net_device *dev)
1733 1726
1734 /* arbitrate between network and tty opens */ 1727 /* arbitrate between network and tty opens */
1735 spin_lock_irqsave(&info->netlock, flags); 1728 spin_lock_irqsave(&info->netlock, flags);
1736 if (info->count != 0 || info->netcount != 0) { 1729 if (info->port.count != 0 || info->netcount != 0) {
1737 printk(KERN_WARNING "%s: hdlc_open returning busy\n", dev->name); 1730 printk(KERN_WARNING "%s: hdlc_open returning busy\n", dev->name);
1738 spin_unlock_irqrestore(&info->netlock, flags); 1731 spin_unlock_irqrestore(&info->netlock, flags);
1739 return -EBUSY; 1732 return -EBUSY;
@@ -1819,7 +1812,7 @@ static int hdlcdev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1819 printk("%s:hdlcdev_ioctl(%s)\n",__FILE__,dev->name); 1812 printk("%s:hdlcdev_ioctl(%s)\n",__FILE__,dev->name);
1820 1813
1821 /* return error if TTY interface open */ 1814 /* return error if TTY interface open */
1822 if (info->count) 1815 if (info->port.count)
1823 return -EBUSY; 1816 return -EBUSY;
1824 1817
1825 if (cmd != SIOCWANDEV) 1818 if (cmd != SIOCWANDEV)
@@ -1909,14 +1902,13 @@ static int hdlcdev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1909static void hdlcdev_tx_timeout(struct net_device *dev) 1902static void hdlcdev_tx_timeout(struct net_device *dev)
1910{ 1903{
1911 SLMP_INFO *info = dev_to_port(dev); 1904 SLMP_INFO *info = dev_to_port(dev);
1912 struct net_device_stats *stats = hdlc_stats(dev);
1913 unsigned long flags; 1905 unsigned long flags;
1914 1906
1915 if (debug_level >= DEBUG_LEVEL_INFO) 1907 if (debug_level >= DEBUG_LEVEL_INFO)
1916 printk("hdlcdev_tx_timeout(%s)\n",dev->name); 1908 printk("hdlcdev_tx_timeout(%s)\n",dev->name);
1917 1909
1918 stats->tx_errors++; 1910 dev->stats.tx_errors++;
1919 stats->tx_aborted_errors++; 1911 dev->stats.tx_aborted_errors++;
1920 1912
1921 spin_lock_irqsave(&info->lock,flags); 1913 spin_lock_irqsave(&info->lock,flags);
1922 tx_stop(info); 1914 tx_stop(info);
@@ -1949,27 +1941,27 @@ static void hdlcdev_rx(SLMP_INFO *info, char *buf, int size)
1949{ 1941{
1950 struct sk_buff *skb = dev_alloc_skb(size); 1942 struct sk_buff *skb = dev_alloc_skb(size);
1951 struct net_device *dev = info->netdev; 1943 struct net_device *dev = info->netdev;
1952 struct net_device_stats *stats = hdlc_stats(dev);
1953 1944
1954 if (debug_level >= DEBUG_LEVEL_INFO) 1945 if (debug_level >= DEBUG_LEVEL_INFO)
1955 printk("hdlcdev_rx(%s)\n",dev->name); 1946 printk("hdlcdev_rx(%s)\n",dev->name);
1956 1947
1957 if (skb == NULL) { 1948 if (skb == NULL) {
1958 printk(KERN_NOTICE "%s: can't alloc skb, dropping packet\n", dev->name); 1949 printk(KERN_NOTICE "%s: can't alloc skb, dropping packet\n",
1959 stats->rx_dropped++; 1950 dev->name);
1951 dev->stats.rx_dropped++;
1960 return; 1952 return;
1961 } 1953 }
1962 1954
1963 memcpy(skb_put(skb, size),buf,size); 1955 memcpy(skb_put(skb, size), buf, size);
1964 1956
1965 skb->protocol = hdlc_type_trans(skb, info->netdev); 1957 skb->protocol = hdlc_type_trans(skb, dev);
1966 1958
1967 stats->rx_packets++; 1959 dev->stats.rx_packets++;
1968 stats->rx_bytes += size; 1960 dev->stats.rx_bytes += size;
1969 1961
1970 netif_rx(skb); 1962 netif_rx(skb);
1971 1963
1972 info->netdev->last_rx = jiffies; 1964 dev->last_rx = jiffies;
1973} 1965}
1974 1966
1975/** 1967/**
@@ -2128,7 +2120,7 @@ static void bh_receive(SLMP_INFO *info)
2128 2120
2129static void bh_transmit(SLMP_INFO *info) 2121static void bh_transmit(SLMP_INFO *info)
2130{ 2122{
2131 struct tty_struct *tty = info->tty; 2123 struct tty_struct *tty = info->port.tty;
2132 2124
2133 if ( debug_level >= DEBUG_LEVEL_BH ) 2125 if ( debug_level >= DEBUG_LEVEL_BH )
2134 printk( "%s(%d):%s bh_transmit() entry\n", 2126 printk( "%s(%d):%s bh_transmit() entry\n",
@@ -2178,7 +2170,7 @@ static void isr_timer(SLMP_INFO * info)
2178 2170
2179static void isr_rxint(SLMP_INFO * info) 2171static void isr_rxint(SLMP_INFO * info)
2180{ 2172{
2181 struct tty_struct *tty = info->tty; 2173 struct tty_struct *tty = info->port.tty;
2182 struct mgsl_icount *icount = &info->icount; 2174 struct mgsl_icount *icount = &info->icount;
2183 unsigned char status = read_reg(info, SR1) & info->ie1_value & (FLGD + IDLD + CDCD + BRKD); 2175 unsigned char status = read_reg(info, SR1) & info->ie1_value & (FLGD + IDLD + CDCD + BRKD);
2184 unsigned char status2 = read_reg(info, SR2) & info->ie2_value & OVRN; 2176 unsigned char status2 = read_reg(info, SR2) & info->ie2_value & OVRN;
@@ -2205,7 +2197,7 @@ static void isr_rxint(SLMP_INFO * info)
2205 if (!(status & info->ignore_status_mask1)) { 2197 if (!(status & info->ignore_status_mask1)) {
2206 if (info->read_status_mask1 & BRKD) { 2198 if (info->read_status_mask1 & BRKD) {
2207 tty_insert_flip_char(tty, 0, TTY_BREAK); 2199 tty_insert_flip_char(tty, 0, TTY_BREAK);
2208 if (info->flags & ASYNC_SAK) 2200 if (info->port.flags & ASYNC_SAK)
2209 do_SAK(tty); 2201 do_SAK(tty);
2210 } 2202 }
2211 } 2203 }
@@ -2239,7 +2231,7 @@ static void isr_rxrdy(SLMP_INFO * info)
2239{ 2231{
2240 u16 status; 2232 u16 status;
2241 unsigned char DataByte; 2233 unsigned char DataByte;
2242 struct tty_struct *tty = info->tty; 2234 struct tty_struct *tty = info->port.tty;
2243 struct mgsl_icount *icount = &info->icount; 2235 struct mgsl_icount *icount = &info->icount;
2244 2236
2245 if ( debug_level >= DEBUG_LEVEL_ISR ) 2237 if ( debug_level >= DEBUG_LEVEL_ISR )
@@ -2352,7 +2344,7 @@ static void isr_txeom(SLMP_INFO * info, unsigned char status)
2352 else 2344 else
2353#endif 2345#endif
2354 { 2346 {
2355 if (info->tty && (info->tty->stopped || info->tty->hw_stopped)) { 2347 if (info->port.tty && (info->port.tty->stopped || info->port.tty->hw_stopped)) {
2356 tx_stop(info); 2348 tx_stop(info);
2357 return; 2349 return;
2358 } 2350 }
@@ -2407,7 +2399,7 @@ static void isr_txrdy(SLMP_INFO * info)
2407 return; 2399 return;
2408 } 2400 }
2409 2401
2410 if (info->tty && (info->tty->stopped || info->tty->hw_stopped)) { 2402 if (info->port.tty && (info->port.tty->stopped || info->port.tty->hw_stopped)) {
2411 tx_stop(info); 2403 tx_stop(info);
2412 return; 2404 return;
2413 } 2405 }
@@ -2554,29 +2546,29 @@ static void isr_io_pin( SLMP_INFO *info, u16 status )
2554 wake_up_interruptible(&info->status_event_wait_q); 2546 wake_up_interruptible(&info->status_event_wait_q);
2555 wake_up_interruptible(&info->event_wait_q); 2547 wake_up_interruptible(&info->event_wait_q);
2556 2548
2557 if ( (info->flags & ASYNC_CHECK_CD) && 2549 if ( (info->port.flags & ASYNC_CHECK_CD) &&
2558 (status & MISCSTATUS_DCD_LATCHED) ) { 2550 (status & MISCSTATUS_DCD_LATCHED) ) {
2559 if ( debug_level >= DEBUG_LEVEL_ISR ) 2551 if ( debug_level >= DEBUG_LEVEL_ISR )
2560 printk("%s CD now %s...", info->device_name, 2552 printk("%s CD now %s...", info->device_name,
2561 (status & SerialSignal_DCD) ? "on" : "off"); 2553 (status & SerialSignal_DCD) ? "on" : "off");
2562 if (status & SerialSignal_DCD) 2554 if (status & SerialSignal_DCD)
2563 wake_up_interruptible(&info->open_wait); 2555 wake_up_interruptible(&info->port.open_wait);
2564 else { 2556 else {
2565 if ( debug_level >= DEBUG_LEVEL_ISR ) 2557 if ( debug_level >= DEBUG_LEVEL_ISR )
2566 printk("doing serial hangup..."); 2558 printk("doing serial hangup...");
2567 if (info->tty) 2559 if (info->port.tty)
2568 tty_hangup(info->tty); 2560 tty_hangup(info->port.tty);
2569 } 2561 }
2570 } 2562 }
2571 2563
2572 if ( (info->flags & ASYNC_CTS_FLOW) && 2564 if ( (info->port.flags & ASYNC_CTS_FLOW) &&
2573 (status & MISCSTATUS_CTS_LATCHED) ) { 2565 (status & MISCSTATUS_CTS_LATCHED) ) {
2574 if ( info->tty ) { 2566 if ( info->port.tty ) {
2575 if (info->tty->hw_stopped) { 2567 if (info->port.tty->hw_stopped) {
2576 if (status & SerialSignal_CTS) { 2568 if (status & SerialSignal_CTS) {
2577 if ( debug_level >= DEBUG_LEVEL_ISR ) 2569 if ( debug_level >= DEBUG_LEVEL_ISR )
2578 printk("CTS tx start..."); 2570 printk("CTS tx start...");
2579 info->tty->hw_stopped = 0; 2571 info->port.tty->hw_stopped = 0;
2580 tx_start(info); 2572 tx_start(info);
2581 info->pending_bh |= BH_TRANSMIT; 2573 info->pending_bh |= BH_TRANSMIT;
2582 return; 2574 return;
@@ -2585,7 +2577,7 @@ static void isr_io_pin( SLMP_INFO *info, u16 status )
2585 if (!(status & SerialSignal_CTS)) { 2577 if (!(status & SerialSignal_CTS)) {
2586 if ( debug_level >= DEBUG_LEVEL_ISR ) 2578 if ( debug_level >= DEBUG_LEVEL_ISR )
2587 printk("CTS tx stop..."); 2579 printk("CTS tx stop...");
2588 info->tty->hw_stopped = 1; 2580 info->port.tty->hw_stopped = 1;
2589 tx_stop(info); 2581 tx_stop(info);
2590 } 2582 }
2591 } 2583 }
@@ -2701,7 +2693,7 @@ static irqreturn_t synclinkmp_interrupt(int dummy, void *dev_id)
2701 * do not request bottom half processing if the 2693 * do not request bottom half processing if the
2702 * device is not open in a normal mode. 2694 * device is not open in a normal mode.
2703 */ 2695 */
2704 if ( port && (port->count || port->netcount) && 2696 if ( port && (port->port.count || port->netcount) &&
2705 port->pending_bh && !port->bh_running && 2697 port->pending_bh && !port->bh_running &&
2706 !port->bh_requested ) { 2698 !port->bh_requested ) {
2707 if ( debug_level >= DEBUG_LEVEL_ISR ) 2699 if ( debug_level >= DEBUG_LEVEL_ISR )
@@ -2727,7 +2719,7 @@ static int startup(SLMP_INFO * info)
2727 if ( debug_level >= DEBUG_LEVEL_INFO ) 2719 if ( debug_level >= DEBUG_LEVEL_INFO )
2728 printk("%s(%d):%s tx_releaseup()\n",__FILE__,__LINE__,info->device_name); 2720 printk("%s(%d):%s tx_releaseup()\n",__FILE__,__LINE__,info->device_name);
2729 2721
2730 if (info->flags & ASYNC_INITIALIZED) 2722 if (info->port.flags & ASYNC_INITIALIZED)
2731 return 0; 2723 return 0;
2732 2724
2733 if (!info->tx_buf) { 2725 if (!info->tx_buf) {
@@ -2750,10 +2742,10 @@ static int startup(SLMP_INFO * info)
2750 2742
2751 mod_timer(&info->status_timer, jiffies + msecs_to_jiffies(10)); 2743 mod_timer(&info->status_timer, jiffies + msecs_to_jiffies(10));
2752 2744
2753 if (info->tty) 2745 if (info->port.tty)
2754 clear_bit(TTY_IO_ERROR, &info->tty->flags); 2746 clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
2755 2747
2756 info->flags |= ASYNC_INITIALIZED; 2748 info->port.flags |= ASYNC_INITIALIZED;
2757 2749
2758 return 0; 2750 return 0;
2759} 2751}
@@ -2764,7 +2756,7 @@ static void shutdown(SLMP_INFO * info)
2764{ 2756{
2765 unsigned long flags; 2757 unsigned long flags;
2766 2758
2767 if (!(info->flags & ASYNC_INITIALIZED)) 2759 if (!(info->port.flags & ASYNC_INITIALIZED))
2768 return; 2760 return;
2769 2761
2770 if (debug_level >= DEBUG_LEVEL_INFO) 2762 if (debug_level >= DEBUG_LEVEL_INFO)
@@ -2786,17 +2778,17 @@ static void shutdown(SLMP_INFO * info)
2786 2778
2787 reset_port(info); 2779 reset_port(info);
2788 2780
2789 if (!info->tty || info->tty->termios->c_cflag & HUPCL) { 2781 if (!info->port.tty || info->port.tty->termios->c_cflag & HUPCL) {
2790 info->serial_signals &= ~(SerialSignal_DTR + SerialSignal_RTS); 2782 info->serial_signals &= ~(SerialSignal_DTR + SerialSignal_RTS);
2791 set_signals(info); 2783 set_signals(info);
2792 } 2784 }
2793 2785
2794 spin_unlock_irqrestore(&info->lock,flags); 2786 spin_unlock_irqrestore(&info->lock,flags);
2795 2787
2796 if (info->tty) 2788 if (info->port.tty)
2797 set_bit(TTY_IO_ERROR, &info->tty->flags); 2789 set_bit(TTY_IO_ERROR, &info->port.tty->flags);
2798 2790
2799 info->flags &= ~ASYNC_INITIALIZED; 2791 info->port.flags &= ~ASYNC_INITIALIZED;
2800} 2792}
2801 2793
2802static void program_hw(SLMP_INFO *info) 2794static void program_hw(SLMP_INFO *info)
@@ -2827,7 +2819,7 @@ static void program_hw(SLMP_INFO *info)
2827 2819
2828 get_signals(info); 2820 get_signals(info);
2829 2821
2830 if (info->netcount || (info->tty && info->tty->termios->c_cflag & CREAD) ) 2822 if (info->netcount || (info->port.tty && info->port.tty->termios->c_cflag & CREAD) )
2831 rx_start(info); 2823 rx_start(info);
2832 2824
2833 spin_unlock_irqrestore(&info->lock,flags); 2825 spin_unlock_irqrestore(&info->lock,flags);
@@ -2840,14 +2832,14 @@ static void change_params(SLMP_INFO *info)
2840 unsigned cflag; 2832 unsigned cflag;
2841 int bits_per_char; 2833 int bits_per_char;
2842 2834
2843 if (!info->tty || !info->tty->termios) 2835 if (!info->port.tty || !info->port.tty->termios)
2844 return; 2836 return;
2845 2837
2846 if (debug_level >= DEBUG_LEVEL_INFO) 2838 if (debug_level >= DEBUG_LEVEL_INFO)
2847 printk("%s(%d):%s change_params()\n", 2839 printk("%s(%d):%s change_params()\n",
2848 __FILE__,__LINE__, info->device_name ); 2840 __FILE__,__LINE__, info->device_name );
2849 2841
2850 cflag = info->tty->termios->c_cflag; 2842 cflag = info->port.tty->termios->c_cflag;
2851 2843
2852 /* if B0 rate (hangup) specified then negate DTR and RTS */ 2844 /* if B0 rate (hangup) specified then negate DTR and RTS */
2853 /* otherwise assert DTR and RTS */ 2845 /* otherwise assert DTR and RTS */
@@ -2895,7 +2887,7 @@ static void change_params(SLMP_INFO *info)
2895 * current data rate. 2887 * current data rate.
2896 */ 2888 */
2897 if (info->params.data_rate <= 460800) { 2889 if (info->params.data_rate <= 460800) {
2898 info->params.data_rate = tty_get_baud_rate(info->tty); 2890 info->params.data_rate = tty_get_baud_rate(info->port.tty);
2899 } 2891 }
2900 2892
2901 if ( info->params.data_rate ) { 2893 if ( info->params.data_rate ) {
@@ -2905,30 +2897,30 @@ static void change_params(SLMP_INFO *info)
2905 info->timeout += HZ/50; /* Add .02 seconds of slop */ 2897 info->timeout += HZ/50; /* Add .02 seconds of slop */
2906 2898
2907 if (cflag & CRTSCTS) 2899 if (cflag & CRTSCTS)
2908 info->flags |= ASYNC_CTS_FLOW; 2900 info->port.flags |= ASYNC_CTS_FLOW;
2909 else 2901 else
2910 info->flags &= ~ASYNC_CTS_FLOW; 2902 info->port.flags &= ~ASYNC_CTS_FLOW;
2911 2903
2912 if (cflag & CLOCAL) 2904 if (cflag & CLOCAL)
2913 info->flags &= ~ASYNC_CHECK_CD; 2905 info->port.flags &= ~ASYNC_CHECK_CD;
2914 else 2906 else
2915 info->flags |= ASYNC_CHECK_CD; 2907 info->port.flags |= ASYNC_CHECK_CD;
2916 2908
2917 /* process tty input control flags */ 2909 /* process tty input control flags */
2918 2910
2919 info->read_status_mask2 = OVRN; 2911 info->read_status_mask2 = OVRN;
2920 if (I_INPCK(info->tty)) 2912 if (I_INPCK(info->port.tty))
2921 info->read_status_mask2 |= PE | FRME; 2913 info->read_status_mask2 |= PE | FRME;
2922 if (I_BRKINT(info->tty) || I_PARMRK(info->tty)) 2914 if (I_BRKINT(info->port.tty) || I_PARMRK(info->port.tty))
2923 info->read_status_mask1 |= BRKD; 2915 info->read_status_mask1 |= BRKD;
2924 if (I_IGNPAR(info->tty)) 2916 if (I_IGNPAR(info->port.tty))
2925 info->ignore_status_mask2 |= PE | FRME; 2917 info->ignore_status_mask2 |= PE | FRME;
2926 if (I_IGNBRK(info->tty)) { 2918 if (I_IGNBRK(info->port.tty)) {
2927 info->ignore_status_mask1 |= BRKD; 2919 info->ignore_status_mask1 |= BRKD;
2928 /* If ignoring parity and break indicators, ignore 2920 /* If ignoring parity and break indicators, ignore
2929 * overruns too. (For real raw support). 2921 * overruns too. (For real raw support).
2930 */ 2922 */
2931 if (I_IGNPAR(info->tty)) 2923 if (I_IGNPAR(info->port.tty))
2932 info->ignore_status_mask2 |= OVRN; 2924 info->ignore_status_mask2 |= OVRN;
2933 } 2925 }
2934 2926
@@ -3348,7 +3340,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
3348 if (filp->f_flags & O_NONBLOCK || tty->flags & (1 << TTY_IO_ERROR)){ 3340 if (filp->f_flags & O_NONBLOCK || tty->flags & (1 << TTY_IO_ERROR)){
3349 /* nonblock mode is set or port is not enabled */ 3341 /* nonblock mode is set or port is not enabled */
3350 /* just verify that callout device is not active */ 3342 /* just verify that callout device is not active */
3351 info->flags |= ASYNC_NORMAL_ACTIVE; 3343 info->port.flags |= ASYNC_NORMAL_ACTIVE;
3352 return 0; 3344 return 0;
3353 } 3345 }
3354 3346
@@ -3357,25 +3349,25 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
3357 3349
3358 /* Wait for carrier detect and the line to become 3350 /* Wait for carrier detect and the line to become
3359 * free (i.e., not in use by the callout). While we are in 3351 * free (i.e., not in use by the callout). While we are in
3360 * this loop, info->count is dropped by one, so that 3352 * this loop, info->port.count is dropped by one, so that
3361 * close() knows when to free things. We restore it upon 3353 * close() knows when to free things. We restore it upon
3362 * exit, either normal or abnormal. 3354 * exit, either normal or abnormal.
3363 */ 3355 */
3364 3356
3365 retval = 0; 3357 retval = 0;
3366 add_wait_queue(&info->open_wait, &wait); 3358 add_wait_queue(&info->port.open_wait, &wait);
3367 3359
3368 if (debug_level >= DEBUG_LEVEL_INFO) 3360 if (debug_level >= DEBUG_LEVEL_INFO)
3369 printk("%s(%d):%s block_til_ready() before block, count=%d\n", 3361 printk("%s(%d):%s block_til_ready() before block, count=%d\n",
3370 __FILE__,__LINE__, tty->driver->name, info->count ); 3362 __FILE__,__LINE__, tty->driver->name, info->port.count );
3371 3363
3372 spin_lock_irqsave(&info->lock, flags); 3364 spin_lock_irqsave(&info->lock, flags);
3373 if (!tty_hung_up_p(filp)) { 3365 if (!tty_hung_up_p(filp)) {
3374 extra_count = true; 3366 extra_count = true;
3375 info->count--; 3367 info->port.count--;
3376 } 3368 }
3377 spin_unlock_irqrestore(&info->lock, flags); 3369 spin_unlock_irqrestore(&info->lock, flags);
3378 info->blocked_open++; 3370 info->port.blocked_open++;
3379 3371
3380 while (1) { 3372 while (1) {
3381 if ((tty->termios->c_cflag & CBAUD)) { 3373 if ((tty->termios->c_cflag & CBAUD)) {
@@ -3387,8 +3379,8 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
3387 3379
3388 set_current_state(TASK_INTERRUPTIBLE); 3380 set_current_state(TASK_INTERRUPTIBLE);
3389 3381
3390 if (tty_hung_up_p(filp) || !(info->flags & ASYNC_INITIALIZED)){ 3382 if (tty_hung_up_p(filp) || !(info->port.flags & ASYNC_INITIALIZED)){
3391 retval = (info->flags & ASYNC_HUP_NOTIFY) ? 3383 retval = (info->port.flags & ASYNC_HUP_NOTIFY) ?
3392 -EAGAIN : -ERESTARTSYS; 3384 -EAGAIN : -ERESTARTSYS;
3393 break; 3385 break;
3394 } 3386 }
@@ -3397,7 +3389,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
3397 get_signals(info); 3389 get_signals(info);
3398 spin_unlock_irqrestore(&info->lock,flags); 3390 spin_unlock_irqrestore(&info->lock,flags);
3399 3391
3400 if (!(info->flags & ASYNC_CLOSING) && 3392 if (!(info->port.flags & ASYNC_CLOSING) &&
3401 (do_clocal || (info->serial_signals & SerialSignal_DCD)) ) { 3393 (do_clocal || (info->serial_signals & SerialSignal_DCD)) ) {
3402 break; 3394 break;
3403 } 3395 }
@@ -3409,24 +3401,24 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
3409 3401
3410 if (debug_level >= DEBUG_LEVEL_INFO) 3402 if (debug_level >= DEBUG_LEVEL_INFO)
3411 printk("%s(%d):%s block_til_ready() count=%d\n", 3403 printk("%s(%d):%s block_til_ready() count=%d\n",
3412 __FILE__,__LINE__, tty->driver->name, info->count ); 3404 __FILE__,__LINE__, tty->driver->name, info->port.count );
3413 3405
3414 schedule(); 3406 schedule();
3415 } 3407 }
3416 3408
3417 set_current_state(TASK_RUNNING); 3409 set_current_state(TASK_RUNNING);
3418 remove_wait_queue(&info->open_wait, &wait); 3410 remove_wait_queue(&info->port.open_wait, &wait);
3419 3411
3420 if (extra_count) 3412 if (extra_count)
3421 info->count++; 3413 info->port.count++;
3422 info->blocked_open--; 3414 info->port.blocked_open--;
3423 3415
3424 if (debug_level >= DEBUG_LEVEL_INFO) 3416 if (debug_level >= DEBUG_LEVEL_INFO)
3425 printk("%s(%d):%s block_til_ready() after, count=%d\n", 3417 printk("%s(%d):%s block_til_ready() after, count=%d\n",
3426 __FILE__,__LINE__, tty->driver->name, info->count ); 3418 __FILE__,__LINE__, tty->driver->name, info->port.count );
3427 3419
3428 if (!retval) 3420 if (!retval)
3429 info->flags |= ASYNC_NORMAL_ACTIVE; 3421 info->port.flags |= ASYNC_NORMAL_ACTIVE;
3430 3422
3431 return retval; 3423 return retval;
3432} 3424}
@@ -3808,13 +3800,12 @@ static SLMP_INFO *alloc_dev(int adapter_num, int port_num, struct pci_dev *pdev)
3808 printk("%s(%d) Error can't allocate device instance data for adapter %d, port %d\n", 3800 printk("%s(%d) Error can't allocate device instance data for adapter %d, port %d\n",
3809 __FILE__,__LINE__, adapter_num, port_num); 3801 __FILE__,__LINE__, adapter_num, port_num);
3810 } else { 3802 } else {
3803 tty_port_init(&info->port);
3811 info->magic = MGSL_MAGIC; 3804 info->magic = MGSL_MAGIC;
3812 INIT_WORK(&info->task, bh_handler); 3805 INIT_WORK(&info->task, bh_handler);
3813 info->max_frame_size = 4096; 3806 info->max_frame_size = 4096;
3814 info->close_delay = 5*HZ/10; 3807 info->port.close_delay = 5*HZ/10;
3815 info->closing_wait = 30*HZ; 3808 info->port.closing_wait = 30*HZ;
3816 init_waitqueue_head(&info->open_wait);
3817 init_waitqueue_head(&info->close_wait);
3818 init_waitqueue_head(&info->status_event_wait_q); 3809 init_waitqueue_head(&info->status_event_wait_q);
3819 init_waitqueue_head(&info->event_wait_q); 3810 init_waitqueue_head(&info->event_wait_q);
3820 spin_lock_init(&info->netlock); 3811 spin_lock_init(&info->netlock);
@@ -4885,7 +4876,7 @@ static bool rx_get_frame(SLMP_INFO *info)
4885 unsigned int framesize = 0; 4876 unsigned int framesize = 0;
4886 bool ReturnCode = false; 4877 bool ReturnCode = false;
4887 unsigned long flags; 4878 unsigned long flags;
4888 struct tty_struct *tty = info->tty; 4879 struct tty_struct *tty = info->port.tty;
4889 unsigned char addr_field = 0xff; 4880 unsigned char addr_field = 0xff;
4890 SCADESC *desc; 4881 SCADESC *desc;
4891 SCADESC_EX *desc_ex; 4882 SCADESC_EX *desc_ex;
@@ -4983,9 +4974,8 @@ CheckAgain:
4983 framesize = 0; 4974 framesize = 0;
4984#if SYNCLINK_GENERIC_HDLC 4975#if SYNCLINK_GENERIC_HDLC
4985 { 4976 {
4986 struct net_device_stats *stats = hdlc_stats(info->netdev); 4977 info->netdev->stats.rx_errors++;
4987 stats->rx_errors++; 4978 info->netdev->stats.rx_frame_errors++;
4988 stats->rx_frame_errors++;
4989 } 4979 }
4990#endif 4980#endif
4991 } 4981 }
@@ -5293,11 +5283,11 @@ static bool loopback_test(SLMP_INFO *info)
5293 bool rc = false; 5283 bool rc = false;
5294 unsigned long flags; 5284 unsigned long flags;
5295 5285
5296 struct tty_struct *oldtty = info->tty; 5286 struct tty_struct *oldtty = info->port.tty;
5297 u32 speed = info->params.clock_speed; 5287 u32 speed = info->params.clock_speed;
5298 5288
5299 info->params.clock_speed = 3686400; 5289 info->params.clock_speed = 3686400;
5300 info->tty = NULL; 5290 info->port.tty = NULL;
5301 5291
5302 /* assume failure */ 5292 /* assume failure */
5303 info->init_error = DiagStatus_DmaFailure; 5293 info->init_error = DiagStatus_DmaFailure;
@@ -5341,7 +5331,7 @@ static bool loopback_test(SLMP_INFO *info)
5341 spin_unlock_irqrestore(&info->lock,flags); 5331 spin_unlock_irqrestore(&info->lock,flags);
5342 5332
5343 info->params.clock_speed = speed; 5333 info->params.clock_speed = speed;
5344 info->tty = oldtty; 5334 info->port.tty = oldtty;
5345 5335
5346 return rc; 5336 return rc;
5347} 5337}
diff --git a/drivers/char/sysrq.c b/drivers/char/sysrq.c
index 9e9bad8bdcf4..8fdfe9c871e3 100644
--- a/drivers/char/sysrq.c
+++ b/drivers/char/sysrq.c
@@ -215,7 +215,7 @@ static void showacpu(void *dummy)
215 215
216static void sysrq_showregs_othercpus(struct work_struct *dummy) 216static void sysrq_showregs_othercpus(struct work_struct *dummy)
217{ 217{
218 smp_call_function(showacpu, NULL, 0, 0); 218 smp_call_function(showacpu, NULL, 0);
219} 219}
220 220
221static DECLARE_WORK(sysrq_showallcpus, sysrq_showregs_othercpus); 221static DECLARE_WORK(sysrq_showallcpus, sysrq_showregs_othercpus);
@@ -402,6 +402,7 @@ static struct sysrq_key_op *sysrq_key_table[36] = {
402 &sysrq_showstate_blocked_op, /* w */ 402 &sysrq_showstate_blocked_op, /* w */
403 /* x: May be registered on ppc/powerpc for xmon */ 403 /* x: May be registered on ppc/powerpc for xmon */
404 NULL, /* x */ 404 NULL, /* x */
405 /* y: May be registered on sparc64 for global register dump */
405 NULL, /* y */ 406 NULL, /* y */
406 NULL /* z */ 407 NULL /* z */
407}; 408};
diff --git a/drivers/char/tb0219.c b/drivers/char/tb0219.c
index 4c431cb7cf1b..6062b62800fd 100644
--- a/drivers/char/tb0219.c
+++ b/drivers/char/tb0219.c
@@ -21,6 +21,7 @@
21#include <linux/fs.h> 21#include <linux/fs.h>
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/module.h> 23#include <linux/module.h>
24#include <linux/smp_lock.h>
24 25
25#include <asm/io.h> 26#include <asm/io.h>
26#include <asm/reboot.h> 27#include <asm/reboot.h>
@@ -236,6 +237,7 @@ static int tanbac_tb0219_open(struct inode *inode, struct file *file)
236{ 237{
237 unsigned int minor; 238 unsigned int minor;
238 239
240 cycle_kernel_lock();
239 minor = iminor(inode); 241 minor = iminor(inode);
240 switch (minor) { 242 switch (minor) {
241 case 0: 243 case 0:
diff --git a/drivers/char/tlclk.c b/drivers/char/tlclk.c
index 35e58030d296..8f2284be68e1 100644
--- a/drivers/char/tlclk.c
+++ b/drivers/char/tlclk.c
@@ -36,6 +36,7 @@
36#include <linux/ioport.h> 36#include <linux/ioport.h>
37#include <linux/interrupt.h> 37#include <linux/interrupt.h>
38#include <linux/spinlock.h> 38#include <linux/spinlock.h>
39#include <linux/smp_lock.h>
39#include <linux/timer.h> 40#include <linux/timer.h>
40#include <linux/sysfs.h> 41#include <linux/sysfs.h>
41#include <linux/device.h> 42#include <linux/device.h>
@@ -204,11 +205,14 @@ static int tlclk_open(struct inode *inode, struct file *filp)
204{ 205{
205 int result; 206 int result;
206 207
207 if (test_and_set_bit(0, &useflags)) 208 lock_kernel();
208 return -EBUSY; 209 if (test_and_set_bit(0, &useflags)) {
210 result = -EBUSY;
209 /* this legacy device is always one per system and it doesn't 211 /* this legacy device is always one per system and it doesn't
210 * know how to handle multiple concurrent clients. 212 * know how to handle multiple concurrent clients.
211 */ 213 */
214 goto out;
215 }
212 216
213 /* Make sure there is no interrupt pending while 217 /* Make sure there is no interrupt pending while
214 * initialising interrupt handler */ 218 * initialising interrupt handler */
@@ -218,13 +222,14 @@ static int tlclk_open(struct inode *inode, struct file *filp)
218 * we can't share this IRQ */ 222 * we can't share this IRQ */
219 result = request_irq(telclk_interrupt, &tlclk_interrupt, 223 result = request_irq(telclk_interrupt, &tlclk_interrupt,
220 IRQF_DISABLED, "telco_clock", tlclk_interrupt); 224 IRQF_DISABLED, "telco_clock", tlclk_interrupt);
221 if (result == -EBUSY) { 225 if (result == -EBUSY)
222 printk(KERN_ERR "tlclk: Interrupt can't be reserved.\n"); 226 printk(KERN_ERR "tlclk: Interrupt can't be reserved.\n");
223 return -EBUSY; 227 else
224 } 228 inb(TLCLK_REG6); /* Clear interrupt events */
225 inb(TLCLK_REG6); /* Clear interrupt events */
226 229
227 return 0; 230out:
231 unlock_kernel();
232 return result;
228} 233}
229 234
230static int tlclk_release(struct inode *inode, struct file *filp) 235static int tlclk_release(struct inode *inode, struct file *filp)
diff --git a/drivers/char/tpm/tpm.c b/drivers/char/tpm/tpm.c
index a5d8bcb40000..e1fc193d9396 100644
--- a/drivers/char/tpm/tpm.c
+++ b/drivers/char/tpm/tpm.c
@@ -26,6 +26,7 @@
26#include <linux/poll.h> 26#include <linux/poll.h>
27#include <linux/mutex.h> 27#include <linux/mutex.h>
28#include <linux/spinlock.h> 28#include <linux/spinlock.h>
29#include <linux/smp_lock.h>
29 30
30#include "tpm.h" 31#include "tpm.h"
31 32
@@ -897,6 +898,7 @@ int tpm_open(struct inode *inode, struct file *file)
897 int rc = 0, minor = iminor(inode); 898 int rc = 0, minor = iminor(inode);
898 struct tpm_chip *chip = NULL, *pos; 899 struct tpm_chip *chip = NULL, *pos;
899 900
901 lock_kernel();
900 spin_lock(&driver_lock); 902 spin_lock(&driver_lock);
901 903
902 list_for_each_entry(pos, &tpm_chip_list, list) { 904 list_for_each_entry(pos, &tpm_chip_list, list) {
@@ -926,16 +928,19 @@ int tpm_open(struct inode *inode, struct file *file)
926 if (chip->data_buffer == NULL) { 928 if (chip->data_buffer == NULL) {
927 chip->num_opens--; 929 chip->num_opens--;
928 put_device(chip->dev); 930 put_device(chip->dev);
931 unlock_kernel();
929 return -ENOMEM; 932 return -ENOMEM;
930 } 933 }
931 934
932 atomic_set(&chip->data_pending, 0); 935 atomic_set(&chip->data_pending, 0);
933 936
934 file->private_data = chip; 937 file->private_data = chip;
938 unlock_kernel();
935 return 0; 939 return 0;
936 940
937err_out: 941err_out:
938 spin_unlock(&driver_lock); 942 spin_unlock(&driver_lock);
943 unlock_kernel();
939 return rc; 944 return rc;
940} 945}
941EXPORT_SYMBOL_GPL(tpm_open); 946EXPORT_SYMBOL_GPL(tpm_open);
diff --git a/drivers/char/tpm/tpm_tis.c b/drivers/char/tpm/tpm_tis.c
index 13a4bdd4e4d6..c7a977bc03e8 100644
--- a/drivers/char/tpm/tpm_tis.c
+++ b/drivers/char/tpm/tpm_tis.c
@@ -623,6 +623,7 @@ static struct pnp_device_id tpm_pnp_tbl[] __devinitdata = {
623 {"IFX0102", 0}, /* Infineon */ 623 {"IFX0102", 0}, /* Infineon */
624 {"BCM0101", 0}, /* Broadcom */ 624 {"BCM0101", 0}, /* Broadcom */
625 {"NSC1200", 0}, /* National */ 625 {"NSC1200", 0}, /* National */
626 {"ICO0102", 0}, /* Intel */
626 /* Add new here */ 627 /* Add new here */
627 {"", 0}, /* User Specified */ 628 {"", 0}, /* User Specified */
628 {"", 0} /* Terminator */ 629 {"", 0} /* Terminator */
diff --git a/drivers/char/tty_io.c b/drivers/char/tty_io.c
index e94bee032314..82f6a8c86332 100644
--- a/drivers/char/tty_io.c
+++ b/drivers/char/tty_io.c
@@ -95,8 +95,9 @@
95#include <linux/wait.h> 95#include <linux/wait.h>
96#include <linux/bitops.h> 96#include <linux/bitops.h>
97#include <linux/delay.h> 97#include <linux/delay.h>
98#include <linux/seq_file.h>
98 99
99#include <asm/uaccess.h> 100#include <linux/uaccess.h>
100#include <asm/system.h> 101#include <asm/system.h>
101 102
102#include <linux/kbd_kern.h> 103#include <linux/kbd_kern.h>
@@ -682,7 +683,7 @@ static void tty_set_termios_ldisc(struct tty_struct *tty, int num)
682static DEFINE_SPINLOCK(tty_ldisc_lock); 683static DEFINE_SPINLOCK(tty_ldisc_lock);
683static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_wait); 684static DECLARE_WAIT_QUEUE_HEAD(tty_ldisc_wait);
684/* Line disc dispatch table */ 685/* Line disc dispatch table */
685static struct tty_ldisc tty_ldiscs[NR_LDISCS]; 686static struct tty_ldisc_ops *tty_ldiscs[NR_LDISCS];
686 687
687/** 688/**
688 * tty_register_ldisc - install a line discipline 689 * tty_register_ldisc - install a line discipline
@@ -697,7 +698,7 @@ static struct tty_ldisc tty_ldiscs[NR_LDISCS];
697 * takes tty_ldisc_lock to guard against ldisc races 698 * takes tty_ldisc_lock to guard against ldisc races
698 */ 699 */
699 700
700int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc) 701int tty_register_ldisc(int disc, struct tty_ldisc_ops *new_ldisc)
701{ 702{
702 unsigned long flags; 703 unsigned long flags;
703 int ret = 0; 704 int ret = 0;
@@ -706,10 +707,9 @@ int tty_register_ldisc(int disc, struct tty_ldisc *new_ldisc)
706 return -EINVAL; 707 return -EINVAL;
707 708
708 spin_lock_irqsave(&tty_ldisc_lock, flags); 709 spin_lock_irqsave(&tty_ldisc_lock, flags);
709 tty_ldiscs[disc] = *new_ldisc; 710 tty_ldiscs[disc] = new_ldisc;
710 tty_ldiscs[disc].num = disc; 711 new_ldisc->num = disc;
711 tty_ldiscs[disc].flags |= LDISC_FLAG_DEFINED; 712 new_ldisc->refcount = 0;
712 tty_ldiscs[disc].refcount = 0;
713 spin_unlock_irqrestore(&tty_ldisc_lock, flags); 713 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
714 714
715 return ret; 715 return ret;
@@ -737,19 +737,56 @@ int tty_unregister_ldisc(int disc)
737 return -EINVAL; 737 return -EINVAL;
738 738
739 spin_lock_irqsave(&tty_ldisc_lock, flags); 739 spin_lock_irqsave(&tty_ldisc_lock, flags);
740 if (tty_ldiscs[disc].refcount) 740 if (tty_ldiscs[disc]->refcount)
741 ret = -EBUSY; 741 ret = -EBUSY;
742 else 742 else
743 tty_ldiscs[disc].flags &= ~LDISC_FLAG_DEFINED; 743 tty_ldiscs[disc] = NULL;
744 spin_unlock_irqrestore(&tty_ldisc_lock, flags); 744 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
745 745
746 return ret; 746 return ret;
747} 747}
748EXPORT_SYMBOL(tty_unregister_ldisc); 748EXPORT_SYMBOL(tty_unregister_ldisc);
749 749
750
751/**
752 * tty_ldisc_try_get - try and reference an ldisc
753 * @disc: ldisc number
754 * @ld: tty ldisc structure to complete
755 *
756 * Attempt to open and lock a line discipline into place. Return
757 * the line discipline refcounted and assigned in ld. On an error
758 * report the error code back
759 */
760
761static int tty_ldisc_try_get(int disc, struct tty_ldisc *ld)
762{
763 unsigned long flags;
764 struct tty_ldisc_ops *ldops;
765 int err = -EINVAL;
766
767 spin_lock_irqsave(&tty_ldisc_lock, flags);
768 ld->ops = NULL;
769 ldops = tty_ldiscs[disc];
770 /* Check the entry is defined */
771 if (ldops) {
772 /* If the module is being unloaded we can't use it */
773 if (!try_module_get(ldops->owner))
774 err = -EAGAIN;
775 else {
776 /* lock it */
777 ldops->refcount++;
778 ld->ops = ldops;
779 err = 0;
780 }
781 }
782 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
783 return err;
784}
785
750/** 786/**
751 * tty_ldisc_get - take a reference to an ldisc 787 * tty_ldisc_get - take a reference to an ldisc
752 * @disc: ldisc number 788 * @disc: ldisc number
789 * @ld: tty line discipline structure to use
753 * 790 *
754 * Takes a reference to a line discipline. Deals with refcounts and 791 * Takes a reference to a line discipline. Deals with refcounts and
755 * module locking counts. Returns NULL if the discipline is not available. 792 * module locking counts. Returns NULL if the discipline is not available.
@@ -760,32 +797,20 @@ EXPORT_SYMBOL(tty_unregister_ldisc);
760 * takes tty_ldisc_lock to guard against ldisc races 797 * takes tty_ldisc_lock to guard against ldisc races
761 */ 798 */
762 799
763struct tty_ldisc *tty_ldisc_get(int disc) 800static int tty_ldisc_get(int disc, struct tty_ldisc *ld)
764{ 801{
765 unsigned long flags; 802 int err;
766 struct tty_ldisc *ld;
767 803
768 if (disc < N_TTY || disc >= NR_LDISCS) 804 if (disc < N_TTY || disc >= NR_LDISCS)
769 return NULL; 805 return -EINVAL;
770 806 err = tty_ldisc_try_get(disc, ld);
771 spin_lock_irqsave(&tty_ldisc_lock, flags); 807 if (err == -EAGAIN) {
772 808 request_module("tty-ldisc-%d", disc);
773 ld = &tty_ldiscs[disc]; 809 err = tty_ldisc_try_get(disc, ld);
774 /* Check the entry is defined */ 810 }
775 if (ld->flags & LDISC_FLAG_DEFINED) { 811 return err;
776 /* If the module is being unloaded we can't use it */
777 if (!try_module_get(ld->owner))
778 ld = NULL;
779 else /* lock it */
780 ld->refcount++;
781 } else
782 ld = NULL;
783 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
784 return ld;
785} 812}
786 813
787EXPORT_SYMBOL_GPL(tty_ldisc_get);
788
789/** 814/**
790 * tty_ldisc_put - drop ldisc reference 815 * tty_ldisc_put - drop ldisc reference
791 * @disc: ldisc number 816 * @disc: ldisc number
@@ -797,22 +822,67 @@ EXPORT_SYMBOL_GPL(tty_ldisc_get);
797 * takes tty_ldisc_lock to guard against ldisc races 822 * takes tty_ldisc_lock to guard against ldisc races
798 */ 823 */
799 824
800void tty_ldisc_put(int disc) 825static void tty_ldisc_put(struct tty_ldisc_ops *ld)
801{ 826{
802 struct tty_ldisc *ld;
803 unsigned long flags; 827 unsigned long flags;
828 int disc = ld->num;
804 829
805 BUG_ON(disc < N_TTY || disc >= NR_LDISCS); 830 BUG_ON(disc < N_TTY || disc >= NR_LDISCS);
806 831
807 spin_lock_irqsave(&tty_ldisc_lock, flags); 832 spin_lock_irqsave(&tty_ldisc_lock, flags);
808 ld = &tty_ldiscs[disc]; 833 ld = tty_ldiscs[disc];
809 BUG_ON(ld->refcount == 0); 834 BUG_ON(ld->refcount == 0);
810 ld->refcount--; 835 ld->refcount--;
811 module_put(ld->owner); 836 module_put(ld->owner);
812 spin_unlock_irqrestore(&tty_ldisc_lock, flags); 837 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
813} 838}
814 839
815EXPORT_SYMBOL_GPL(tty_ldisc_put); 840static void * tty_ldiscs_seq_start(struct seq_file *m, loff_t *pos)
841{
842 return (*pos < NR_LDISCS) ? pos : NULL;
843}
844
845static void * tty_ldiscs_seq_next(struct seq_file *m, void *v, loff_t *pos)
846{
847 (*pos)++;
848 return (*pos < NR_LDISCS) ? pos : NULL;
849}
850
851static void tty_ldiscs_seq_stop(struct seq_file *m, void *v)
852{
853}
854
855static int tty_ldiscs_seq_show(struct seq_file *m, void *v)
856{
857 int i = *(loff_t *)v;
858 struct tty_ldisc ld;
859
860 if (tty_ldisc_get(i, &ld) < 0)
861 return 0;
862 seq_printf(m, "%-10s %2d\n", ld.ops->name ? ld.ops->name : "???", i);
863 tty_ldisc_put(ld.ops);
864 return 0;
865}
866
867static const struct seq_operations tty_ldiscs_seq_ops = {
868 .start = tty_ldiscs_seq_start,
869 .next = tty_ldiscs_seq_next,
870 .stop = tty_ldiscs_seq_stop,
871 .show = tty_ldiscs_seq_show,
872};
873
874static int proc_tty_ldiscs_open(struct inode *inode, struct file *file)
875{
876 return seq_open(file, &tty_ldiscs_seq_ops);
877}
878
879const struct file_operations tty_ldiscs_proc_fops = {
880 .owner = THIS_MODULE,
881 .open = proc_tty_ldiscs_open,
882 .read = seq_read,
883 .llseek = seq_lseek,
884 .release = seq_release,
885};
816 886
817/** 887/**
818 * tty_ldisc_assign - set ldisc on a tty 888 * tty_ldisc_assign - set ldisc on a tty
@@ -829,8 +899,8 @@ EXPORT_SYMBOL_GPL(tty_ldisc_put);
829 899
830static void tty_ldisc_assign(struct tty_struct *tty, struct tty_ldisc *ld) 900static void tty_ldisc_assign(struct tty_struct *tty, struct tty_ldisc *ld)
831{ 901{
902 ld->refcount = 0;
832 tty->ldisc = *ld; 903 tty->ldisc = *ld;
833 tty->ldisc.refcount = 0;
834} 904}
835 905
836/** 906/**
@@ -954,6 +1024,41 @@ static void tty_ldisc_enable(struct tty_struct *tty)
954} 1024}
955 1025
956/** 1026/**
1027 * tty_ldisc_restore - helper for tty ldisc change
1028 * @tty: tty to recover
1029 * @old: previous ldisc
1030 *
1031 * Restore the previous line discipline or N_TTY when a line discipline
1032 * change fails due to an open error
1033 */
1034
1035static void tty_ldisc_restore(struct tty_struct *tty, struct tty_ldisc *old)
1036{
1037 char buf[64];
1038 struct tty_ldisc new_ldisc;
1039
1040 /* There is an outstanding reference here so this is safe */
1041 tty_ldisc_get(old->ops->num, old);
1042 tty_ldisc_assign(tty, old);
1043 tty_set_termios_ldisc(tty, old->ops->num);
1044 if (old->ops->open && (old->ops->open(tty) < 0)) {
1045 tty_ldisc_put(old->ops);
1046 /* This driver is always present */
1047 if (tty_ldisc_get(N_TTY, &new_ldisc) < 0)
1048 panic("n_tty: get");
1049 tty_ldisc_assign(tty, &new_ldisc);
1050 tty_set_termios_ldisc(tty, N_TTY);
1051 if (new_ldisc.ops->open) {
1052 int r = new_ldisc.ops->open(tty);
1053 if (r < 0)
1054 panic("Couldn't open N_TTY ldisc for "
1055 "%s --- error %d.",
1056 tty_name(tty, buf), r);
1057 }
1058 }
1059}
1060
1061/**
957 * tty_set_ldisc - set line discipline 1062 * tty_set_ldisc - set line discipline
958 * @tty: the terminal to set 1063 * @tty: the terminal to set
959 * @ldisc: the line discipline 1064 * @ldisc: the line discipline
@@ -967,28 +1072,18 @@ static void tty_ldisc_enable(struct tty_struct *tty)
967 1072
968static int tty_set_ldisc(struct tty_struct *tty, int ldisc) 1073static int tty_set_ldisc(struct tty_struct *tty, int ldisc)
969{ 1074{
970 int retval = 0; 1075 int retval;
971 struct tty_ldisc o_ldisc; 1076 struct tty_ldisc o_ldisc, new_ldisc;
972 char buf[64];
973 int work; 1077 int work;
974 unsigned long flags; 1078 unsigned long flags;
975 struct tty_ldisc *ld;
976 struct tty_struct *o_tty; 1079 struct tty_struct *o_tty;
977 1080
978 if ((ldisc < N_TTY) || (ldisc >= NR_LDISCS))
979 return -EINVAL;
980
981restart: 1081restart:
982 1082 /* This is a bit ugly for now but means we can break the 'ldisc
983 ld = tty_ldisc_get(ldisc); 1083 is part of the tty struct' assumption later */
984 /* Eduardo Blanco <ejbs@cs.cs.com.uy> */ 1084 retval = tty_ldisc_get(ldisc, &new_ldisc);
985 /* Cyrus Durgin <cider@speakeasy.org> */ 1085 if (retval)
986 if (ld == NULL) { 1086 return retval;
987 request_module("tty-ldisc-%d", ldisc);
988 ld = tty_ldisc_get(ldisc);
989 }
990 if (ld == NULL)
991 return -EINVAL;
992 1087
993 /* 1088 /*
994 * Problem: What do we do if this blocks ? 1089 * Problem: What do we do if this blocks ?
@@ -996,8 +1091,8 @@ restart:
996 1091
997 tty_wait_until_sent(tty, 0); 1092 tty_wait_until_sent(tty, 0);
998 1093
999 if (tty->ldisc.num == ldisc) { 1094 if (tty->ldisc.ops->num == ldisc) {
1000 tty_ldisc_put(ldisc); 1095 tty_ldisc_put(new_ldisc.ops);
1001 return 0; 1096 return 0;
1002 } 1097 }
1003 1098
@@ -1024,7 +1119,7 @@ restart:
1024 /* Free the new ldisc we grabbed. Must drop the lock 1119 /* Free the new ldisc we grabbed. Must drop the lock
1025 first. */ 1120 first. */
1026 spin_unlock_irqrestore(&tty_ldisc_lock, flags); 1121 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
1027 tty_ldisc_put(ldisc); 1122 tty_ldisc_put(o_ldisc.ops);
1028 /* 1123 /*
1029 * There are several reasons we may be busy, including 1124 * There are several reasons we may be busy, including
1030 * random momentary I/O traffic. We must therefore 1125 * random momentary I/O traffic. We must therefore
@@ -1038,7 +1133,7 @@ restart:
1038 } 1133 }
1039 if (o_tty && o_tty->ldisc.refcount) { 1134 if (o_tty && o_tty->ldisc.refcount) {
1040 spin_unlock_irqrestore(&tty_ldisc_lock, flags); 1135 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
1041 tty_ldisc_put(ldisc); 1136 tty_ldisc_put(o_tty->ldisc.ops);
1042 if (wait_event_interruptible(tty_ldisc_wait, o_tty->ldisc.refcount == 0) < 0) 1137 if (wait_event_interruptible(tty_ldisc_wait, o_tty->ldisc.refcount == 0) < 0)
1043 return -ERESTARTSYS; 1138 return -ERESTARTSYS;
1044 goto restart; 1139 goto restart;
@@ -1049,8 +1144,9 @@ restart:
1049 * another ldisc change 1144 * another ldisc change
1050 */ 1145 */
1051 if (!test_bit(TTY_LDISC, &tty->flags)) { 1146 if (!test_bit(TTY_LDISC, &tty->flags)) {
1147 struct tty_ldisc *ld;
1052 spin_unlock_irqrestore(&tty_ldisc_lock, flags); 1148 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
1053 tty_ldisc_put(ldisc); 1149 tty_ldisc_put(new_ldisc.ops);
1054 ld = tty_ldisc_ref_wait(tty); 1150 ld = tty_ldisc_ref_wait(tty);
1055 tty_ldisc_deref(ld); 1151 tty_ldisc_deref(ld);
1056 goto restart; 1152 goto restart;
@@ -1060,7 +1156,7 @@ restart:
1060 if (o_tty) 1156 if (o_tty)
1061 clear_bit(TTY_LDISC, &o_tty->flags); 1157 clear_bit(TTY_LDISC, &o_tty->flags);
1062 spin_unlock_irqrestore(&tty_ldisc_lock, flags); 1158 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
1063 1159
1064 /* 1160 /*
1065 * From this point on we know nobody has an ldisc 1161 * From this point on we know nobody has an ldisc
1066 * usage reference, nor can they obtain one until 1162 * usage reference, nor can they obtain one until
@@ -1070,45 +1166,30 @@ restart:
1070 work = cancel_delayed_work(&tty->buf.work); 1166 work = cancel_delayed_work(&tty->buf.work);
1071 /* 1167 /*
1072 * Wait for ->hangup_work and ->buf.work handlers to terminate 1168 * Wait for ->hangup_work and ->buf.work handlers to terminate
1169 * MUST NOT hold locks here.
1073 */ 1170 */
1074 flush_scheduled_work(); 1171 flush_scheduled_work();
1075 /* Shutdown the current discipline. */ 1172 /* Shutdown the current discipline. */
1076 if (tty->ldisc.close) 1173 if (o_ldisc.ops->close)
1077 (tty->ldisc.close)(tty); 1174 (o_ldisc.ops->close)(tty);
1078 1175
1079 /* Now set up the new line discipline. */ 1176 /* Now set up the new line discipline. */
1080 tty_ldisc_assign(tty, ld); 1177 tty_ldisc_assign(tty, &new_ldisc);
1081 tty_set_termios_ldisc(tty, ldisc); 1178 tty_set_termios_ldisc(tty, ldisc);
1082 if (tty->ldisc.open) 1179 if (new_ldisc.ops->open)
1083 retval = (tty->ldisc.open)(tty); 1180 retval = (new_ldisc.ops->open)(tty);
1084 if (retval < 0) { 1181 if (retval < 0) {
1085 tty_ldisc_put(ldisc); 1182 tty_ldisc_put(new_ldisc.ops);
1086 /* There is an outstanding reference here so this is safe */ 1183 tty_ldisc_restore(tty, &o_ldisc);
1087 tty_ldisc_assign(tty, tty_ldisc_get(o_ldisc.num));
1088 tty_set_termios_ldisc(tty, tty->ldisc.num);
1089 if (tty->ldisc.open && (tty->ldisc.open(tty) < 0)) {
1090 tty_ldisc_put(o_ldisc.num);
1091 /* This driver is always present */
1092 tty_ldisc_assign(tty, tty_ldisc_get(N_TTY));
1093 tty_set_termios_ldisc(tty, N_TTY);
1094 if (tty->ldisc.open) {
1095 int r = tty->ldisc.open(tty);
1096
1097 if (r < 0)
1098 panic("Couldn't open N_TTY ldisc for "
1099 "%s --- error %d.",
1100 tty_name(tty, buf), r);
1101 }
1102 }
1103 } 1184 }
1104 /* At this point we hold a reference to the new ldisc and a 1185 /* At this point we hold a reference to the new ldisc and a
1105 a reference to the old ldisc. If we ended up flipping back 1186 a reference to the old ldisc. If we ended up flipping back
1106 to the existing ldisc we have two references to it */ 1187 to the existing ldisc we have two references to it */
1107 1188
1108 if (tty->ldisc.num != o_ldisc.num && tty->ops->set_ldisc) 1189 if (tty->ldisc.ops->num != o_ldisc.ops->num && tty->ops->set_ldisc)
1109 tty->ops->set_ldisc(tty); 1190 tty->ops->set_ldisc(tty);
1110 1191
1111 tty_ldisc_put(o_ldisc.num); 1192 tty_ldisc_put(o_ldisc.ops);
1112 1193
1113 /* 1194 /*
1114 * Allow ldisc referencing to occur as soon as the driver 1195 * Allow ldisc referencing to occur as soon as the driver
@@ -1335,8 +1416,8 @@ void tty_wakeup(struct tty_struct *tty)
1335 if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) { 1416 if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) {
1336 ld = tty_ldisc_ref(tty); 1417 ld = tty_ldisc_ref(tty);
1337 if (ld) { 1418 if (ld) {
1338 if (ld->write_wakeup) 1419 if (ld->ops->write_wakeup)
1339 ld->write_wakeup(tty); 1420 ld->ops->write_wakeup(tty);
1340 tty_ldisc_deref(ld); 1421 tty_ldisc_deref(ld);
1341 } 1422 }
1342 } 1423 }
@@ -1357,8 +1438,8 @@ void tty_ldisc_flush(struct tty_struct *tty)
1357{ 1438{
1358 struct tty_ldisc *ld = tty_ldisc_ref(tty); 1439 struct tty_ldisc *ld = tty_ldisc_ref(tty);
1359 if (ld) { 1440 if (ld) {
1360 if (ld->flush_buffer) 1441 if (ld->ops->flush_buffer)
1361 ld->flush_buffer(tty); 1442 ld->ops->flush_buffer(tty);
1362 tty_ldisc_deref(ld); 1443 tty_ldisc_deref(ld);
1363 } 1444 }
1364 tty_buffer_flush(tty); 1445 tty_buffer_flush(tty);
@@ -1386,7 +1467,7 @@ static void tty_reset_termios(struct tty_struct *tty)
1386 * do_tty_hangup - actual handler for hangup events 1467 * do_tty_hangup - actual handler for hangup events
1387 * @work: tty device 1468 * @work: tty device
1388 * 1469 *
1389 * This can be called by the "eventd" kernel thread. That is process 1470k * This can be called by the "eventd" kernel thread. That is process
1390 * synchronous but doesn't hold any locks, so we need to make sure we 1471 * synchronous but doesn't hold any locks, so we need to make sure we
1391 * have the appropriate locks for what we're doing. 1472 * have the appropriate locks for what we're doing.
1392 * 1473 *
@@ -1449,14 +1530,14 @@ static void do_tty_hangup(struct work_struct *work)
1449 ld = tty_ldisc_ref(tty); 1530 ld = tty_ldisc_ref(tty);
1450 if (ld != NULL) { 1531 if (ld != NULL) {
1451 /* We may have no line discipline at this point */ 1532 /* We may have no line discipline at this point */
1452 if (ld->flush_buffer) 1533 if (ld->ops->flush_buffer)
1453 ld->flush_buffer(tty); 1534 ld->ops->flush_buffer(tty);
1454 tty_driver_flush_buffer(tty); 1535 tty_driver_flush_buffer(tty);
1455 if ((test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) && 1536 if ((test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags)) &&
1456 ld->write_wakeup) 1537 ld->ops->write_wakeup)
1457 ld->write_wakeup(tty); 1538 ld->ops->write_wakeup(tty);
1458 if (ld->hangup) 1539 if (ld->ops->hangup)
1459 ld->hangup(tty); 1540 ld->ops->hangup(tty);
1460 } 1541 }
1461 /* 1542 /*
1462 * FIXME: Once we trust the LDISC code better we can wait here for 1543 * FIXME: Once we trust the LDISC code better we can wait here for
@@ -1825,8 +1906,8 @@ static ssize_t tty_read(struct file *file, char __user *buf, size_t count,
1825 /* We want to wait for the line discipline to sort out in this 1906 /* We want to wait for the line discipline to sort out in this
1826 situation */ 1907 situation */
1827 ld = tty_ldisc_ref_wait(tty); 1908 ld = tty_ldisc_ref_wait(tty);
1828 if (ld->read) 1909 if (ld->ops->read)
1829 i = (ld->read)(tty, file, buf, count); 1910 i = (ld->ops->read)(tty, file, buf, count);
1830 else 1911 else
1831 i = -EIO; 1912 i = -EIO;
1832 tty_ldisc_deref(ld); 1913 tty_ldisc_deref(ld);
@@ -1978,10 +2059,10 @@ static ssize_t tty_write(struct file *file, const char __user *buf,
1978 printk(KERN_ERR "tty driver %s lacks a write_room method.\n", 2059 printk(KERN_ERR "tty driver %s lacks a write_room method.\n",
1979 tty->driver->name); 2060 tty->driver->name);
1980 ld = tty_ldisc_ref_wait(tty); 2061 ld = tty_ldisc_ref_wait(tty);
1981 if (!ld->write) 2062 if (!ld->ops->write)
1982 ret = -EIO; 2063 ret = -EIO;
1983 else 2064 else
1984 ret = do_tty_write(ld->write, tty, file, buf, count); 2065 ret = do_tty_write(ld->ops->write, tty, file, buf, count);
1985 tty_ldisc_deref(ld); 2066 tty_ldisc_deref(ld);
1986 return ret; 2067 return ret;
1987} 2068}
@@ -2007,6 +2088,42 @@ ssize_t redirected_tty_write(struct file *file, const char __user *buf,
2007 return tty_write(file, buf, count, ppos); 2088 return tty_write(file, buf, count, ppos);
2008} 2089}
2009 2090
2091void tty_port_init(struct tty_port *port)
2092{
2093 memset(port, 0, sizeof(*port));
2094 init_waitqueue_head(&port->open_wait);
2095 init_waitqueue_head(&port->close_wait);
2096 mutex_init(&port->mutex);
2097 port->close_delay = (50 * HZ) / 100;
2098 port->closing_wait = (3000 * HZ) / 100;
2099}
2100EXPORT_SYMBOL(tty_port_init);
2101
2102int tty_port_alloc_xmit_buf(struct tty_port *port)
2103{
2104 /* We may sleep in get_zeroed_page() */
2105 mutex_lock(&port->mutex);
2106 if (port->xmit_buf == NULL)
2107 port->xmit_buf = (unsigned char *)get_zeroed_page(GFP_KERNEL);
2108 mutex_unlock(&port->mutex);
2109 if (port->xmit_buf == NULL)
2110 return -ENOMEM;
2111 return 0;
2112}
2113EXPORT_SYMBOL(tty_port_alloc_xmit_buf);
2114
2115void tty_port_free_xmit_buf(struct tty_port *port)
2116{
2117 mutex_lock(&port->mutex);
2118 if (port->xmit_buf != NULL) {
2119 free_page((unsigned long)port->xmit_buf);
2120 port->xmit_buf = NULL;
2121 }
2122 mutex_unlock(&port->mutex);
2123}
2124EXPORT_SYMBOL(tty_port_free_xmit_buf);
2125
2126
2010static char ptychar[] = "pqrstuvwxyzabcde"; 2127static char ptychar[] = "pqrstuvwxyzabcde";
2011 2128
2012/** 2129/**
@@ -2076,6 +2193,7 @@ static int init_dev(struct tty_driver *driver, int idx,
2076 struct ktermios *tp, **tp_loc, *o_tp, **o_tp_loc; 2193 struct ktermios *tp, **tp_loc, *o_tp, **o_tp_loc;
2077 struct ktermios *ltp, **ltp_loc, *o_ltp, **o_ltp_loc; 2194 struct ktermios *ltp, **ltp_loc, *o_ltp, **o_ltp_loc;
2078 int retval = 0; 2195 int retval = 0;
2196 struct tty_ldisc *ld;
2079 2197
2080 /* check whether we're reopening an existing tty */ 2198 /* check whether we're reopening an existing tty */
2081 if (driver->flags & TTY_DRIVER_DEVPTS_MEM) { 2199 if (driver->flags & TTY_DRIVER_DEVPTS_MEM) {
@@ -2224,17 +2342,19 @@ static int init_dev(struct tty_driver *driver, int idx,
2224 * If we fail here just call release_tty to clean up. No need 2342 * If we fail here just call release_tty to clean up. No need
2225 * to decrement the use counts, as release_tty doesn't care. 2343 * to decrement the use counts, as release_tty doesn't care.
2226 */ 2344 */
2345
2346 ld = &tty->ldisc;
2227 2347
2228 if (tty->ldisc.open) { 2348 if (ld->ops->open) {
2229 retval = (tty->ldisc.open)(tty); 2349 retval = (ld->ops->open)(tty);
2230 if (retval) 2350 if (retval)
2231 goto release_mem_out; 2351 goto release_mem_out;
2232 } 2352 }
2233 if (o_tty && o_tty->ldisc.open) { 2353 if (o_tty && o_tty->ldisc.ops->open) {
2234 retval = (o_tty->ldisc.open)(o_tty); 2354 retval = (o_tty->ldisc.ops->open)(o_tty);
2235 if (retval) { 2355 if (retval) {
2236 if (tty->ldisc.close) 2356 if (ld->ops->close)
2237 (tty->ldisc.close)(tty); 2357 (ld->ops->close)(tty);
2238 goto release_mem_out; 2358 goto release_mem_out;
2239 } 2359 }
2240 tty_ldisc_enable(o_tty); 2360 tty_ldisc_enable(o_tty);
@@ -2378,6 +2498,7 @@ static void release_tty(struct tty_struct *tty, int idx)
2378static void release_dev(struct file *filp) 2498static void release_dev(struct file *filp)
2379{ 2499{
2380 struct tty_struct *tty, *o_tty; 2500 struct tty_struct *tty, *o_tty;
2501 struct tty_ldisc ld;
2381 int pty_master, tty_closing, o_tty_closing, do_sleep; 2502 int pty_master, tty_closing, o_tty_closing, do_sleep;
2382 int devpts; 2503 int devpts;
2383 int idx; 2504 int idx;
@@ -2611,26 +2732,27 @@ static void release_dev(struct file *filp)
2611 spin_unlock_irqrestore(&tty_ldisc_lock, flags); 2732 spin_unlock_irqrestore(&tty_ldisc_lock, flags);
2612 /* 2733 /*
2613 * Shutdown the current line discipline, and reset it to N_TTY. 2734 * Shutdown the current line discipline, and reset it to N_TTY.
2614 * N.B. why reset ldisc when we're releasing the memory??
2615 * 2735 *
2616 * FIXME: this MUST get fixed for the new reflocking 2736 * FIXME: this MUST get fixed for the new reflocking
2617 */ 2737 */
2618 if (tty->ldisc.close) 2738 if (tty->ldisc.ops->close)
2619 (tty->ldisc.close)(tty); 2739 (tty->ldisc.ops->close)(tty);
2620 tty_ldisc_put(tty->ldisc.num); 2740 tty_ldisc_put(tty->ldisc.ops);
2621 2741
2622 /* 2742 /*
2623 * Switch the line discipline back 2743 * Switch the line discipline back
2624 */ 2744 */
2625 tty_ldisc_assign(tty, tty_ldisc_get(N_TTY)); 2745 WARN_ON(tty_ldisc_get(N_TTY, &ld));
2746 tty_ldisc_assign(tty, &ld);
2626 tty_set_termios_ldisc(tty, N_TTY); 2747 tty_set_termios_ldisc(tty, N_TTY);
2627 if (o_tty) { 2748 if (o_tty) {
2628 /* FIXME: could o_tty be in setldisc here ? */ 2749 /* FIXME: could o_tty be in setldisc here ? */
2629 clear_bit(TTY_LDISC, &o_tty->flags); 2750 clear_bit(TTY_LDISC, &o_tty->flags);
2630 if (o_tty->ldisc.close) 2751 if (o_tty->ldisc.ops->close)
2631 (o_tty->ldisc.close)(o_tty); 2752 (o_tty->ldisc.ops->close)(o_tty);
2632 tty_ldisc_put(o_tty->ldisc.num); 2753 tty_ldisc_put(o_tty->ldisc.ops);
2633 tty_ldisc_assign(o_tty, tty_ldisc_get(N_TTY)); 2754 WARN_ON(tty_ldisc_get(N_TTY, &ld));
2755 tty_ldisc_assign(o_tty, &ld);
2634 tty_set_termios_ldisc(o_tty, N_TTY); 2756 tty_set_termios_ldisc(o_tty, N_TTY);
2635 } 2757 }
2636 /* 2758 /*
@@ -2665,7 +2787,7 @@ static void release_dev(struct file *filp)
2665 * ->siglock protects ->signal/->sighand 2787 * ->siglock protects ->signal/->sighand
2666 */ 2788 */
2667 2789
2668static int tty_open(struct inode *inode, struct file *filp) 2790static int __tty_open(struct inode *inode, struct file *filp)
2669{ 2791{
2670 struct tty_struct *tty; 2792 struct tty_struct *tty;
2671 int noctty, retval; 2793 int noctty, retval;
@@ -2779,6 +2901,19 @@ got_driver:
2779 return 0; 2901 return 0;
2780} 2902}
2781 2903
2904/* BKL pushdown: scary code avoidance wrapper */
2905static int tty_open(struct inode *inode, struct file *filp)
2906{
2907 int ret;
2908
2909 lock_kernel();
2910 ret = __tty_open(inode, filp);
2911 unlock_kernel();
2912 return ret;
2913}
2914
2915
2916
2782#ifdef CONFIG_UNIX98_PTYS 2917#ifdef CONFIG_UNIX98_PTYS
2783/** 2918/**
2784 * ptmx_open - open a unix 98 pty master 2919 * ptmx_open - open a unix 98 pty master
@@ -2792,7 +2927,7 @@ got_driver:
2792 * allocated_ptys_lock handles the list of free pty numbers 2927 * allocated_ptys_lock handles the list of free pty numbers
2793 */ 2928 */
2794 2929
2795static int ptmx_open(struct inode *inode, struct file *filp) 2930static int __ptmx_open(struct inode *inode, struct file *filp)
2796{ 2931{
2797 struct tty_struct *tty; 2932 struct tty_struct *tty;
2798 int retval; 2933 int retval;
@@ -2831,6 +2966,16 @@ out:
2831 devpts_kill_index(index); 2966 devpts_kill_index(index);
2832 return retval; 2967 return retval;
2833} 2968}
2969
2970static int ptmx_open(struct inode *inode, struct file *filp)
2971{
2972 int ret;
2973
2974 lock_kernel();
2975 ret = __ptmx_open(inode, filp);
2976 unlock_kernel();
2977 return ret;
2978}
2834#endif 2979#endif
2835 2980
2836/** 2981/**
@@ -2876,8 +3021,8 @@ static unsigned int tty_poll(struct file *filp, poll_table *wait)
2876 return 0; 3021 return 0;
2877 3022
2878 ld = tty_ldisc_ref_wait(tty); 3023 ld = tty_ldisc_ref_wait(tty);
2879 if (ld->poll) 3024 if (ld->ops->poll)
2880 ret = (ld->poll)(tty, filp, wait); 3025 ret = (ld->ops->poll)(tty, filp, wait);
2881 tty_ldisc_deref(ld); 3026 tty_ldisc_deref(ld);
2882 return ret; 3027 return ret;
2883} 3028}
@@ -2886,15 +3031,16 @@ static int tty_fasync(int fd, struct file *filp, int on)
2886{ 3031{
2887 struct tty_struct *tty; 3032 struct tty_struct *tty;
2888 unsigned long flags; 3033 unsigned long flags;
2889 int retval; 3034 int retval = 0;
2890 3035
3036 lock_kernel();
2891 tty = (struct tty_struct *)filp->private_data; 3037 tty = (struct tty_struct *)filp->private_data;
2892 if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "tty_fasync")) 3038 if (tty_paranoia_check(tty, filp->f_path.dentry->d_inode, "tty_fasync"))
2893 return 0; 3039 goto out;
2894 3040
2895 retval = fasync_helper(fd, filp, on, &tty->fasync); 3041 retval = fasync_helper(fd, filp, on, &tty->fasync);
2896 if (retval <= 0) 3042 if (retval <= 0)
2897 return retval; 3043 goto out;
2898 3044
2899 if (on) { 3045 if (on) {
2900 enum pid_type type; 3046 enum pid_type type;
@@ -2912,12 +3058,15 @@ static int tty_fasync(int fd, struct file *filp, int on)
2912 spin_unlock_irqrestore(&tty->ctrl_lock, flags); 3058 spin_unlock_irqrestore(&tty->ctrl_lock, flags);
2913 retval = __f_setown(filp, pid, type, 0); 3059 retval = __f_setown(filp, pid, type, 0);
2914 if (retval) 3060 if (retval)
2915 return retval; 3061 goto out;
2916 } else { 3062 } else {
2917 if (!tty->fasync && !waitqueue_active(&tty->read_wait)) 3063 if (!tty->fasync && !waitqueue_active(&tty->read_wait))
2918 tty->minimum_to_wake = N_TTY_BUF_SIZE; 3064 tty->minimum_to_wake = N_TTY_BUF_SIZE;
2919 } 3065 }
2920 return 0; 3066 retval = 0;
3067out:
3068 unlock_kernel();
3069 return retval;
2921} 3070}
2922 3071
2923/** 3072/**
@@ -2947,7 +3096,7 @@ static int tiocsti(struct tty_struct *tty, char __user *p)
2947 if (get_user(ch, p)) 3096 if (get_user(ch, p))
2948 return -EFAULT; 3097 return -EFAULT;
2949 ld = tty_ldisc_ref_wait(tty); 3098 ld = tty_ldisc_ref_wait(tty);
2950 ld->receive_buf(tty, &ch, &mbz, 1); 3099 ld->ops->receive_buf(tty, &ch, &mbz, 1);
2951 tty_ldisc_deref(ld); 3100 tty_ldisc_deref(ld);
2952 return 0; 3101 return 0;
2953} 3102}
@@ -3322,7 +3471,7 @@ static int send_break(struct tty_struct *tty, unsigned int duration)
3322 msleep_interruptible(duration); 3471 msleep_interruptible(duration);
3323 tty->ops->break_ctl(tty, 0); 3472 tty->ops->break_ctl(tty, 0);
3324 tty_write_unlock(tty); 3473 tty_write_unlock(tty);
3325 if (!signal_pending(current)) 3474 if (signal_pending(current))
3326 return -EINTR; 3475 return -EINTR;
3327 return 0; 3476 return 0;
3328} 3477}
@@ -3368,35 +3517,31 @@ static int tty_tiocmget(struct tty_struct *tty, struct file *file, int __user *p
3368static int tty_tiocmset(struct tty_struct *tty, struct file *file, unsigned int cmd, 3517static int tty_tiocmset(struct tty_struct *tty, struct file *file, unsigned int cmd,
3369 unsigned __user *p) 3518 unsigned __user *p)
3370{ 3519{
3371 int retval = -EINVAL; 3520 int retval;
3372 3521 unsigned int set, clear, val;
3373 if (tty->ops->tiocmset) {
3374 unsigned int set, clear, val;
3375
3376 retval = get_user(val, p);
3377 if (retval)
3378 return retval;
3379
3380 set = clear = 0;
3381 switch (cmd) {
3382 case TIOCMBIS:
3383 set = val;
3384 break;
3385 case TIOCMBIC:
3386 clear = val;
3387 break;
3388 case TIOCMSET:
3389 set = val;
3390 clear = ~val;
3391 break;
3392 }
3393 3522
3394 set &= TIOCM_DTR|TIOCM_RTS|TIOCM_OUT1|TIOCM_OUT2|TIOCM_LOOP; 3523 if (tty->ops->tiocmset == NULL)
3395 clear &= TIOCM_DTR|TIOCM_RTS|TIOCM_OUT1|TIOCM_OUT2|TIOCM_LOOP; 3524 return -EINVAL;
3396 3525
3397 retval = tty->ops->tiocmset(tty, file, set, clear); 3526 retval = get_user(val, p);
3527 if (retval)
3528 return retval;
3529 set = clear = 0;
3530 switch (cmd) {
3531 case TIOCMBIS:
3532 set = val;
3533 break;
3534 case TIOCMBIC:
3535 clear = val;
3536 break;
3537 case TIOCMSET:
3538 set = val;
3539 clear = ~val;
3540 break;
3398 } 3541 }
3399 return retval; 3542 set &= TIOCM_DTR|TIOCM_RTS|TIOCM_OUT1|TIOCM_OUT2|TIOCM_LOOP;
3543 clear &= TIOCM_DTR|TIOCM_RTS|TIOCM_OUT1|TIOCM_OUT2|TIOCM_LOOP;
3544 return tty->ops->tiocmset(tty, file, set, clear);
3400} 3545}
3401 3546
3402/* 3547/*
@@ -3501,7 +3646,7 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
3501 case TIOCGSID: 3646 case TIOCGSID:
3502 return tiocgsid(tty, real_tty, p); 3647 return tiocgsid(tty, real_tty, p);
3503 case TIOCGETD: 3648 case TIOCGETD:
3504 return put_user(tty->ldisc.num, (int __user *)p); 3649 return put_user(tty->ldisc.ops->num, (int __user *)p);
3505 case TIOCSETD: 3650 case TIOCSETD:
3506 return tiocsetd(tty, p); 3651 return tiocsetd(tty, p);
3507#ifdef CONFIG_VT 3652#ifdef CONFIG_VT
@@ -3554,8 +3699,8 @@ long tty_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
3554 } 3699 }
3555 ld = tty_ldisc_ref_wait(tty); 3700 ld = tty_ldisc_ref_wait(tty);
3556 retval = -EINVAL; 3701 retval = -EINVAL;
3557 if (ld->ioctl) { 3702 if (ld->ops->ioctl) {
3558 retval = ld->ioctl(tty, file, cmd, arg); 3703 retval = ld->ops->ioctl(tty, file, cmd, arg);
3559 if (retval == -ENOIOCTLCMD) 3704 if (retval == -ENOIOCTLCMD)
3560 retval = -EINVAL; 3705 retval = -EINVAL;
3561 } 3706 }
@@ -3582,8 +3727,8 @@ static long tty_compat_ioctl(struct file *file, unsigned int cmd,
3582 } 3727 }
3583 3728
3584 ld = tty_ldisc_ref_wait(tty); 3729 ld = tty_ldisc_ref_wait(tty);
3585 if (ld->compat_ioctl) 3730 if (ld->ops->compat_ioctl)
3586 retval = ld->compat_ioctl(tty, file, cmd, arg); 3731 retval = ld->ops->compat_ioctl(tty, file, cmd, arg);
3587 tty_ldisc_deref(ld); 3732 tty_ldisc_deref(ld);
3588 3733
3589 return retval; 3734 return retval;
@@ -3755,7 +3900,8 @@ static void flush_to_ldisc(struct work_struct *work)
3755 flag_buf = head->flag_buf_ptr + head->read; 3900 flag_buf = head->flag_buf_ptr + head->read;
3756 head->read += count; 3901 head->read += count;
3757 spin_unlock_irqrestore(&tty->buf.lock, flags); 3902 spin_unlock_irqrestore(&tty->buf.lock, flags);
3758 disc->receive_buf(tty, char_buf, flag_buf, count); 3903 disc->ops->receive_buf(tty, char_buf,
3904 flag_buf, count);
3759 spin_lock_irqsave(&tty->buf.lock, flags); 3905 spin_lock_irqsave(&tty->buf.lock, flags);
3760 } 3906 }
3761 /* Restore the queue head */ 3907 /* Restore the queue head */
@@ -3816,9 +3962,12 @@ EXPORT_SYMBOL(tty_flip_buffer_push);
3816 3962
3817static void initialize_tty_struct(struct tty_struct *tty) 3963static void initialize_tty_struct(struct tty_struct *tty)
3818{ 3964{
3965 struct tty_ldisc ld;
3819 memset(tty, 0, sizeof(struct tty_struct)); 3966 memset(tty, 0, sizeof(struct tty_struct));
3820 tty->magic = TTY_MAGIC; 3967 tty->magic = TTY_MAGIC;
3821 tty_ldisc_assign(tty, tty_ldisc_get(N_TTY)); 3968 if (tty_ldisc_get(N_TTY, &ld) < 0)
3969 panic("n_tty: init_tty");
3970 tty_ldisc_assign(tty, &ld);
3822 tty->session = NULL; 3971 tty->session = NULL;
3823 tty->pgrp = NULL; 3972 tty->pgrp = NULL;
3824 tty->overrun_time = jiffies; 3973 tty->overrun_time = jiffies;
diff --git a/drivers/char/tty_ioctl.c b/drivers/char/tty_ioctl.c
index b1a757a5ee27..ea9fc5d03b99 100644
--- a/drivers/char/tty_ioctl.c
+++ b/drivers/char/tty_ioctl.c
@@ -491,8 +491,8 @@ static void change_termios(struct tty_struct *tty, struct ktermios *new_termios)
491 491
492 ld = tty_ldisc_ref(tty); 492 ld = tty_ldisc_ref(tty);
493 if (ld != NULL) { 493 if (ld != NULL) {
494 if (ld->set_termios) 494 if (ld->ops->set_termios)
495 (ld->set_termios)(tty, &old_termios); 495 (ld->ops->set_termios)(tty, &old_termios);
496 tty_ldisc_deref(ld); 496 tty_ldisc_deref(ld);
497 } 497 }
498 mutex_unlock(&tty->termios_mutex); 498 mutex_unlock(&tty->termios_mutex);
@@ -552,8 +552,8 @@ static int set_termios(struct tty_struct *tty, void __user *arg, int opt)
552 ld = tty_ldisc_ref(tty); 552 ld = tty_ldisc_ref(tty);
553 553
554 if (ld != NULL) { 554 if (ld != NULL) {
555 if ((opt & TERMIOS_FLUSH) && ld->flush_buffer) 555 if ((opt & TERMIOS_FLUSH) && ld->ops->flush_buffer)
556 ld->flush_buffer(tty); 556 ld->ops->flush_buffer(tty);
557 tty_ldisc_deref(ld); 557 tty_ldisc_deref(ld);
558 } 558 }
559 559
@@ -959,12 +959,12 @@ int tty_perform_flush(struct tty_struct *tty, unsigned long arg)
959 ld = tty_ldisc_ref(tty); 959 ld = tty_ldisc_ref(tty);
960 switch (arg) { 960 switch (arg) {
961 case TCIFLUSH: 961 case TCIFLUSH:
962 if (ld && ld->flush_buffer) 962 if (ld && ld->ops->flush_buffer)
963 ld->flush_buffer(tty); 963 ld->ops->flush_buffer(tty);
964 break; 964 break;
965 case TCIOFLUSH: 965 case TCIOFLUSH:
966 if (ld && ld->flush_buffer) 966 if (ld && ld->ops->flush_buffer)
967 ld->flush_buffer(tty); 967 ld->ops->flush_buffer(tty);
968 /* fall through */ 968 /* fall through */
969 case TCOFLUSH: 969 case TCOFLUSH:
970 tty_driver_flush_buffer(tty); 970 tty_driver_flush_buffer(tty);
@@ -981,16 +981,9 @@ EXPORT_SYMBOL_GPL(tty_perform_flush);
981int n_tty_ioctl(struct tty_struct *tty, struct file *file, 981int n_tty_ioctl(struct tty_struct *tty, struct file *file,
982 unsigned int cmd, unsigned long arg) 982 unsigned int cmd, unsigned long arg)
983{ 983{
984 struct tty_struct *real_tty;
985 unsigned long flags; 984 unsigned long flags;
986 int retval; 985 int retval;
987 986
988 if (tty->driver->type == TTY_DRIVER_TYPE_PTY &&
989 tty->driver->subtype == PTY_TYPE_MASTER)
990 real_tty = tty->link;
991 else
992 real_tty = tty;
993
994 switch (cmd) { 987 switch (cmd) {
995 case TCXONC: 988 case TCXONC:
996 retval = tty_check_change(tty); 989 retval = tty_check_change(tty);
diff --git a/drivers/char/vc_screen.c b/drivers/char/vc_screen.c
index 83aeedda200c..eebfad2777d2 100644
--- a/drivers/char/vc_screen.c
+++ b/drivers/char/vc_screen.c
@@ -34,6 +34,7 @@
34#include <linux/kbd_kern.h> 34#include <linux/kbd_kern.h>
35#include <linux/console.h> 35#include <linux/console.h>
36#include <linux/device.h> 36#include <linux/device.h>
37#include <linux/smp_lock.h>
37 38
38#include <asm/uaccess.h> 39#include <asm/uaccess.h>
39#include <asm/byteorder.h> 40#include <asm/byteorder.h>
@@ -460,9 +461,13 @@ static int
460vcs_open(struct inode *inode, struct file *filp) 461vcs_open(struct inode *inode, struct file *filp)
461{ 462{
462 unsigned int currcons = iminor(inode) & 127; 463 unsigned int currcons = iminor(inode) & 127;
464 int ret = 0;
465
466 lock_kernel();
463 if(currcons && !vc_cons_allocated(currcons-1)) 467 if(currcons && !vc_cons_allocated(currcons-1))
464 return -ENXIO; 468 ret = -ENXIO;
465 return 0; 469 unlock_kernel();
470 return ret;
466} 471}
467 472
468static const struct file_operations vcs_fops = { 473static const struct file_operations vcs_fops = {
diff --git a/drivers/char/viocons.c b/drivers/char/viocons.c
index 3d3e1c2b310f..65fb848e1cce 100644
--- a/drivers/char/viocons.c
+++ b/drivers/char/viocons.c
@@ -7,7 +7,7 @@
7 * Authors: Dave Boutcher <boutcher@us.ibm.com> 7 * Authors: Dave Boutcher <boutcher@us.ibm.com>
8 * Ryan Arnold <ryanarn@us.ibm.com> 8 * Ryan Arnold <ryanarn@us.ibm.com>
9 * Colin Devilbiss <devilbis@us.ibm.com> 9 * Colin Devilbiss <devilbis@us.ibm.com>
10 * Stephen Rothwell <sfr@au1.ibm.com> 10 * Stephen Rothwell
11 * 11 *
12 * (C) Copyright 2000, 2001, 2002, 2003, 2004 IBM Corporation 12 * (C) Copyright 2000, 2001, 2002, 2003, 2004 IBM Corporation
13 * 13 *
diff --git a/drivers/char/viotape.c b/drivers/char/viotape.c
index 58aad63831f4..e5da98d8f9cd 100644
--- a/drivers/char/viotape.c
+++ b/drivers/char/viotape.c
@@ -6,7 +6,7 @@
6 * Authors: Dave Boutcher <boutcher@us.ibm.com> 6 * Authors: Dave Boutcher <boutcher@us.ibm.com>
7 * Ryan Arnold <ryanarn@us.ibm.com> 7 * Ryan Arnold <ryanarn@us.ibm.com>
8 * Colin Devilbiss <devilbis@us.ibm.com> 8 * Colin Devilbiss <devilbis@us.ibm.com>
9 * Stephen Rothwell <sfr@au1.ibm.com> 9 * Stephen Rothwell
10 * 10 *
11 * (C) Copyright 2000-2004 IBM Corporation 11 * (C) Copyright 2000-2004 IBM Corporation
12 * 12 *
@@ -46,6 +46,7 @@
46#include <linux/completion.h> 46#include <linux/completion.h>
47#include <linux/proc_fs.h> 47#include <linux/proc_fs.h>
48#include <linux/seq_file.h> 48#include <linux/seq_file.h>
49#include <linux/smp_lock.h>
49 50
50#include <asm/uaccess.h> 51#include <asm/uaccess.h>
51#include <asm/ioctls.h> 52#include <asm/ioctls.h>
@@ -677,6 +678,17 @@ free_op:
677 return ret; 678 return ret;
678} 679}
679 680
681static long viotap_unlocked_ioctl(struct file *file,
682 unsigned int cmd, unsigned long arg)
683{
684 long rc;
685
686 lock_kernel();
687 rc = viotap_ioctl(file->f_path.dentry->d_inode, file, cmd, arg);
688 unlock_kernel();
689 return rc;
690}
691
680static int viotap_open(struct inode *inode, struct file *file) 692static int viotap_open(struct inode *inode, struct file *file)
681{ 693{
682 HvLpEvent_Rc hvrc; 694 HvLpEvent_Rc hvrc;
@@ -687,6 +699,7 @@ static int viotap_open(struct inode *inode, struct file *file)
687 if (op == NULL) 699 if (op == NULL)
688 return -ENOMEM; 700 return -ENOMEM;
689 701
702 lock_kernel();
690 get_dev_info(file->f_path.dentry->d_inode, &devi); 703 get_dev_info(file->f_path.dentry->d_inode, &devi);
691 704
692 /* Note: We currently only support one mode! */ 705 /* Note: We currently only support one mode! */
@@ -717,6 +730,7 @@ static int viotap_open(struct inode *inode, struct file *file)
717 730
718free_op: 731free_op:
719 free_op_struct(op); 732 free_op_struct(op);
733 unlock_kernel();
720 return ret; 734 return ret;
721} 735}
722 736
@@ -783,12 +797,12 @@ free_op:
783} 797}
784 798
785const struct file_operations viotap_fops = { 799const struct file_operations viotap_fops = {
786 .owner = THIS_MODULE, 800 .owner = THIS_MODULE,
787 .read = viotap_read, 801 .read = viotap_read,
788 .write = viotap_write, 802 .write = viotap_write,
789 .ioctl = viotap_ioctl, 803 .unlocked_ioctl = viotap_unlocked_ioctl,
790 .open = viotap_open, 804 .open = viotap_open,
791 .release = viotap_release, 805 .release = viotap_release,
792}; 806};
793 807
794/* Handle interrupt events for tape */ 808/* Handle interrupt events for tape */
diff --git a/drivers/char/vme_scc.c b/drivers/char/vme_scc.c
index e122a0e87bb0..f17ac043b551 100644
--- a/drivers/char/vme_scc.c
+++ b/drivers/char/vme_scc.c
@@ -89,9 +89,7 @@ static void scc_break_ctl(struct tty_struct *tty, int break_state);
89 89
90static struct tty_driver *scc_driver; 90static struct tty_driver *scc_driver;
91 91
92struct scc_port scc_ports[2]; 92static struct scc_port scc_ports[2];
93
94int scc_initialized = 0;
95 93
96/*--------------------------------------------------------------------------- 94/*---------------------------------------------------------------------------
97 * Interface from generic_serial.c back here 95 * Interface from generic_serial.c back here
diff --git a/drivers/char/vr41xx_giu.c b/drivers/char/vr41xx_giu.c
index e5ed09192be8..ffe9b4e3072e 100644
--- a/drivers/char/vr41xx_giu.c
+++ b/drivers/char/vr41xx_giu.c
@@ -27,6 +27,7 @@
27#include <linux/kernel.h> 27#include <linux/kernel.h>
28#include <linux/module.h> 28#include <linux/module.h>
29#include <linux/platform_device.h> 29#include <linux/platform_device.h>
30#include <linux/smp_lock.h>
30#include <linux/spinlock.h> 31#include <linux/spinlock.h>
31#include <linux/types.h> 32#include <linux/types.h>
32 33
@@ -547,6 +548,7 @@ static int gpio_open(struct inode *inode, struct file *file)
547{ 548{
548 unsigned int pin; 549 unsigned int pin;
549 550
551 cycle_kernel_lock();
550 pin = iminor(inode); 552 pin = iminor(inode);
551 if (pin >= giu_nr_pins) 553 if (pin >= giu_nr_pins)
552 return -EBADF; 554 return -EBADF;
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index fa1ffbf2c621..935f1c207a1f 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -434,7 +434,7 @@ static void update_attr(struct vc_data *vc)
434 vc->vc_blink, vc->vc_underline, 434 vc->vc_blink, vc->vc_underline,
435 vc->vc_reverse ^ vc->vc_decscnm, vc->vc_italic); 435 vc->vc_reverse ^ vc->vc_decscnm, vc->vc_italic);
436 vc->vc_video_erase_char = (build_attr(vc, vc->vc_color, 1, vc->vc_blink, 0, vc->vc_decscnm, 0) << 8) | ' '; 436 vc->vc_video_erase_char = (build_attr(vc, vc->vc_color, 1, vc->vc_blink, 0, vc->vc_decscnm, 0) << 8) | ' ';
437 vc->vc_scrl_erase_char = (build_attr(vc, vc->vc_def_color, 1, false, false, false, false) << 8) | ' '; 437 vc->vc_scrl_erase_char = (build_attr(vc, vc->vc_def_color, 1, false, false, vc->vc_decscnm, false) << 8) | ' ';
438} 438}
439 439
440/* Note: inverting the screen twice should revert to the original state */ 440/* Note: inverting the screen twice should revert to the original state */
@@ -909,7 +909,7 @@ int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines)
909 909
910 if (vc->vc_tty) { 910 if (vc->vc_tty) {
911 struct winsize ws, *cws = &vc->vc_tty->winsize; 911 struct winsize ws, *cws = &vc->vc_tty->winsize;
912 unsigned long flags; 912 struct pid *pgrp = NULL;
913 913
914 memset(&ws, 0, sizeof(ws)); 914 memset(&ws, 0, sizeof(ws));
915 ws.ws_row = vc->vc_rows; 915 ws.ws_row = vc->vc_rows;
@@ -917,11 +917,14 @@ int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines)
917 ws.ws_ypixel = vc->vc_scan_lines; 917 ws.ws_ypixel = vc->vc_scan_lines;
918 918
919 mutex_lock(&vc->vc_tty->termios_mutex); 919 mutex_lock(&vc->vc_tty->termios_mutex);
920 spin_lock_irqsave(&vc->vc_tty->ctrl_lock, flags); 920 spin_lock_irq(&vc->vc_tty->ctrl_lock);
921 if ((ws.ws_row != cws->ws_row || ws.ws_col != cws->ws_col) && 921 if ((ws.ws_row != cws->ws_row || ws.ws_col != cws->ws_col))
922 vc->vc_tty->pgrp) 922 pgrp = get_pid(vc->vc_tty->pgrp);
923 spin_unlock_irq(&vc->vc_tty->ctrl_lock);
924 if (pgrp) {
923 kill_pgrp(vc->vc_tty->pgrp, SIGWINCH, 1); 925 kill_pgrp(vc->vc_tty->pgrp, SIGWINCH, 1);
924 spin_unlock_irqrestore(&vc->vc_tty->ctrl_lock, flags); 926 put_pid(pgrp);
927 }
925 *cws = ws; 928 *cws = ws;
926 mutex_unlock(&vc->vc_tty->termios_mutex); 929 mutex_unlock(&vc->vc_tty->termios_mutex);
927 } 930 }
diff --git a/drivers/char/xilinx_hwicap/xilinx_hwicap.c b/drivers/char/xilinx_hwicap/xilinx_hwicap.c
index 3edf1fc12963..1e1b81e57cdc 100644
--- a/drivers/char/xilinx_hwicap/xilinx_hwicap.c
+++ b/drivers/char/xilinx_hwicap/xilinx_hwicap.c
@@ -85,6 +85,7 @@
85#include <linux/poll.h> 85#include <linux/poll.h>
86#include <linux/proc_fs.h> 86#include <linux/proc_fs.h>
87#include <linux/mutex.h> 87#include <linux/mutex.h>
88#include <linux/smp_lock.h>
88#include <linux/sysctl.h> 89#include <linux/sysctl.h>
89#include <linux/version.h> 90#include <linux/version.h>
90#include <linux/fs.h> 91#include <linux/fs.h>
@@ -504,11 +505,12 @@ static int hwicap_open(struct inode *inode, struct file *file)
504 struct hwicap_drvdata *drvdata; 505 struct hwicap_drvdata *drvdata;
505 int status; 506 int status;
506 507
508 lock_kernel();
507 drvdata = container_of(inode->i_cdev, struct hwicap_drvdata, cdev); 509 drvdata = container_of(inode->i_cdev, struct hwicap_drvdata, cdev);
508 510
509 status = mutex_lock_interruptible(&drvdata->sem); 511 status = mutex_lock_interruptible(&drvdata->sem);
510 if (status) 512 if (status)
511 return status; 513 goto out;
512 514
513 if (drvdata->is_open) { 515 if (drvdata->is_open) {
514 status = -EBUSY; 516 status = -EBUSY;
@@ -528,6 +530,8 @@ static int hwicap_open(struct inode *inode, struct file *file)
528 530
529 error: 531 error:
530 mutex_unlock(&drvdata->sem); 532 mutex_unlock(&drvdata->sem);
533 out:
534 unlock_kernel();
531 return status; 535 return status;
532} 536}
533 537